mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-05 22:05:11 +00:00
add retake, send actions and preview
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
This commit is contained in:
parent
547e9ebf8b
commit
67c421a067
@ -190,6 +190,7 @@ dependencies {
|
||||
implementation 'androidx.camera:camera-camera2:1.0.1'
|
||||
implementation 'androidx.camera:camera-lifecycle:1.0.1'
|
||||
implementation 'androidx.camera:camera-view:1.0.0-alpha20'
|
||||
implementation "androidx.exifinterface:exifinterface:1.3.3"
|
||||
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||
|
||||
|
@ -24,12 +24,15 @@ package com.nextcloud.talk.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.Size;
|
||||
import android.view.OrientationEventListener;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
@ -39,6 +42,8 @@ import com.nextcloud.talk.models.TakePictureViewModel;
|
||||
import com.nextcloud.talk.utils.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
@ -53,6 +58,7 @@ import androidx.camera.core.ImageCaptureException;
|
||||
import androidx.camera.core.Preview;
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.exifinterface.media.ExifInterface;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
public class TakePhotoActivity extends AppCompatActivity {
|
||||
@ -99,7 +105,7 @@ public class TakePhotoActivity extends AppCompatActivity {
|
||||
viewModel.isTorchEnabled()
|
||||
.observe(
|
||||
this,
|
||||
enabled -> camera.getCameraControl().enableTorch(enabled));
|
||||
enabled -> camera.getCameraControl().enableTorch(enabled));
|
||||
|
||||
binding.toggleTorch.setOnClickListener((v) -> viewModel.toggleTorchEnabled());
|
||||
binding.switchCamera.setOnClickListener((v) -> {
|
||||
@ -111,6 +117,20 @@ public class TakePhotoActivity extends AppCompatActivity {
|
||||
imageCapture,
|
||||
preview);
|
||||
});
|
||||
binding.retake.setOnClickListener((v) -> {
|
||||
Uri uri = (Uri) binding.photoPreview.getTag();
|
||||
File photoFile = new File(uri.getPath());
|
||||
if (!photoFile.delete()) {
|
||||
Log.w(TAG, "Error deleting temp camera image");
|
||||
}
|
||||
binding.takePhoto.setEnabled(true);
|
||||
showCameraElements();
|
||||
});
|
||||
binding.send.setOnClickListener((v) -> {
|
||||
Uri uri = (Uri) binding.photoPreview.getTag();
|
||||
setResult(RESULT_OK, new Intent().setDataAndType(uri, "image/jpeg"));
|
||||
finish();
|
||||
});
|
||||
} catch (IllegalArgumentException | ExecutionException | InterruptedException e) {
|
||||
Log.e(TAG, "Error taking picture", e);
|
||||
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
|
||||
@ -119,6 +139,28 @@ public class TakePhotoActivity extends AppCompatActivity {
|
||||
}, ContextCompat.getMainExecutor(this));
|
||||
}
|
||||
|
||||
private void showCameraElements() {
|
||||
binding.send.setVisibility(View.GONE);
|
||||
binding.retake.setVisibility(View.GONE);
|
||||
binding.photoPreview.setVisibility(View.GONE);
|
||||
|
||||
binding.preview.setVisibility(View.VISIBLE);
|
||||
binding.takePhoto.setVisibility(View.VISIBLE);
|
||||
binding.switchCamera.setVisibility(View.VISIBLE);
|
||||
binding.toggleTorch.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void showPictureProcessingElements() {
|
||||
binding.preview.setVisibility(View.GONE);
|
||||
binding.takePhoto.setVisibility(View.GONE);
|
||||
binding.switchCamera.setVisibility(View.GONE);
|
||||
binding.toggleTorch.setVisibility(View.GONE);
|
||||
|
||||
binding.send.setVisibility(View.VISIBLE);
|
||||
binding.retake.setVisibility(View.VISIBLE);
|
||||
binding.photoPreview.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private ImageCapture getImageCapture() {
|
||||
final ImageCapture imageCapture = new ImageCapture.Builder().setTargetResolution(new Size(720, 1280)).build();
|
||||
|
||||
@ -145,7 +187,7 @@ public class TakePhotoActivity extends AppCompatActivity {
|
||||
|
||||
binding.takePhoto.setOnClickListener((v) -> {
|
||||
binding.takePhoto.setEnabled(false);
|
||||
final String photoFileName = dateFormat.format(new Date())+ ".jpg";
|
||||
final String photoFileName = dateFormat.format(new Date()) + ".jpg";
|
||||
try {
|
||||
final File photoFile = FileUtils.getTempCacheFile(this, "photos/" + photoFileName);
|
||||
final ImageCapture.OutputFileOptions options =
|
||||
@ -155,24 +197,33 @@ public class TakePhotoActivity extends AppCompatActivity {
|
||||
ContextCompat.getMainExecutor(this),
|
||||
new ImageCapture.OnImageSavedCallback() {
|
||||
|
||||
@Override
|
||||
public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
|
||||
final Uri savedUri = Uri.fromFile(photoFile);
|
||||
Log.i(TAG, "onImageSaved - savedUri:" + savedUri);
|
||||
setResult(RESULT_OK, new Intent().setDataAndType(savedUri, "image/jpeg"));
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull ImageCaptureException e) {
|
||||
Log.e(TAG, "Error", e);
|
||||
|
||||
if(!photoFile.delete()) {
|
||||
Log.w(TAG, "Deleting picture failed");
|
||||
@Override
|
||||
public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
|
||||
final Uri savedUri = Uri.fromFile(photoFile);
|
||||
Log.i(TAG, "onImageSaved - savedUri:" + savedUri);
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
|
||||
try {
|
||||
binding.photoPreview.setImageBitmap(
|
||||
BitmapFactory.decodeStream(new FileInputStream(photoFile), null, options));
|
||||
binding.photoPreview.setRotation(getImageOrientation(photoFile));
|
||||
binding.photoPreview.setTag(savedUri);
|
||||
showPictureProcessingElements();
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, "Error reading image", e);
|
||||
}
|
||||
}
|
||||
binding.takePhoto.setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull ImageCaptureException e) {
|
||||
Log.e(TAG, "Error", e);
|
||||
|
||||
if (!photoFile.delete()) {
|
||||
Log.w(TAG, "Deleting picture failed");
|
||||
}
|
||||
binding.takePhoto.setEnabled(true);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(this, R.string.take_photo_error_deleting_picture, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
@ -181,6 +232,36 @@ public class TakePhotoActivity extends AppCompatActivity {
|
||||
return imageCapture;
|
||||
}
|
||||
|
||||
public int getImageOrientation(File imageFile) {
|
||||
int rotate = 0;
|
||||
try {
|
||||
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
|
||||
int orientation = exif.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL);
|
||||
|
||||
switch (orientation) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
rotate = 270;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
rotate = 180;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
rotate = 90;
|
||||
break;
|
||||
default:
|
||||
rotate = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Log.i(TAG, "ImageOrientation - Exif orientation: " + orientation + " - " + "Rotate value: " + rotate);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calculation rotation value");
|
||||
}
|
||||
return rotate;
|
||||
}
|
||||
|
||||
private Preview getPreview() {
|
||||
Preview preview = new Preview.Builder().build();
|
||||
preview.setSurfaceProvider(binding.preview.getSurfaceProvider());
|
||||
|
8
app/src/main/res/drawable/ic_autorenew.xml
Normal file
8
app/src/main/res/drawable/ic_autorenew.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<!-- drawable/autorenew.xml -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#000" android:pathData="M12,6V9L16,5L12,1V4A8,8 0 0,0 4,12C4,13.57 4.46,15.03 5.24,16.26L6.7,14.8C6.25,13.97 6,13 6,12A6,6 0 0,1 12,6M18.76,7.74L17.3,9.2C17.74,10.04 18,11 18,12A6,6 0 0,1 12,18V15L8,19L12,23V20A8,8 0 0,0 20,12C20,10.43 19.54,8.97 18.76,7.74Z" />
|
||||
</vector>
|
@ -34,6 +34,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/photo_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@null"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/toggle_torch"
|
||||
style="@style/Widget.AppTheme.Button.IconButton"
|
||||
@ -41,8 +48,8 @@
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:contentDescription="@string/take_photo_toggle_torch"
|
||||
android:insetLeft="4dp"
|
||||
@ -68,9 +75,9 @@
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:contentDescription="@string/take_photo_switch_camera"
|
||||
android:insetLeft="4dp"
|
||||
android:insetTop="4dp"
|
||||
@ -89,6 +96,34 @@
|
||||
app:layout_constraintEnd_toStartOf="@+id/toggle_torch"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/retake"
|
||||
style="@style/Widget.AppTheme.Button.IconButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@string/take_photo_switch_camera"
|
||||
android:insetLeft="0dp"
|
||||
android:insetTop="0dp"
|
||||
android:insetRight="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:padding="0dp"
|
||||
android:tint="@android:color/white"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="@color/colorPrimary"
|
||||
app:cornerRadius="@dimen/button_corner_radius"
|
||||
app:elevation="0dp"
|
||||
app:icon="@drawable/ic_autorenew"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
app:iconSize="24dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@id/takePhoto"
|
||||
app:layout_constraintEnd_toStartOf="@id/takePhoto"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/takePhoto"
|
||||
android:layout_width="wrap_content"
|
||||
@ -103,4 +138,32 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:srcCompat="@drawable/ic_baseline_photo_camera_24" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/send"
|
||||
style="@style/Widget.AppTheme.Button.IconButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@string/take_photo_switch_camera"
|
||||
android:insetLeft="0dp"
|
||||
android:insetTop="0dp"
|
||||
android:insetRight="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:padding="0dp"
|
||||
android:tint="@android:color/white"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="@color/colorPrimary"
|
||||
app:cornerRadius="@dimen/button_corner_radius"
|
||||
app:elevation="0dp"
|
||||
app:icon="@drawable/ic_send"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
app:iconSize="24dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@id/takePhoto"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/takePhoto" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
Loading…
Reference in New Issue
Block a user