mirror of
https://github.com/SimpleMobileTools/Simple-Camera.git
synced 2025-02-16 19:30:40 +01:00
convert MainActivity to kotlin
This commit is contained in:
parent
c50608aa27
commit
900f12634e
@ -7,6 +7,7 @@ import android.util.Log
|
||||
import com.simplemobiletools.camera.activities.MainActivity
|
||||
import com.simplemobiletools.filepicker.extensions.getFileDocument
|
||||
import com.simplemobiletools.filepicker.extensions.needsStupidWritePermissions
|
||||
import com.simplemobiletools.filepicker.extensions.toast
|
||||
import java.io.*
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
@ -39,7 +40,7 @@ class PhotoProcessor(val activity: MainActivity, val uri: Uri?) : AsyncTask<Byte
|
||||
val config = Config.newInstance(activity)
|
||||
if (config.treeUri.isEmpty()) {
|
||||
activity.runOnUiThread {
|
||||
Utils.showToast(activity, R.string.save_error_internal_storage)
|
||||
activity.toast(R.string.save_error_internal_storage)
|
||||
}
|
||||
config.savePhotosFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString()
|
||||
return ""
|
||||
|
@ -9,7 +9,6 @@ import android.graphics.Point
|
||||
import android.hardware.Camera
|
||||
import android.support.v4.content.ContextCompat
|
||||
import com.simplemobiletools.filepicker.extensions.getFileDocument
|
||||
import com.simplemobiletools.filepicker.extensions.hasStoragePermission
|
||||
import com.simplemobiletools.filepicker.extensions.needsStupidWritePermissions
|
||||
import com.simplemobiletools.filepicker.extensions.toast
|
||||
import java.io.File
|
||||
@ -102,8 +101,6 @@ class Utils {
|
||||
|
||||
fun hasCameraPermission(context: Context) = ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
|
||||
|
||||
fun hasStoragePermission(context: Context) = context.hasStoragePermission()
|
||||
|
||||
fun hasAudioPermission(cxt: Context) = ContextCompat.checkSelfPermission(cxt, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
|
||||
|
||||
fun needsStupidWritePermissions(context: Context, path: String) = context.needsStupidWritePermissions(path)
|
||||
|
@ -1,711 +0,0 @@
|
||||
package com.simplemobiletools.camera.activities;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.simplemobiletools.camera.Config;
|
||||
import com.simplemobiletools.camera.Constants;
|
||||
import com.simplemobiletools.camera.views.FocusRectView;
|
||||
import com.simplemobiletools.camera.PhotoProcessor;
|
||||
import com.simplemobiletools.camera.Preview;
|
||||
import com.simplemobiletools.camera.Preview.PreviewListener;
|
||||
import com.simplemobiletools.camera.R;
|
||||
import com.simplemobiletools.camera.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class MainActivity extends SimpleActivity
|
||||
implements SensorEventListener, PreviewListener, PhotoProcessor.MediaSavedListener, MediaScannerConnection.OnScanCompletedListener {
|
||||
@BindView(R.id.view_holder) RelativeLayout mViewHolder;
|
||||
@BindView(R.id.toggle_camera) ImageView mToggleCameraBtn;
|
||||
@BindView(R.id.toggle_flash) ImageView mToggleFlashBtn;
|
||||
@BindView(R.id.toggle_photo_video) ImageView mTogglePhotoVideoBtn;
|
||||
@BindView(R.id.shutter) ImageView mShutterBtn;
|
||||
@BindView(R.id.video_rec_curr_timer) TextView mRecCurrTimer;
|
||||
@BindView(R.id.settings) View mSettingsBtn;
|
||||
@BindView(R.id.last_photo_video_preview) ImageView mLastPhotoVideoPreview;
|
||||
|
||||
private static final int CAMERA_STORAGE_PERMISSION = 1;
|
||||
private static final int AUDIO_PERMISSION = 2;
|
||||
private static final int FADE_DELAY = 5000;
|
||||
|
||||
private static SensorManager mSensorManager;
|
||||
private static Preview mPreview;
|
||||
private static FocusRectView mFocusRectView;
|
||||
private static Handler mTimerHandler;
|
||||
private static Uri mPreviewUri;
|
||||
private static Handler mFadeHandler;
|
||||
|
||||
private static boolean mIsFlashEnabled;
|
||||
private static boolean mIsInPhotoMode;
|
||||
private static boolean mIsAskingPermissions;
|
||||
private static boolean mIsCameraAvailable;
|
||||
private static boolean mIsImageCaptureIntent;
|
||||
private static boolean mIsVideoCaptureIntent;
|
||||
private static boolean mIsHardwareShutterHandled;
|
||||
private static int mCurrVideoRecTimer;
|
||||
private static int mOrientation;
|
||||
private static int mCurrCamera;
|
||||
private static int mLastHandledOrientation;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
tryInitCamera();
|
||||
|
||||
final ActionBar actionbar = getSupportActionBar();
|
||||
if (actionbar != null)
|
||||
actionbar.hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_CAMERA && !mIsHardwareShutterHandled) {
|
||||
mIsHardwareShutterHandled = true;
|
||||
shutterPressed();
|
||||
return true;
|
||||
} else {
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_CAMERA) {
|
||||
mIsHardwareShutterHandled = false;
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
private void hideToggleModeAbout() {
|
||||
if (mTogglePhotoVideoBtn != null)
|
||||
mTogglePhotoVideoBtn.setVisibility(View.GONE);
|
||||
|
||||
if (mSettingsBtn != null)
|
||||
mSettingsBtn.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void tryInitCamera() {
|
||||
if (hasCameraAndStoragePermission()) {
|
||||
initializeCamera();
|
||||
handleIntent();
|
||||
} else {
|
||||
final List<String> permissions = new ArrayList<>(2);
|
||||
if (!Utils.Companion.hasCameraPermission(getApplicationContext())) {
|
||||
permissions.add(Manifest.permission.CAMERA);
|
||||
}
|
||||
if (!Utils.Companion.hasStoragePermission(getApplicationContext())) {
|
||||
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
}
|
||||
ActivityCompat.requestPermissions(this, permissions.toArray(new String[permissions.size()]), CAMERA_STORAGE_PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleIntent() {
|
||||
final Intent intent = getIntent();
|
||||
if (intent != null && intent.getAction() != null) {
|
||||
if (intent.getExtras() != null && intent.getAction().equals(MediaStore.ACTION_IMAGE_CAPTURE) ||
|
||||
intent.getAction().equals(MediaStore.ACTION_IMAGE_CAPTURE_SECURE)) {
|
||||
mIsImageCaptureIntent = true;
|
||||
hideToggleModeAbout();
|
||||
final Object output = intent.getExtras().get(MediaStore.EXTRA_OUTPUT);
|
||||
if (output != null && output instanceof Uri) {
|
||||
mPreview.setTargetUri((Uri) output);
|
||||
}
|
||||
} else if (intent.getAction().equals(MediaStore.ACTION_VIDEO_CAPTURE)) {
|
||||
mIsVideoCaptureIntent = true;
|
||||
hideToggleModeAbout();
|
||||
mShutterBtn.setImageDrawable(getResources().getDrawable(R.mipmap.video_rec));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeCamera() {
|
||||
setContentView(R.layout.activity_main);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
if (Utils.Companion.hasNavBar(getResources()) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
final View btnLayout = findViewById(R.id.btn_holder);
|
||||
final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) btnLayout.getLayoutParams();
|
||||
lp.setMargins(0, 0, 0, lp.bottomMargin + Utils.Companion.getNavBarHeight(getResources()));
|
||||
}
|
||||
|
||||
mCurrCamera = getConfig().getLastUsedCamera();
|
||||
mPreview = new Preview(this, (SurfaceView) findViewById(R.id.camera_view), this);
|
||||
mPreview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
mViewHolder.addView(mPreview);
|
||||
mToggleCameraBtn.setImageResource(mCurrCamera == Camera.CameraInfo.CAMERA_FACING_BACK ? R.mipmap.camera_front : R.mipmap.camera_back);
|
||||
|
||||
mFocusRectView = new FocusRectView(getApplicationContext());
|
||||
mViewHolder.addView(mFocusRectView);
|
||||
|
||||
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
|
||||
mIsInPhotoMode = true;
|
||||
mTimerHandler = new Handler();
|
||||
mFadeHandler = new Handler();
|
||||
mIsFlashEnabled = getConfig().getLastFlashlightState();
|
||||
setupPreviewImage(true);
|
||||
}
|
||||
|
||||
private boolean hasCameraAndStoragePermission() {
|
||||
return Utils.Companion.hasCameraPermission(getApplicationContext()) && Utils.Companion.hasStoragePermission(getApplicationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
mIsAskingPermissions = false;
|
||||
|
||||
if (requestCode == CAMERA_STORAGE_PERMISSION) {
|
||||
if (hasCameraAndStoragePermission()) {
|
||||
initializeCamera();
|
||||
handleIntent();
|
||||
} else {
|
||||
Utils.Companion.showToast(getApplicationContext(), R.string.no_permissions);
|
||||
finish();
|
||||
}
|
||||
} else if (requestCode == AUDIO_PERMISSION) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
togglePhotoVideo();
|
||||
} else {
|
||||
Utils.Companion.showToast(getApplicationContext(), R.string.no_audio_permissions);
|
||||
if (mIsVideoCaptureIntent)
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.toggle_camera)
|
||||
public void toggleCamera() {
|
||||
if (!checkCameraAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCurrCamera == Camera.CameraInfo.CAMERA_FACING_BACK) {
|
||||
mCurrCamera = Camera.CameraInfo.CAMERA_FACING_FRONT;
|
||||
} else {
|
||||
mCurrCamera = Camera.CameraInfo.CAMERA_FACING_BACK;
|
||||
}
|
||||
|
||||
getConfig().setLastUsedCamera(mCurrCamera);
|
||||
int newIconId = R.mipmap.camera_front;
|
||||
mPreview.releaseCamera();
|
||||
if (mPreview.setCamera(mCurrCamera)) {
|
||||
if (mCurrCamera == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
||||
newIconId = R.mipmap.camera_back;
|
||||
}
|
||||
mToggleCameraBtn.setImageResource(newIconId);
|
||||
disableFlash();
|
||||
hideTimer();
|
||||
} else {
|
||||
Utils.Companion.showToast(getApplicationContext(), R.string.camera_switch_error);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.last_photo_video_preview)
|
||||
public void showLastMediaPreview() {
|
||||
if (mPreviewUri == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
final String REVIEW_ACTION = "com.android.camera.action.REVIEW";
|
||||
Intent intent = new Intent(REVIEW_ACTION, mPreviewUri);
|
||||
this.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, mPreviewUri);
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
Utils.Companion.showToast(getApplicationContext(), R.string.no_gallery_app_available);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.toggle_flash)
|
||||
public void toggleFlash() {
|
||||
if (!checkCameraAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIsFlashEnabled = !mIsFlashEnabled;
|
||||
checkFlash();
|
||||
}
|
||||
|
||||
private void checkFlash() {
|
||||
if (mIsFlashEnabled) {
|
||||
enableFlash();
|
||||
} else {
|
||||
disableFlash();
|
||||
}
|
||||
}
|
||||
|
||||
private void disableFlash() {
|
||||
mPreview.disableFlash();
|
||||
mToggleFlashBtn.setImageResource(R.mipmap.flash_off);
|
||||
mIsFlashEnabled = false;
|
||||
getConfig().setLastFlashlightState(mIsFlashEnabled);
|
||||
}
|
||||
|
||||
private void enableFlash() {
|
||||
mPreview.enableFlash();
|
||||
mToggleFlashBtn.setImageResource(R.mipmap.flash_on);
|
||||
mIsFlashEnabled = true;
|
||||
getConfig().setLastFlashlightState(mIsFlashEnabled);
|
||||
}
|
||||
|
||||
@OnClick(R.id.shutter)
|
||||
public void handleShutterPressed() {
|
||||
shutterPressed();
|
||||
}
|
||||
|
||||
private void shutterPressed() {
|
||||
if (!checkCameraAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleShutter();
|
||||
}
|
||||
|
||||
private void handleShutter() {
|
||||
if (mIsInPhotoMode) {
|
||||
toggleBottomButtons(true);
|
||||
mPreview.takePicture();
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
toggleBottomButtons(false);
|
||||
}
|
||||
}, Preview.PHOTO_PREVIEW_LENGTH);
|
||||
} else {
|
||||
final Resources res = getResources();
|
||||
final boolean isRecording = mPreview.toggleRecording();
|
||||
if (isRecording) {
|
||||
mShutterBtn.setImageDrawable(res.getDrawable(R.mipmap.video_stop));
|
||||
mToggleCameraBtn.setVisibility(View.INVISIBLE);
|
||||
showTimer();
|
||||
} else {
|
||||
mShutterBtn.setImageDrawable(res.getDrawable(R.mipmap.video_rec));
|
||||
mToggleCameraBtn.setVisibility(View.VISIBLE);
|
||||
hideTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleBottomButtons(Boolean hide) {
|
||||
mShutterBtn.animate().alpha(hide ? 0 : 1).start();
|
||||
mToggleCameraBtn.animate().alpha(hide ? 0 : 1).start();
|
||||
mToggleFlashBtn.animate().alpha(hide ? 0 : 1).start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.settings)
|
||||
public void launchSettings() {
|
||||
if (mSettingsBtn.getAlpha() == 1.f) {
|
||||
final Intent intent = new Intent(getApplicationContext(), SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
fadeInButtons();
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.toggle_photo_video)
|
||||
public void handleTogglePhotoVideo() {
|
||||
togglePhotoVideo();
|
||||
checkButtons();
|
||||
}
|
||||
|
||||
private void togglePhotoVideo() {
|
||||
if (!checkCameraAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Utils.Companion.hasAudioPermission(getApplicationContext())) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, AUDIO_PERMISSION);
|
||||
mIsAskingPermissions = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsVideoCaptureIntent)
|
||||
mPreview.trySwitchToVideo();
|
||||
|
||||
disableFlash();
|
||||
hideTimer();
|
||||
mIsInPhotoMode = !mIsInPhotoMode;
|
||||
mToggleCameraBtn.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void checkButtons() {
|
||||
if (mIsInPhotoMode) {
|
||||
initPhotoButtons();
|
||||
} else {
|
||||
tryInitVideoButtons();
|
||||
}
|
||||
}
|
||||
|
||||
private void initPhotoButtons() {
|
||||
final Resources res = getResources();
|
||||
mTogglePhotoVideoBtn.setImageDrawable(res.getDrawable(R.mipmap.videocam));
|
||||
mShutterBtn.setImageDrawable(res.getDrawable(R.mipmap.camera));
|
||||
mPreview.initPhotoMode();
|
||||
setupPreviewImage(true);
|
||||
}
|
||||
|
||||
private void tryInitVideoButtons() {
|
||||
if (mPreview.initRecorder()) {
|
||||
initVideoButtons();
|
||||
} else {
|
||||
if (!mIsVideoCaptureIntent) {
|
||||
Utils.Companion.showToast(getApplicationContext(), R.string.video_mode_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initVideoButtons() {
|
||||
final Resources res = getResources();
|
||||
mTogglePhotoVideoBtn.setImageDrawable(res.getDrawable(R.mipmap.photo));
|
||||
mToggleCameraBtn.setVisibility(View.VISIBLE);
|
||||
mShutterBtn.setImageDrawable(res.getDrawable(R.mipmap.video_rec));
|
||||
checkFlash();
|
||||
setupPreviewImage(false);
|
||||
}
|
||||
|
||||
private void setupPreviewImage(boolean isPhoto) {
|
||||
final Uri uri = (isPhoto) ? MediaStore.Images.Media.EXTERNAL_CONTENT_URI : MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
final long lastMediaId = getLastMediaId(uri);
|
||||
if (lastMediaId == 0) {
|
||||
return;
|
||||
}
|
||||
final ContentResolver cr = getContentResolver();
|
||||
mPreviewUri = Uri.withAppendedPath(uri, String.valueOf(lastMediaId));
|
||||
Bitmap tmb;
|
||||
|
||||
if (isPhoto) {
|
||||
tmb = MediaStore.Images.Thumbnails.getThumbnail(cr, lastMediaId, MediaStore.Images.Thumbnails.MICRO_KIND, null);
|
||||
final int rotationDegrees = getImageRotation();
|
||||
tmb = rotateThumbnail(tmb, rotationDegrees);
|
||||
} else {
|
||||
tmb = MediaStore.Video.Thumbnails.getThumbnail(cr, lastMediaId, MediaStore.Video.Thumbnails.MICRO_KIND, null);
|
||||
}
|
||||
|
||||
setPreviewImage(tmb);
|
||||
}
|
||||
|
||||
private int getImageRotation() {
|
||||
final String[] projection = {MediaStore.Images.ImageColumns.ORIENTATION};
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
final int orientationIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION);
|
||||
return cursor.getInt(orientationIndex);
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Bitmap rotateThumbnail(Bitmap tmb, int degrees) {
|
||||
if (degrees == 0)
|
||||
return tmb;
|
||||
|
||||
final Matrix matrix = new Matrix();
|
||||
matrix.setRotate(degrees, tmb.getWidth() / 2, tmb.getHeight() / 2);
|
||||
return Bitmap.createBitmap(tmb, 0, 0, tmb.getWidth(), tmb.getHeight(), matrix, true);
|
||||
}
|
||||
|
||||
private void setPreviewImage(final Bitmap bmp) {
|
||||
if (bmp != null) {
|
||||
mLastPhotoVideoPreview.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mLastPhotoVideoPreview.setImageBitmap(bmp);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private long getLastMediaId(Uri uri) {
|
||||
final String[] projection = {MediaStore.Images.ImageColumns._ID};
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = getContentResolver().query(uri, projection, null, null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
final int idIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID);
|
||||
return cursor.getLong(idIndex);
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void scheduleFadeOut() {
|
||||
mFadeHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fadeOutButtons();
|
||||
}
|
||||
}, FADE_DELAY);
|
||||
}
|
||||
|
||||
private void fadeOutButtons() {
|
||||
fadeAnim(mSettingsBtn, .5f);
|
||||
fadeAnim(mTogglePhotoVideoBtn, .0f);
|
||||
fadeAnim(mLastPhotoVideoPreview, .0f);
|
||||
}
|
||||
|
||||
private void fadeInButtons() {
|
||||
fadeAnim(mSettingsBtn, 1.f);
|
||||
fadeAnim(mTogglePhotoVideoBtn, 1.f);
|
||||
fadeAnim(mLastPhotoVideoPreview, 1.f);
|
||||
scheduleFadeOut();
|
||||
}
|
||||
|
||||
private void fadeAnim(View view, float value) {
|
||||
view.animate().alpha(value).start();
|
||||
if (value == .0f) {
|
||||
view.setClickable(false);
|
||||
} else {
|
||||
view.setClickable(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void hideNavigationBarIcons() {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
||||
}
|
||||
|
||||
private void hideTimer() {
|
||||
mRecCurrTimer.setText(Utils.Companion.formatSeconds(0));
|
||||
mRecCurrTimer.setVisibility(View.GONE);
|
||||
mCurrVideoRecTimer = 0;
|
||||
mTimerHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
private void showTimer() {
|
||||
mRecCurrTimer.setVisibility(View.VISIBLE);
|
||||
setupTimer();
|
||||
}
|
||||
|
||||
private void setupTimer() {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mRecCurrTimer.setText(Utils.Companion.formatSeconds(mCurrVideoRecTimer++));
|
||||
mTimerHandler.postDelayed(this, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (hasCameraAndStoragePermission()) {
|
||||
resumeCameraItems();
|
||||
setupPreviewImage(mIsInPhotoMode);
|
||||
scheduleFadeOut();
|
||||
|
||||
if (mIsVideoCaptureIntent && mIsInPhotoMode) {
|
||||
togglePhotoVideo();
|
||||
checkButtons();
|
||||
}
|
||||
}
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
|
||||
private void resumeCameraItems() {
|
||||
final int cnt = Camera.getNumberOfCameras();
|
||||
if (cnt == 1) {
|
||||
mToggleCameraBtn.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
if (mPreview.setCamera(mCurrCamera)) {
|
||||
hideNavigationBarIcons();
|
||||
checkFlash();
|
||||
|
||||
if (mSensorManager != null) {
|
||||
final Sensor accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
|
||||
}
|
||||
|
||||
if (!mIsInPhotoMode) {
|
||||
initVideoButtons();
|
||||
}
|
||||
} else {
|
||||
Utils.Companion.showToast(getApplicationContext(), R.string.camera_switch_error);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
if (!hasCameraAndStoragePermission() || mIsAskingPermissions)
|
||||
return;
|
||||
|
||||
if (mFadeHandler != null)
|
||||
mFadeHandler.removeCallbacksAndMessages(null);
|
||||
|
||||
hideTimer();
|
||||
if (mPreview != null) {
|
||||
mPreview.releaseCamera();
|
||||
}
|
||||
|
||||
if (mSensorManager != null)
|
||||
mSensorManager.unregisterListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (event.values[0] < 6.5 && event.values[0] > -6.5) {
|
||||
mOrientation = Constants.ORIENT_PORTRAIT;
|
||||
} else {
|
||||
if (event.values[0] > 0) {
|
||||
mOrientation = Constants.ORIENT_LANDSCAPE_LEFT;
|
||||
} else {
|
||||
mOrientation = Constants.ORIENT_LANDSCAPE_RIGHT;
|
||||
}
|
||||
}
|
||||
if (mOrientation != mLastHandledOrientation) {
|
||||
int degrees = 0;
|
||||
switch (mOrientation) {
|
||||
case Constants.ORIENT_LANDSCAPE_LEFT:
|
||||
degrees = 90;
|
||||
break;
|
||||
case Constants.ORIENT_LANDSCAPE_RIGHT:
|
||||
degrees = -90;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
animateViews(degrees);
|
||||
mLastHandledOrientation = mOrientation;
|
||||
}
|
||||
}
|
||||
|
||||
private void animateViews(int degrees) {
|
||||
View[] views = {mToggleCameraBtn, mToggleFlashBtn, mTogglePhotoVideoBtn, mShutterBtn, mSettingsBtn, mLastPhotoVideoPreview};
|
||||
for (View view : views) {
|
||||
rotate(view, degrees);
|
||||
}
|
||||
}
|
||||
|
||||
private void rotate(View view, int degrees) {
|
||||
view.animate().rotation(degrees).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
|
||||
}
|
||||
|
||||
private boolean checkCameraAvailable() {
|
||||
if (!mIsCameraAvailable) {
|
||||
Utils.Companion.showToast(getApplicationContext(), R.string.camera_unavailable);
|
||||
}
|
||||
return mIsCameraAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlashAvailable(boolean available) {
|
||||
if (available) {
|
||||
mToggleFlashBtn.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mToggleFlashBtn.setVisibility(View.INVISIBLE);
|
||||
disableFlash();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsCameraAvailable(boolean available) {
|
||||
mIsCameraAvailable = available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentOrientation() {
|
||||
return mOrientation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void videoSaved(Uri uri) {
|
||||
setupPreviewImage(mIsInPhotoMode);
|
||||
if (mIsVideoCaptureIntent) {
|
||||
final Intent intent = new Intent();
|
||||
intent.setData(uri);
|
||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFocusRect(int x, int y) {
|
||||
if (mFocusRectView != null) {
|
||||
mFocusRectView.drawFocusRect(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mediaSaved(String path) {
|
||||
final String[] paths = {path};
|
||||
MediaScannerConnection.scanFile(getApplicationContext(), paths, null, this);
|
||||
|
||||
if (mIsImageCaptureIntent) {
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Config.Companion.newInstance(getApplicationContext()).setFirstRun(false);
|
||||
if (mPreview != null)
|
||||
mPreview.releaseCamera();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanCompleted(String path, Uri uri) {
|
||||
setupPreviewImage(mIsInPhotoMode);
|
||||
}
|
||||
}
|
@ -0,0 +1,603 @@
|
||||
package com.simplemobiletools.camera.activities
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import android.database.Cursor
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Matrix
|
||||
import android.hardware.*
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.provider.MediaStore
|
||||
import android.support.v4.app.ActivityCompat
|
||||
import android.view.*
|
||||
import android.widget.RelativeLayout
|
||||
import com.simplemobiletools.camera.*
|
||||
import com.simplemobiletools.camera.Preview.PreviewListener
|
||||
import com.simplemobiletools.camera.views.FocusRectView
|
||||
import com.simplemobiletools.filepicker.extensions.hasStoragePermission
|
||||
import com.simplemobiletools.filepicker.extensions.toast
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import java.util.*
|
||||
|
||||
class MainActivity : SimpleActivity(), SensorEventListener, PreviewListener, PhotoProcessor.MediaSavedListener, MediaScannerConnection.OnScanCompletedListener {
|
||||
companion object {
|
||||
|
||||
private val CAMERA_STORAGE_PERMISSION = 1
|
||||
private val AUDIO_PERMISSION = 2
|
||||
private val FADE_DELAY = 5000
|
||||
|
||||
lateinit var mSensorManager: SensorManager
|
||||
lateinit var mFocusRectView: FocusRectView
|
||||
lateinit var mTimerHandler: Handler
|
||||
lateinit var mFadeHandler: Handler
|
||||
lateinit var mPreview: Preview
|
||||
lateinit var mRes: Resources
|
||||
|
||||
private var mPreviewUri: Uri? = null
|
||||
private var mIsFlashEnabled = false
|
||||
private var mIsInPhotoMode = false
|
||||
private var mIsAskingPermissions = false
|
||||
private var mIsCameraAvailable = false
|
||||
private var mIsImageCaptureIntent = false
|
||||
private var mIsVideoCaptureIntent = false
|
||||
private var mIsHardwareShutterHandled = false
|
||||
private var mCurrVideoRecTimer = 0
|
||||
private var mOrientation = 0
|
||||
private var mCurrCamera = 0
|
||||
private var mLastHandledOrientation = 0
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
mRes = resources
|
||||
tryInitCamera()
|
||||
|
||||
supportActionBar?.hide()
|
||||
|
||||
toggle_camera.setOnClickListener { toggleCamera() }
|
||||
last_photo_video_preview.setOnClickListener { showLastMediaPreview() }
|
||||
toggle_flash.setOnClickListener { toggleFlash() }
|
||||
shutter.setOnClickListener { shutterPressed() }
|
||||
settings.setOnClickListener { launchSettings() }
|
||||
toggle_photo_video.setOnClickListener { handleTogglePhotoVideo() }
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
||||
return if (keyCode == KeyEvent.KEYCODE_CAMERA && !mIsHardwareShutterHandled) {
|
||||
mIsHardwareShutterHandled = true
|
||||
shutterPressed()
|
||||
true
|
||||
} else {
|
||||
super.onKeyDown(keyCode, event)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_CAMERA) {
|
||||
mIsHardwareShutterHandled = false
|
||||
}
|
||||
return super.onKeyUp(keyCode, event)
|
||||
}
|
||||
|
||||
private fun hideToggleModeAbout() {
|
||||
toggle_photo_video.visibility = View.GONE
|
||||
settings.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun tryInitCamera() {
|
||||
if (hasCameraAndStoragePermission()) {
|
||||
initializeCamera()
|
||||
handleIntent()
|
||||
} else {
|
||||
val permissions = ArrayList<String>(2)
|
||||
if (!Utils.hasCameraPermission(applicationContext)) {
|
||||
permissions.add(Manifest.permission.CAMERA)
|
||||
}
|
||||
if (!hasStoragePermission()) {
|
||||
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
}
|
||||
ActivityCompat.requestPermissions(this, permissions.toTypedArray(), CAMERA_STORAGE_PERMISSION)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleIntent() {
|
||||
if (intent != null && intent.action != null) {
|
||||
if (intent.extras != null && intent.action == MediaStore.ACTION_IMAGE_CAPTURE || intent.action == MediaStore.ACTION_IMAGE_CAPTURE_SECURE) {
|
||||
mIsImageCaptureIntent = true
|
||||
hideToggleModeAbout()
|
||||
val output = intent.extras.get(MediaStore.EXTRA_OUTPUT)
|
||||
if (output != null && output is Uri) {
|
||||
mPreview.setTargetUri(output)
|
||||
}
|
||||
} else if (intent.action == MediaStore.ACTION_VIDEO_CAPTURE) {
|
||||
mIsVideoCaptureIntent = true
|
||||
hideToggleModeAbout()
|
||||
shutter.setImageDrawable(mRes.getDrawable(R.mipmap.video_rec))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeCamera() {
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
if (Utils.hasNavBar(mRes) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
val lp = btn_holder.layoutParams as RelativeLayout.LayoutParams
|
||||
lp.setMargins(0, 0, 0, lp.bottomMargin + Utils.getNavBarHeight(mRes))
|
||||
}
|
||||
|
||||
mCurrCamera = config.lastUsedCamera
|
||||
mPreview = Preview(this, camera_view, this)
|
||||
mPreview.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
view_holder.addView(mPreview)
|
||||
toggle_camera.setImageResource(if (mCurrCamera == Camera.CameraInfo.CAMERA_FACING_BACK) R.mipmap.camera_front else R.mipmap.camera_back)
|
||||
|
||||
mFocusRectView = FocusRectView(applicationContext)
|
||||
view_holder.addView(mFocusRectView)
|
||||
|
||||
mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
mIsInPhotoMode = true
|
||||
mTimerHandler = Handler()
|
||||
mFadeHandler = Handler()
|
||||
mIsFlashEnabled = config.lastFlashlightState
|
||||
setupPreviewImage(true)
|
||||
}
|
||||
|
||||
private fun hasCameraAndStoragePermission() = Utils.hasCameraPermission(applicationContext) && hasStoragePermission()
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
mIsAskingPermissions = false
|
||||
|
||||
if (requestCode == CAMERA_STORAGE_PERMISSION) {
|
||||
if (hasCameraAndStoragePermission()) {
|
||||
initializeCamera()
|
||||
handleIntent()
|
||||
} else {
|
||||
toast(R.string.no_permissions)
|
||||
finish()
|
||||
}
|
||||
} else if (requestCode == AUDIO_PERMISSION) {
|
||||
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
togglePhotoVideo()
|
||||
} else {
|
||||
toast(R.string.no_audio_permissions)
|
||||
if (mIsVideoCaptureIntent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleCamera() {
|
||||
if (!checkCameraAvailable()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (mCurrCamera == Camera.CameraInfo.CAMERA_FACING_BACK) {
|
||||
mCurrCamera = Camera.CameraInfo.CAMERA_FACING_FRONT
|
||||
} else {
|
||||
mCurrCamera = Camera.CameraInfo.CAMERA_FACING_BACK
|
||||
}
|
||||
|
||||
config.lastUsedCamera = mCurrCamera
|
||||
var newIconId = R.mipmap.camera_front
|
||||
mPreview.releaseCamera()
|
||||
if (mPreview.setCamera(mCurrCamera)) {
|
||||
if (mCurrCamera == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
||||
newIconId = R.mipmap.camera_back
|
||||
}
|
||||
toggle_camera.setImageResource(newIconId)
|
||||
disableFlash()
|
||||
hideTimer()
|
||||
} else {
|
||||
toast(R.string.camera_switch_error)
|
||||
}
|
||||
}
|
||||
|
||||
fun showLastMediaPreview() {
|
||||
if (mPreviewUri == null)
|
||||
return
|
||||
|
||||
try {
|
||||
val REVIEW_ACTION = "com.android.camera.action.REVIEW"
|
||||
val intent = Intent(REVIEW_ACTION, mPreviewUri)
|
||||
startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
val intent = Intent(Intent.ACTION_VIEW, mPreviewUri)
|
||||
if (intent.resolveActivity(packageManager) != null) {
|
||||
startActivity(intent)
|
||||
} else {
|
||||
toast(R.string.no_gallery_app_available)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleFlash() {
|
||||
if (!checkCameraAvailable()) {
|
||||
return
|
||||
}
|
||||
|
||||
mIsFlashEnabled = !mIsFlashEnabled
|
||||
checkFlash()
|
||||
}
|
||||
|
||||
private fun checkFlash() {
|
||||
if (mIsFlashEnabled) {
|
||||
enableFlash()
|
||||
} else {
|
||||
disableFlash()
|
||||
}
|
||||
}
|
||||
|
||||
private fun disableFlash() {
|
||||
mPreview.disableFlash()
|
||||
toggle_flash.setImageResource(R.mipmap.flash_off)
|
||||
mIsFlashEnabled = false
|
||||
config.lastFlashlightState = mIsFlashEnabled
|
||||
}
|
||||
|
||||
private fun enableFlash() {
|
||||
mPreview.enableFlash()
|
||||
toggle_flash.setImageResource(R.mipmap.flash_on)
|
||||
mIsFlashEnabled = true
|
||||
config.lastFlashlightState = mIsFlashEnabled
|
||||
}
|
||||
|
||||
private fun shutterPressed() {
|
||||
if (checkCameraAvailable()) {
|
||||
handleShutter()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleShutter() {
|
||||
if (mIsInPhotoMode) {
|
||||
toggleBottomButtons(true)
|
||||
mPreview.takePicture()
|
||||
Handler().postDelayed({ toggleBottomButtons(false) }, Preview.PHOTO_PREVIEW_LENGTH.toLong())
|
||||
} else {
|
||||
val isRecording = mPreview.toggleRecording()
|
||||
if (isRecording) {
|
||||
shutter.setImageDrawable(mRes.getDrawable(R.mipmap.video_stop))
|
||||
toggle_camera.visibility = View.INVISIBLE
|
||||
showTimer()
|
||||
} else {
|
||||
shutter.setImageDrawable(mRes.getDrawable(R.mipmap.video_rec))
|
||||
toggle_camera.visibility = View.VISIBLE
|
||||
hideTimer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleBottomButtons(hide: Boolean) {
|
||||
val alpha = if (hide) 0f else 1f
|
||||
shutter.animate().alpha(alpha).start()
|
||||
toggle_camera.animate().alpha(alpha).start()
|
||||
toggle_flash.animate().alpha(alpha).start()
|
||||
}
|
||||
|
||||
fun launchSettings() {
|
||||
if (settings.alpha == 1f) {
|
||||
val intent = Intent(applicationContext, SettingsActivity::class.java)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
fadeInButtons()
|
||||
}
|
||||
}
|
||||
|
||||
fun handleTogglePhotoVideo() {
|
||||
togglePhotoVideo()
|
||||
checkButtons()
|
||||
}
|
||||
|
||||
private fun togglePhotoVideo() {
|
||||
if (!checkCameraAvailable()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!Utils.hasAudioPermission(applicationContext)) {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECORD_AUDIO), AUDIO_PERMISSION)
|
||||
mIsAskingPermissions = true
|
||||
return
|
||||
}
|
||||
|
||||
if (mIsVideoCaptureIntent)
|
||||
mPreview.trySwitchToVideo()
|
||||
|
||||
disableFlash()
|
||||
hideTimer()
|
||||
mIsInPhotoMode = !mIsInPhotoMode
|
||||
toggle_camera.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun checkButtons() {
|
||||
if (mIsInPhotoMode) {
|
||||
initPhotoButtons()
|
||||
} else {
|
||||
tryInitVideoButtons()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initPhotoButtons() {
|
||||
toggle_photo_video.setImageDrawable(mRes.getDrawable(R.mipmap.videocam))
|
||||
shutter.setImageDrawable(mRes.getDrawable(R.mipmap.camera))
|
||||
mPreview.initPhotoMode()
|
||||
setupPreviewImage(true)
|
||||
}
|
||||
|
||||
private fun tryInitVideoButtons() {
|
||||
if (mPreview.initRecorder()) {
|
||||
initVideoButtons()
|
||||
} else {
|
||||
if (!mIsVideoCaptureIntent) {
|
||||
toast(R.string.video_mode_error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initVideoButtons() {
|
||||
toggle_photo_video.setImageDrawable(mRes.getDrawable(R.mipmap.photo))
|
||||
toggle_camera.visibility = View.VISIBLE
|
||||
shutter.setImageDrawable(mRes.getDrawable(R.mipmap.video_rec))
|
||||
checkFlash()
|
||||
setupPreviewImage(false)
|
||||
}
|
||||
|
||||
private fun setupPreviewImage(isPhoto: Boolean) {
|
||||
val uri = if (isPhoto) MediaStore.Images.Media.EXTERNAL_CONTENT_URI else MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
||||
val lastMediaId = getLastMediaId(uri)
|
||||
if (lastMediaId == 0L) {
|
||||
return
|
||||
}
|
||||
val cr = contentResolver
|
||||
mPreviewUri = Uri.withAppendedPath(uri, lastMediaId.toString())
|
||||
var tmb: Bitmap
|
||||
|
||||
if (isPhoto) {
|
||||
tmb = MediaStore.Images.Thumbnails.getThumbnail(cr, lastMediaId, MediaStore.Images.Thumbnails.MICRO_KIND, null)
|
||||
val rotationDegrees = getImageRotation()
|
||||
tmb = rotateThumbnail(tmb, rotationDegrees)
|
||||
} else {
|
||||
tmb = MediaStore.Video.Thumbnails.getThumbnail(cr, lastMediaId, MediaStore.Video.Thumbnails.MICRO_KIND, null)
|
||||
}
|
||||
|
||||
setPreviewImage(tmb)
|
||||
}
|
||||
|
||||
private fun getImageRotation(): Int {
|
||||
val projection = arrayOf(MediaStore.Images.ImageColumns.ORIENTATION)
|
||||
var cursor: Cursor? = null
|
||||
try {
|
||||
cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null)
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
val orientationIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION)
|
||||
return cursor.getInt(orientationIndex)
|
||||
}
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
private fun rotateThumbnail(tmb: Bitmap, degrees: Int): Bitmap {
|
||||
if (degrees == 0)
|
||||
return tmb
|
||||
|
||||
val matrix = Matrix()
|
||||
matrix.setRotate(degrees.toFloat(), (tmb.width / 2).toFloat(), (tmb.height / 2).toFloat())
|
||||
return Bitmap.createBitmap(tmb, 0, 0, tmb.width, tmb.height, matrix, true)
|
||||
}
|
||||
|
||||
private fun setPreviewImage(bmp: Bitmap?) {
|
||||
if (bmp != null) {
|
||||
last_photo_video_preview.post { last_photo_video_preview.setImageBitmap(bmp) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLastMediaId(uri: Uri): Long {
|
||||
val projection = arrayOf(MediaStore.Images.ImageColumns._ID)
|
||||
var cursor: Cursor? = null
|
||||
try {
|
||||
cursor = contentResolver.query(uri, projection, null, null, "${MediaStore.Images.ImageColumns.DATE_TAKEN} DESC")
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
val idIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID)
|
||||
return cursor.getLong(idIndex)
|
||||
}
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
private fun scheduleFadeOut() = mFadeHandler.postDelayed({ fadeOutButtons() }, FADE_DELAY.toLong())
|
||||
|
||||
private fun fadeOutButtons() {
|
||||
fadeAnim(settings, .5f)
|
||||
fadeAnim(toggle_photo_video, .0f)
|
||||
fadeAnim(last_photo_video_preview, .0f)
|
||||
}
|
||||
|
||||
private fun fadeInButtons() {
|
||||
fadeAnim(settings, 1f)
|
||||
fadeAnim(toggle_photo_video, 1f)
|
||||
fadeAnim(last_photo_video_preview, 1f)
|
||||
scheduleFadeOut()
|
||||
}
|
||||
|
||||
private fun fadeAnim(view: View, value: Float) {
|
||||
view.animate().alpha(value).start()
|
||||
view.isClickable = value != .0f
|
||||
}
|
||||
|
||||
private fun hideNavigationBarIcons() {
|
||||
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE
|
||||
}
|
||||
|
||||
private fun hideTimer() {
|
||||
video_rec_curr_timer.text = Utils.formatSeconds(0)
|
||||
video_rec_curr_timer.visibility = View.GONE
|
||||
mCurrVideoRecTimer = 0
|
||||
mTimerHandler.removeCallbacksAndMessages(null)
|
||||
}
|
||||
|
||||
private fun showTimer() {
|
||||
video_rec_curr_timer.visibility = View.VISIBLE
|
||||
setupTimer()
|
||||
}
|
||||
|
||||
private fun setupTimer() {
|
||||
runOnUiThread(object : Runnable {
|
||||
override fun run() {
|
||||
video_rec_curr_timer.text = Utils.formatSeconds(mCurrVideoRecTimer++)
|
||||
mTimerHandler.postDelayed(this, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (hasCameraAndStoragePermission()) {
|
||||
resumeCameraItems()
|
||||
setupPreviewImage(mIsInPhotoMode)
|
||||
scheduleFadeOut()
|
||||
|
||||
if (mIsVideoCaptureIntent && mIsInPhotoMode) {
|
||||
togglePhotoVideo()
|
||||
checkButtons()
|
||||
}
|
||||
}
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
}
|
||||
|
||||
private fun resumeCameraItems() {
|
||||
val cnt = Camera.getNumberOfCameras()
|
||||
if (cnt == 1) {
|
||||
toggle_camera.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
if (mPreview.setCamera(mCurrCamera)) {
|
||||
hideNavigationBarIcons()
|
||||
checkFlash()
|
||||
|
||||
val accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
|
||||
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME)
|
||||
|
||||
if (!mIsInPhotoMode) {
|
||||
initVideoButtons()
|
||||
}
|
||||
} else {
|
||||
toast(R.string.camera_switch_error)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
if (!hasCameraAndStoragePermission() || mIsAskingPermissions)
|
||||
return
|
||||
|
||||
mFadeHandler.removeCallbacksAndMessages(null)
|
||||
|
||||
hideTimer()
|
||||
mPreview.releaseCamera()
|
||||
mSensorManager.unregisterListener(this)
|
||||
}
|
||||
|
||||
override fun onSensorChanged(event: SensorEvent) {
|
||||
if (event.values[0] < 6.5 && event.values[0] > -6.5) {
|
||||
mOrientation = Constants.ORIENT_PORTRAIT
|
||||
} else {
|
||||
if (event.values[0] > 0) {
|
||||
mOrientation = Constants.ORIENT_LANDSCAPE_LEFT
|
||||
} else {
|
||||
mOrientation = Constants.ORIENT_LANDSCAPE_RIGHT
|
||||
}
|
||||
}
|
||||
|
||||
if (mOrientation != mLastHandledOrientation) {
|
||||
val degrees = when (mOrientation) {
|
||||
Constants.ORIENT_LANDSCAPE_LEFT -> 90
|
||||
Constants.ORIENT_LANDSCAPE_RIGHT -> -90
|
||||
else -> 0
|
||||
}
|
||||
|
||||
animateViews(degrees)
|
||||
mLastHandledOrientation = mOrientation
|
||||
}
|
||||
}
|
||||
|
||||
private fun animateViews(degrees: Int) {
|
||||
val views = arrayOf<View>(toggle_camera, toggle_flash, toggle_photo_video, shutter, settings, last_photo_video_preview)
|
||||
for (view in views) {
|
||||
rotate(view, degrees)
|
||||
}
|
||||
}
|
||||
|
||||
private fun rotate(view: View, degrees: Int) = view.animate().rotation(degrees.toFloat()).start()
|
||||
|
||||
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
|
||||
}
|
||||
|
||||
private fun checkCameraAvailable(): Boolean {
|
||||
if (!mIsCameraAvailable) {
|
||||
toast(R.string.camera_unavailable)
|
||||
}
|
||||
return mIsCameraAvailable
|
||||
}
|
||||
|
||||
override fun setFlashAvailable(available: Boolean) {
|
||||
if (available) {
|
||||
toggle_flash.visibility = View.VISIBLE
|
||||
} else {
|
||||
toggle_flash.visibility = View.INVISIBLE
|
||||
disableFlash()
|
||||
}
|
||||
}
|
||||
|
||||
override fun setIsCameraAvailable(available: Boolean) {
|
||||
mIsCameraAvailable = available
|
||||
}
|
||||
|
||||
override fun getCurrentOrientation() = mOrientation
|
||||
|
||||
override fun videoSaved(uri: Uri) {
|
||||
setupPreviewImage(mIsInPhotoMode)
|
||||
if (mIsVideoCaptureIntent) {
|
||||
Intent().apply {
|
||||
data = uri
|
||||
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
setResult(Activity.RESULT_OK, this)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun drawFocusRect(x: Int, y: Int) = mFocusRectView.drawFocusRect(x, y)
|
||||
|
||||
override fun mediaSaved(path: String) {
|
||||
val paths = arrayOf(path)
|
||||
MediaScannerConnection.scanFile(applicationContext, paths, null, this)
|
||||
|
||||
if (mIsImageCaptureIntent) {
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
config.isFirstRun = false
|
||||
mPreview.releaseCamera()
|
||||
}
|
||||
|
||||
override fun onScanCompleted(path: String, uri: Uri) = setupPreviewImage(mIsInPhotoMode)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user