diff --git a/app/build.gradle b/app/build.gradle index 56991e82..1b196158 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,13 +3,13 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion 27 - buildToolsVersion "27.0.3" + compileSdkVersion 28 + buildToolsVersion "28.0.3" defaultConfig { applicationId "com.simplemobiletools.camera" - minSdkVersion 16 - targetSdkVersion 27 + minSdkVersion 21 + targetSdkVersion 28 versionCode 63 versionName "4.2.0" setProperty("archivesBaseName", "camera") @@ -41,7 +41,7 @@ android { } dependencies { - implementation 'com.simplemobiletools:commons:4.6.4' + implementation 'com.simplemobiletools:commons:5.1.4' } Properties props = new Properties() diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 28fc0e04..a6242280 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -102,7 +102,7 @@ diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt index 5bb8154b..f263f3f6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt @@ -16,14 +16,12 @@ import com.bumptech.glide.request.RequestOptions import com.simplemobiletools.camera.BuildConfig import com.simplemobiletools.camera.R import com.simplemobiletools.camera.extensions.config -import com.simplemobiletools.camera.extensions.getMyCamera import com.simplemobiletools.camera.extensions.navBarHeight import com.simplemobiletools.camera.helpers.* -import com.simplemobiletools.camera.interfaces.MyCamera +import com.simplemobiletools.camera.implementations.MyCameraImpl import com.simplemobiletools.camera.interfaces.MyPreview +import com.simplemobiletools.camera.views.CameraPreview import com.simplemobiletools.camera.views.FocusCircleView -import com.simplemobiletools.camera.views.PreviewCameraOne -import com.simplemobiletools.camera.views.PreviewCameraTwo import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.Release @@ -36,7 +34,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { private lateinit var mOrientationEventListener: OrientationEventListener private lateinit var mFocusCircleView: FocusCircleView private lateinit var mFadeHandler: Handler - private lateinit var mCameraImpl: MyCamera + private lateinit var mCameraImpl: MyCameraImpl private var mPreview: MyPreview? = null private var mPreviewUri: Uri? = null @@ -116,7 +114,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { mIsHardwareShutterHandled = false mCurrVideoRecTimer = 0 mLastHandledOrientation = 0 - mCameraImpl = getMyCamera() + mCameraImpl = MyCameraImpl(applicationContext) if (config.alwaysOpenBackCamera) { config.lastUsedCamera = mCameraImpl.getBackCameraId().toString() @@ -193,13 +191,10 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { setContentView(R.layout.activity_main) initButtons() - camera_surface_view.beVisibleIf(!isLollipopPlus()) - camera_texture_view.beVisibleIf(isLollipopPlus()) - (btn_holder.layoutParams as RelativeLayout.LayoutParams).setMargins(0, 0, 0, (navBarHeight + resources.getDimension(R.dimen.activity_margin)).toInt()) checkVideoCaptureIntent() - mPreview = if (isLollipopPlus()) PreviewCameraTwo(this, camera_texture_view, mIsInPhotoMode) else PreviewCameraOne(this, camera_surface_view) + mPreview = CameraPreview(this, camera_texture_view, mIsInPhotoMode) view_holder.addView(mPreview as ViewGroup) checkImageCaptureIntent() mPreview?.setIsImageCaptureIntent(isImageCaptureIntent()) @@ -373,7 +368,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { mPreviewUri = Uri.withAppendedPath(uri, lastMediaId.toString()) runOnUiThread { - if (!isActivityDestroyed()) { + if (!isDestroyed) { val options = RequestOptions() .centerCrop() .diskCacheStrategy(DiskCacheStrategy.NONE) @@ -419,14 +414,6 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE } - fun toggleTimer(show: Boolean) { - if (show) { - showTimer() - } else { - hideTimer() - } - } - private fun showTimer() { video_rec_curr_timer.beVisible() setupTimer() @@ -450,14 +437,10 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { private fun resumeCameraItems() { showToggleCameraIfNeeded() - if (mPreview?.resumeCamera() == true) { - hideNavigationBarIcons() + hideNavigationBarIcons() - if (!mIsInPhotoMode) { - initVideoButtons() - } - } else { - toast(R.string.camera_switch_error) + if (!mIsInPhotoMode) { + initVideoButtons() } } @@ -470,7 +453,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { private fun setupOrientationEventListener() { mOrientationEventListener = object : OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) { override fun onOrientationChanged(orientation: Int) { - if (isActivityDestroyed()) { + if (isDestroyed) { mOrientationEventListener.disable() return } @@ -490,7 +473,6 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { animateViews(degrees) mLastHandledOrientation = currOrient - mPreview?.deviceOrientationChanged() } } } @@ -555,7 +537,6 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener { fun drawFocusCircle(x: Float, y: Float) = mFocusCircleView.drawFocusCircle(x, y) override fun mediaSaved(path: String) { - mPreview?.imageSaved() rescanPaths(arrayListOf(path)) { setupPreviewImage(true) Intent(BROADCAST_REFRESH_MEDIA).apply { diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/camera/activities/SettingsActivity.kt index e25e35b7..422d09f1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/activities/SettingsActivity.kt @@ -10,7 +10,6 @@ import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.LICENSE_GLIDE -import com.simplemobiletools.commons.helpers.isLollipopPlus import com.simplemobiletools.commons.models.FAQItem import com.simplemobiletools.commons.models.RadioItem import kotlinx.android.synthetic.main.activity_settings.* @@ -29,7 +28,6 @@ class SettingsActivity : SimpleActivity() { setupCustomizeColors() setupUseEnglish() setupAvoidWhatsNew() - setupShowPreview() setupSound() setupFocusBeforeCapture() setupVolumeButtonsAsShutter() @@ -111,15 +109,6 @@ class SettingsActivity : SimpleActivity() { return humanized.substringAfterLast("/", humanized) } - private fun setupShowPreview() { - settings_show_preview_holder.beVisibleIf(!isLollipopPlus()) - settings_show_preview.isChecked = config.isShowPreviewEnabled - settings_show_preview_holder.setOnClickListener { - settings_show_preview.toggle() - config.isShowPreviewEnabled = settings_show_preview.isChecked - } - } - private fun setupSound() { settings_sound.isChecked = config.isSoundEnabled settings_sound_holder.setOnClickListener { diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/dialogs/ChangeResolutionDialog.kt b/app/src/main/kotlin/com/simplemobiletools/camera/dialogs/ChangeResolutionDialog.kt index 25ffb6fb..8b589cd2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/dialogs/ChangeResolutionDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/dialogs/ChangeResolutionDialog.kt @@ -1,8 +1,8 @@ package com.simplemobiletools.camera.dialogs -import android.support.v7.app.AlertDialog import android.view.LayoutInflater import android.view.View +import androidx.appcompat.app.AlertDialog import com.simplemobiletools.camera.R import com.simplemobiletools.camera.activities.SimpleActivity import com.simplemobiletools.camera.extensions.config diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Context.kt index f4770ef0..fd5b027e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Context.kt @@ -4,9 +4,6 @@ import android.content.Context import android.graphics.Point import android.view.WindowManager import com.simplemobiletools.camera.helpers.Config -import com.simplemobiletools.camera.implementations.MyCameraOneImpl -import com.simplemobiletools.camera.implementations.MyCameraTwoImpl -import com.simplemobiletools.commons.helpers.isLollipopPlus import java.io.File import java.text.SimpleDateFormat import java.util.* @@ -47,5 +44,3 @@ val Context.realScreenSize: Point } val Context.navBarHeight: Int get() = realScreenSize.y - usableScreenSize.y - -fun Context.getMyCamera() = if (isLollipopPlus()) MyCameraTwoImpl(applicationContext) else MyCameraOneImpl(applicationContext) diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Size.kt b/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Size.kt deleted file mode 100644 index ffd2c630..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/camera/extensions/Size.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.simplemobiletools.camera.extensions - -import android.content.Context -import android.hardware.Camera -import com.simplemobiletools.camera.R - diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/camera/helpers/Config.kt index 94e89aaf..d52c6cfb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/helpers/Config.kt @@ -21,10 +21,6 @@ class Config(context: Context) : BaseConfig(context) { } set(path) = prefs.edit().putString(SAVE_PHOTOS, path).apply() - var isShowPreviewEnabled: Boolean - get() = prefs.getBoolean(SHOW_PREVIEW, false) - set(enabled) = prefs.edit().putBoolean(SHOW_PREVIEW, enabled).apply() - var isSoundEnabled: Boolean get() = prefs.getBoolean(SOUND, true) set(enabled) = prefs.edit().putBoolean(SOUND, enabled).apply() @@ -73,10 +69,6 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getInt(FRONT_VIDEO_RESOLUTION_INDEX, 0) set(frontVideoResIndex) = prefs.edit().putInt(FRONT_VIDEO_RESOLUTION_INDEX, frontVideoResIndex).apply() - var wasPhotoPreviewHintShown: Boolean - get() = prefs.getBoolean(PHOTO_PREVIEW_HINT_SHOWN, false) - set(wasPhotoPreviewHintShown) = prefs.edit().putBoolean(PHOTO_PREVIEW_HINT_SHOWN, wasPhotoPreviewHintShown).apply() - var keepSettingsVisible: Boolean get() = prefs.getBoolean(KEEP_SETTINGS_VISIBLE, false) set(keepSettingsVisible) = prefs.edit().putBoolean(KEEP_SETTINGS_VISIBLE, keepSettingsVisible).apply() diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/camera/helpers/Constants.kt index b16e441e..66c59abe 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/helpers/Constants.kt @@ -6,7 +6,6 @@ const val ORIENT_LANDSCAPE_RIGHT = 2 // shared preferences const val SAVE_PHOTOS = "save_photos" -const val SHOW_PREVIEW = "show_preview" const val SOUND = "sound" const val FOCUS_BEFORE_CAPTURE = "focus_before_capture_2" const val VOLUME_BUTTONS_AS_SHUTTER = "volume_buttons_as_shutter" @@ -19,7 +18,6 @@ const val BACK_PHOTO_RESOLUTION_INDEX = "back_photo_resolution_index_2" const val BACK_VIDEO_RESOLUTION_INDEX = "back_video_resolution_index_2" const val FRONT_PHOTO_RESOLUTION_INDEX = "front_photo_resolution_index_2" const val FRONT_VIDEO_RESOLUTION_INDEX = "front_video_resolution_index_2" -const val PHOTO_PREVIEW_HINT_SHOWN = "photo_preview_hint_shown" const val KEEP_SETTINGS_VISIBLE = "keep_settings_visible" const val ALWAYS_OPEN_BACK_CAMERA = "always_open_back_camera" const val SAVE_PHOTO_METADATA = "save_photo_metadata" diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraImpl.kt b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraImpl.kt new file mode 100644 index 00000000..47872fbe --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraImpl.kt @@ -0,0 +1,16 @@ +package com.simplemobiletools.camera.implementations + +import android.content.Context +import android.hardware.camera2.CameraCharacteristics +import android.hardware.camera2.CameraManager + +class MyCameraImpl(val context: Context) { + fun getFrontCameraId() = CameraCharacteristics.LENS_FACING_FRONT + + fun getBackCameraId() = CameraCharacteristics.LENS_FACING_BACK + + fun getCountOfCameras(): Int { + val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager + return manager.cameraIdList.size + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraOneImpl.kt b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraOneImpl.kt deleted file mode 100644 index 47f1444b..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraOneImpl.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.simplemobiletools.camera.implementations - -import android.content.Context -import android.hardware.Camera -import com.simplemobiletools.camera.interfaces.MyCamera - -class MyCameraOneImpl(val context: Context) : MyCamera() { - override fun getFrontCameraId() = Camera.CameraInfo.CAMERA_FACING_FRONT - - override fun getBackCameraId() = Camera.CameraInfo.CAMERA_FACING_BACK - - override fun getCountOfCameras() = Camera.getNumberOfCameras() -} diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraTwoImpl.kt b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraTwoImpl.kt deleted file mode 100644 index 85e2f285..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/MyCameraTwoImpl.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.simplemobiletools.camera.implementations - -import android.annotation.TargetApi -import android.content.Context -import android.hardware.camera2.CameraCharacteristics -import android.hardware.camera2.CameraManager -import android.os.Build -import com.simplemobiletools.camera.interfaces.MyCamera - -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -class MyCameraTwoImpl(val context: Context) : MyCamera() { - override fun getFrontCameraId() = CameraCharacteristics.LENS_FACING_FRONT - - override fun getBackCameraId() = CameraCharacteristics.LENS_FACING_BACK - - override fun getCountOfCameras(): Int { - val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager - return manager.cameraIdList.size - } -} diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyCamera.kt b/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyCamera.kt deleted file mode 100644 index 3f36fffe..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyCamera.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.simplemobiletools.camera.interfaces - -abstract class MyCamera { - abstract fun getFrontCameraId(): Int - - abstract fun getBackCameraId(): Int - - abstract fun getCountOfCameras(): Int -} diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyPreview.kt b/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyPreview.kt index 8cd8bf5c..f1437148 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyPreview.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/interfaces/MyPreview.kt @@ -32,10 +32,4 @@ interface MyPreview { fun initVideoMode(): Boolean fun checkFlashlight() - - fun deviceOrientationChanged() - - fun resumeCamera(): Boolean - - fun imageSaved() } diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt b/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt index 173d2c15..96b7b65d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt @@ -1,8 +1,6 @@ package com.simplemobiletools.camera.models -import android.annotation.TargetApi import android.content.Context -import android.os.Build import android.util.Size import com.simplemobiletools.camera.R @@ -45,6 +43,5 @@ data class MySize(val width: Int, val height: Int) { else -> context.resources.getString(R.string.other) } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) fun toSize() = Size(width, height) } diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/views/PreviewCameraTwo.kt b/app/src/main/kotlin/com/simplemobiletools/camera/views/CameraPreview.kt similarity index 92% rename from app/src/main/kotlin/com/simplemobiletools/camera/views/PreviewCameraTwo.kt rename to app/src/main/kotlin/com/simplemobiletools/camera/views/CameraPreview.kt index e4bb7276..2ac91357 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/views/PreviewCameraTwo.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/views/CameraPreview.kt @@ -1,7 +1,6 @@ package com.simplemobiletools.camera.views import android.annotation.SuppressLint -import android.annotation.TargetApi import android.content.Context import android.graphics.ImageFormat import android.graphics.Matrix @@ -14,7 +13,6 @@ import android.media.ImageReader import android.media.MediaActionSound import android.media.MediaRecorder import android.net.Uri -import android.os.Build import android.os.Handler import android.os.HandlerThread import android.util.DisplayMetrics @@ -30,30 +28,22 @@ import com.simplemobiletools.camera.R import com.simplemobiletools.camera.activities.MainActivity import com.simplemobiletools.camera.dialogs.ChangeResolutionDialog import com.simplemobiletools.camera.extensions.config -import com.simplemobiletools.camera.extensions.getMyCamera import com.simplemobiletools.camera.extensions.getOutputMediaFile import com.simplemobiletools.camera.helpers.* +import com.simplemobiletools.camera.implementations.MyCameraImpl import com.simplemobiletools.camera.interfaces.MyPreview import com.simplemobiletools.camera.models.FocusArea import com.simplemobiletools.camera.models.MySize import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.helpers.isJellyBean1Plus import com.simplemobiletools.commons.models.FileDirItem import java.io.File -import java.lang.IllegalArgumentException -import java.lang.InterruptedException -import java.lang.Math -import java.lang.System -import java.lang.Thread import java.util.* import java.util.concurrent.Semaphore import java.util.concurrent.TimeUnit -import kotlin.RuntimeException // based on the Android Camera2 photo sample at https://github.com/googlesamples/android-Camera2Basic // and video sample at https://github.com/googlesamples/android-Camera2Video -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPreview { +class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview { private val FOCUS_TAG = "focus_tag" private val MAX_PREVIEW_WIDTH = 1920 private val MAX_PREVIEW_HEIGHT = 1080 @@ -129,7 +119,7 @@ class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPrevie null } - val isFrontCamera = cameraCharacteristics?.get(CameraCharacteristics.LENS_FACING).toString() == activity.getMyCamera().getFrontCameraId().toString() + val isFrontCamera = cameraCharacteristics?.get(CameraCharacteristics.LENS_FACING).toString() == MyCameraImpl(activity).getFrontCameraId().toString() mUseFrontCamera = !activity.config.alwaysOpenBackCamera && isFrontCamera mIsInVideoMode = !initPhotoMode loadSounds() @@ -417,13 +407,8 @@ class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPrevie private fun getRealDisplaySize(): MySize { val metrics = DisplayMetrics() - return if (isJellyBean1Plus()) { - mActivity.windowManager.defaultDisplay.getRealMetrics(metrics) - MySize(metrics.widthPixels, metrics.heightPixels) - } else { - mActivity.windowManager.defaultDisplay.getMetrics(metrics) - MySize(metrics.widthPixels, metrics.heightPixels) - } + mActivity.windowManager.defaultDisplay.getRealMetrics(metrics) + return MySize(metrics.widthPixels, metrics.heightPixels) } private val cameraStateCallback = object : CameraDevice.StateCallback() { @@ -718,53 +703,6 @@ class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPrevie return FocusArea(rect, MeteringRectangle.METERING_WEIGHT_MAX) } - // touch-to-focus stucks after capturing a photo without "Focus before capture" so just reset the whole session until fixed properly - private fun resetPreviewSession() { - val stateCallback = object : CameraCaptureSession.StateCallback() { - override fun onConfigured(cameraCaptureSession: CameraCaptureSession) { - if (mCameraDevice == null) { - return - } - - mCaptureSession = cameraCaptureSession - try { - mPreviewRequestBuilder!!.apply { - set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE) - setFlashAndExposure(this) - mPreviewRequest = build() - } - mCaptureSession!!.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler) - mCameraState = STATE_PREVIEW - - Handler().postDelayed({ - if (mLastFocusX != 0f && mLastFocusY != 0f) { - if (mCaptureSession != null) { - focusArea(mLastFocusX, mLastFocusY, false) - } - } - }, 200L) - } catch (e: Exception) { - } - } - - override fun onConfigureFailed(cameraCaptureSession: CameraCaptureSession) {} - } - - try { - closeCaptureSession() - val texture = mTextureView.surfaceTexture!! - texture.setDefaultBufferSize(mPreviewSize!!.width, mPreviewSize!!.height) - - val currentResolution = getCurrentResolution() - mImageReader = ImageReader.newInstance(currentResolution.width, currentResolution.height, ImageFormat.JPEG, 2) - mImageReader!!.setOnImageAvailableListener(imageAvailableListener, mBackgroundHandler) - - val surface = Surface(texture) - mCameraDevice!!.createCaptureSession(Arrays.asList(surface, mImageReader!!.surface), stateCallback, null) - } catch (e: Exception) { - } - } - private fun calculateCameraToPreviewMatrix() { val yScale = if (mUseFrontCamera) -1 else 1 mCameraToPreviewMatrix.apply { @@ -1034,11 +972,5 @@ class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPrevie } } - override fun deviceOrientationChanged() {} - - override fun resumeCamera() = true - - override fun imageSaved() {} - override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {} } diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/views/PreviewCameraOne.kt b/app/src/main/kotlin/com/simplemobiletools/camera/views/PreviewCameraOne.kt deleted file mode 100644 index 6aa619d0..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/camera/views/PreviewCameraOne.kt +++ /dev/null @@ -1,922 +0,0 @@ -package com.simplemobiletools.camera.views - -import android.annotation.SuppressLint -import android.annotation.TargetApi -import android.app.Activity -import android.content.Context -import android.graphics.Point -import android.graphics.Rect -import android.hardware.Camera -import android.media.AudioManager -import android.media.CamcorderProfile -import android.media.MediaPlayer -import android.media.MediaRecorder -import android.net.Uri -import android.os.Build -import android.os.Environment -import android.os.Handler -import android.view.* -import com.simplemobiletools.camera.R -import com.simplemobiletools.camera.activities.MainActivity -import com.simplemobiletools.camera.dialogs.ChangeResolutionDialog -import com.simplemobiletools.camera.extensions.config -import com.simplemobiletools.camera.extensions.getMyCamera -import com.simplemobiletools.camera.extensions.getOutputMediaFile -import com.simplemobiletools.camera.extensions.realScreenSize -import com.simplemobiletools.camera.helpers.* -import com.simplemobiletools.camera.implementations.MyCameraOneImpl -import com.simplemobiletools.camera.interfaces.MyPreview -import com.simplemobiletools.camera.models.MySize -import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.helpers.isJellyBean1Plus -import java.io.File -import java.io.IOException -import java.util.* - -class PreviewCameraOne : ViewGroup, SurfaceHolder.Callback, MyPreview { - private val FOCUS_AREA_SIZE = 100 - private val PHOTO_PREVIEW_LENGTH = 500L - private val REFOCUS_PERIOD = 3000L - - private lateinit var mSurfaceHolder: SurfaceHolder - private lateinit var mSurfaceView: SurfaceView - private lateinit var mScreenSize: Point - private lateinit var mConfig: Config - private var mSupportedPreviewSizes: List? = null - private var mPreviewSize: Camera.Size? = null - private var mParameters: Camera.Parameters? = null - private var mRecorder: MediaRecorder? = null - private var mScaleGestureDetector: ScaleGestureDetector? = null - private var mZoomRatios = ArrayList() - private var mFlashlightState = FLASH_OFF - private var mCamera: Camera? = null - private var mCameraImpl: MyCameraOneImpl? = null - private var mAutoFocusHandler = Handler() - private var mActivity: MainActivity? = null - private var mTargetUri: Uri? = null - private var mCameraState = STATE_PREVIEW - - private var mCurrVideoPath = "" - private var mCanTakePicture = false - private var mIsRecording = false - private var mIsInVideoMode = false - private var mIsSurfaceCreated = false - private var mSwitchToVideoAsap = false - private var mSetupPreviewAfterMeasure = false - private var mIsSixteenToNine = false - private var mWasZooming = false - private var mIsPreviewShown = false - private var mWasCameraPreviewSet = false - private var mIsImageCaptureIntent = false - private var mIsFocusingBeforeCapture = false - private var mLastClickX = 0f - private var mLastClickY = 0f - private var mCurrCameraId = 0 - private var mMaxZoom = 0 - private var mRotationAtCapture = 0 - - constructor(context: Context) : super(context) - - @SuppressLint("ClickableViewAccessibility") - constructor(activity: MainActivity, surfaceView: SurfaceView) : super(activity) { - mActivity = activity - mSurfaceView = surfaceView - mSurfaceHolder = mSurfaceView.holder - mSurfaceHolder.addCallback(this) - mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) - mCameraImpl = MyCameraOneImpl(activity.applicationContext) - mConfig = activity.config - mScreenSize = getScreenSize() - initGestureDetector() - - mSurfaceView.setOnTouchListener { view, event -> - mLastClickX = event.x - mLastClickY = event.y - - if (mMaxZoom > 0 && mParameters?.isZoomSupported == true) { - mScaleGestureDetector!!.onTouchEvent(event) - } - false - } - - mSurfaceView.setOnClickListener { - if (mIsPreviewShown) { - resumePreview() - } else { - if (!mWasZooming && !mIsPreviewShown) { - focusArea(false) - } - - mWasZooming = false - mSurfaceView.isSoundEffectsEnabled = true - } - } - } - - override fun onResumed() {} - - override fun onPaused() { - releaseCamera() - } - - override fun tryInitVideoMode() { - if (mIsSurfaceCreated) { - initVideoMode() - } else { - mSwitchToVideoAsap = true - } - } - - override fun resumeCamera(): Boolean { - val newCamera: Camera - try { - newCamera = Camera.open(mCurrCameraId) - mActivity!!.setIsCameraAvailable(true) - } catch (e: Exception) { - mActivity!!.showErrorToast(e) - mActivity!!.setIsCameraAvailable(false) - return false - } - - if (mCamera === newCamera) { - return false - } - - releaseCamera() - mCamera = newCamera - if (initCamera() && mIsInVideoMode) { - initVideoMode() - } - - if (!mWasCameraPreviewSet && mIsSurfaceCreated) { - mCamera!!.setPreviewDisplay(mSurfaceHolder) - mWasCameraPreviewSet = true - } - return true - } - - override fun imageSaved() {} - - private fun initCamera(): Boolean { - if (mCamera == null) - return false - - mParameters = mCamera!!.parameters - mMaxZoom = mParameters!!.maxZoom - - if (mParameters!!.isZoomSupported) - mZoomRatios = mParameters!!.zoomRatios as ArrayList - - mSupportedPreviewSizes = mParameters!!.supportedPreviewSizes.sortedByDescending { it.width * it.height } - refreshPreview() - - // hackfix for slow photo preview, more info at https://github.com/SimpleMobileTools/Simple-Camera/issues/120 - if (Build.MODEL == "Nexus 4") { - mParameters!!.setRecordingHint(true) - } - - val focusModes = mParameters!!.supportedFocusModes - if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { - mParameters!!.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE - } - - mCamera!!.setDisplayOrientation(getPreviewRotation(mCurrCameraId)) - mParameters!!.zoom = 0 - updateCameraParameters() - - if (mCanTakePicture) { - try { - mCamera!!.setPreviewDisplay(mSurfaceHolder) - } catch (e: IOException) { - mActivity!!.showErrorToast(e) - return false - } - } - - mActivity!!.setFlashAvailable(hasFlash(mCamera)) - return true - } - - override fun toggleFrontBackCamera() { - mCurrCameraId = if (mCurrCameraId == mCameraImpl!!.getBackCameraId()) { - mCameraImpl!!.getFrontCameraId() - } else { - mCameraImpl!!.getBackCameraId() - } - - mConfig.lastUsedCamera = mCurrCameraId.toString() - releaseCamera() - if (resumeCamera()) { - setFlashlightState(FLASH_OFF) - mActivity?.updateCameraIcon(mCurrCameraId == mCameraImpl!!.getFrontCameraId()) - mActivity?.toggleTimer(false) - } else { - mActivity?.toast(R.string.camera_switch_error) - } - } - - override fun getCameraState() = mCameraState - - private fun refreshPreview() { - mIsSixteenToNine = getSelectedResolution().isSixteenToNine() - mSetupPreviewAfterMeasure = true - requestLayout() - invalidate() - rescheduleAutofocus() - } - - private fun getSelectedResolution(): MySize { - if (mParameters == null) { - mParameters = mCamera!!.parameters - } - - var index = getResolutionIndex() - val resolutions = if (mIsInVideoMode) { - mParameters!!.supportedVideoSizes ?: mParameters!!.supportedPreviewSizes - } else { - mParameters!!.supportedPictureSizes - }.map { MySize(it.width, it.height) }.sortedByDescending { it.width * it.height } - - if (index == -1) { - index = getDefaultFullscreenResolution(resolutions) ?: 0 - } - - return resolutions[index] - } - - private fun getResolutionIndex(): Int { - val isBackCamera = mConfig.lastUsedCamera == Camera.CameraInfo.CAMERA_FACING_BACK.toString() - return if (mIsInVideoMode) { - if (isBackCamera) mConfig.backVideoResIndex else mConfig.frontVideoResIndex - } else { - if (isBackCamera) mConfig.backPhotoResIndex else mConfig.frontPhotoResIndex - } - } - - private fun getDefaultFullscreenResolution(resolutions: List): Int? { - val screenAspectRatio = mActivity!!.realScreenSize.y / mActivity!!.realScreenSize.x.toFloat() - resolutions.forEachIndexed { index, size -> - val diff = screenAspectRatio - (size.width / size.height.toFloat()) - if (Math.abs(diff) < 0.1f) { - mConfig.backPhotoResIndex = index - return index - } - } - return null - } - - private fun initGestureDetector() { - mScaleGestureDetector = ScaleGestureDetector(mActivity, object : ScaleGestureDetector.SimpleOnScaleGestureListener() { - override fun onScale(detector: ScaleGestureDetector): Boolean { - val zoomFactor = mParameters!!.zoom - var zoomRatio = mZoomRatios[zoomFactor] / 100f - zoomRatio *= detector.scaleFactor - - var newZoomFactor = zoomFactor - if (zoomRatio <= 1f) { - newZoomFactor = 0 - } else if (zoomRatio >= mZoomRatios[mMaxZoom] / 100f) { - newZoomFactor = mMaxZoom - } else { - if (detector.scaleFactor > 1f) { - for (i in zoomFactor until mZoomRatios.size) { - if (mZoomRatios[i] / 100.0f >= zoomRatio) { - newZoomFactor = i - break - } - } - } else { - for (i in zoomFactor downTo 0) { - if (mZoomRatios[i] / 100.0f <= zoomRatio) { - newZoomFactor = i - break - } - } - } - } - - newZoomFactor = Math.max(newZoomFactor, 0) - newZoomFactor = Math.min(mMaxZoom, newZoomFactor) - - mParameters!!.zoom = newZoomFactor - updateCameraParameters() - return true - } - - override fun onScaleEnd(detector: ScaleGestureDetector) { - super.onScaleEnd(detector) - mWasZooming = true - mSurfaceView.isSoundEffectsEnabled = false - mParameters!!.focusAreas = null - } - }) - } - - override fun tryTakePicture() { - if (mConfig.focusBeforeCapture) { - focusArea(true) - } else { - takePicture() - } - } - - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) - private fun takePicture() { - if (mCanTakePicture) { - val selectedResolution = getSelectedResolution() - mParameters!!.setPictureSize(selectedResolution.width, selectedResolution.height) - val pictureSize = mParameters!!.pictureSize - if (selectedResolution.width != pictureSize.width || selectedResolution.height != pictureSize.height) { - mActivity!!.toast(R.string.setting_resolution_failed) - } - - if (isJellyBean1Plus()) { - mCamera!!.enableShutterSound(false) - } - - mRotationAtCapture = mActivity!!.mLastHandledOrientation - updateCameraParameters() - mCameraState = STATE_PICTURE_TAKEN - mIsPreviewShown = true - try { - Thread { - mCamera!!.takePicture(null, null, takePictureCallback) - - if (mConfig.isSoundEnabled) { - val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager - val volume = audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM) - if (volume != 0) { - val mp = MediaPlayer.create(context, Uri.parse("file:///system/media/audio/ui/camera_click.ogg")) - mp?.start() - } - } - }.start() - } catch (ignored: Exception) { - } - } - mCanTakePicture = false - mIsFocusingBeforeCapture = false - } - - private val takePictureCallback = Camera.PictureCallback { data, cam -> - if (data.isEmpty()) { - mActivity!!.toast(R.string.unknown_error_occurred) - return@PictureCallback - } - - mCameraState = STATE_PREVIEW - if (!mIsImageCaptureIntent) { - handlePreview() - } - - if (mIsImageCaptureIntent) { - if (mTargetUri != null) { - storePhoto(data) - } else { - mActivity!!.apply { - setResult(Activity.RESULT_OK) - finish() - } - } - } else { - storePhoto(data) - } - } - - private fun storePhoto(data: ByteArray) { - val previewRotation = getPreviewRotation(mCurrCameraId) - PhotoProcessor(mActivity!!, mTargetUri, mRotationAtCapture, previewRotation, getIsUsingFrontCamera(), mIsImageCaptureIntent).execute(data) - } - - private fun getIsUsingFrontCamera() = mCurrCameraId == mActivity!!.getMyCamera().getFrontCameraId() - - private fun handlePreview() { - if (mConfig.isShowPreviewEnabled) { - if (!mConfig.wasPhotoPreviewHintShown) { - mActivity!!.toast(R.string.click_to_resume_preview) - mConfig.wasPhotoPreviewHintShown = true - } - } else { - Handler().postDelayed({ - mIsPreviewShown = false - resumePreview() - }, PHOTO_PREVIEW_LENGTH) - } - } - - private fun resumePreview() { - mIsPreviewShown = false - mActivity!!.toggleBottomButtons(false) - try { - mCamera?.startPreview() - } catch (ignored: Exception) { - } - mCanTakePicture = true - focusArea(false, false) - } - - private fun focusArea(takePictureAfter: Boolean, showFocusRect: Boolean = true) { - if (mCamera == null || (mIsFocusingBeforeCapture && !takePictureAfter)) { - return - } - - if (takePictureAfter) { - mIsFocusingBeforeCapture = true - } - - mCamera!!.cancelAutoFocus() - if (mParameters!!.maxNumFocusAreas > 0) { - if (mLastClickX == 0f && mLastClickY == 0f) { - mLastClickX = width / 2.toFloat() - mLastClickY = height / 2.toFloat() - } - - val focusRect = calculateFocusArea(mLastClickX, mLastClickY) - val focusAreas = ArrayList(1) - focusAreas.add(Camera.Area(focusRect, 1000)) - mParameters!!.focusAreas = focusAreas - - if (showFocusRect) { - mActivity!!.drawFocusCircle(mLastClickX, mLastClickY) - } - } - - try { - val focusModes = mParameters!!.supportedFocusModes - if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { - mParameters!!.focusMode = Camera.Parameters.FOCUS_MODE_AUTO - } - - updateCameraParameters() - mCamera!!.autoFocus { success, camera -> - if (camera == null || mCamera == null) { - return@autoFocus - } - - mCamera!!.cancelAutoFocus() - if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { - mParameters!!.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE - } - - updateCameraParameters() - - if (takePictureAfter) { - takePicture() - } else { - rescheduleAutofocus() - } - } - } catch (ignored: Exception) { - } - } - - private fun calculateFocusArea(x: Float, y: Float): Rect { - var left = x / mSurfaceView.width * 2000 - 1000 - var top = y / mSurfaceView.height * 2000 - 1000 - - val tmp = left - left = top - top = -tmp - - val rectLeft = Math.max(left.toInt() - FOCUS_AREA_SIZE / 2, -1000) - val rectTop = Math.max(top.toInt() - FOCUS_AREA_SIZE / 2, -1000) - val rectRight = Math.min(left.toInt() + FOCUS_AREA_SIZE / 2, 1000) - val rectBottom = Math.min(top.toInt() + FOCUS_AREA_SIZE / 2, 1000) - return Rect(rectLeft, rectTop, rectRight, rectBottom) - } - - private fun rescheduleAutofocus() { - mAutoFocusHandler.removeCallbacksAndMessages(null) - mAutoFocusHandler.postDelayed({ - if (!mIsInVideoMode || !mIsRecording) { - focusArea(false, false) - } - }, REFOCUS_PERIOD) - } - - override fun showChangeResolutionDialog() { - if (mCamera != null) { - val oldResolution = getSelectedResolution() - val photoResolutions = mCamera!!.parameters.supportedPictureSizes.map { MySize(it.width, it.height) } as ArrayList - val videoSizes = mCamera!!.parameters.supportedVideoSizes ?: mCamera!!.parameters.supportedPreviewSizes - val videoResolutions = videoSizes.map { MySize(it.width, it.height) } as ArrayList - ChangeResolutionDialog(mActivity!!, getIsUsingFrontCamera(), photoResolutions, videoResolutions, false) { - if (oldResolution != getSelectedResolution()) { - refreshPreview() - } - } - } - } - - fun releaseCamera() { - stopRecording() - mCamera?.stopPreview() - mCamera?.release() - mCamera = null - cleanupRecorder() - } - - override fun surfaceCreated(holder: SurfaceHolder) { - mIsSurfaceCreated = true - try { - mWasCameraPreviewSet = mCamera != null - mCamera?.setPreviewDisplay(mSurfaceHolder) - - if (mSwitchToVideoAsap) - initVideoMode() - } catch (e: IOException) { - mActivity!!.showErrorToast(e) - } - } - - override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { - mIsSurfaceCreated = true - - if (mIsInVideoMode) { - initVideoMode() - } - } - - override fun surfaceDestroyed(holder: SurfaceHolder) { - mIsSurfaceCreated = false - mCamera?.stopPreview() - cleanupRecorder() - } - - private fun setupPreview() { - mCanTakePicture = true - if (mCamera != null && mPreviewSize != null) { - if (mParameters == null) - mParameters = mCamera!!.parameters - - mParameters!!.setPreviewSize(mPreviewSize!!.width, mPreviewSize!!.height) - updateCameraParameters() - try { - mCamera!!.startPreview() - } catch (e: RuntimeException) { - mActivity!!.showErrorToast(e) - } - } - } - - private fun cleanupRecorder() { - if (mRecorder != null) { - if (mIsRecording) { - stopRecording() - } - - mRecorder!!.release() - mRecorder = null - } - } - - override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {} - - private fun getOptimalPreviewSize(sizes: List, width: Int, height: Int): Camera.Size { - var result: Camera.Size? = null - for (size in sizes) { - if (size.width <= width && size.height <= height) { - if (result == null) { - result = size - } else { - val resultArea = result.width * result.height - val newArea = size.width * size.height - - if (newArea > resultArea) { - result = size - } - } - } - } - - return result!! - } - - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - setMeasuredDimension(mScreenSize.x, mScreenSize.y) - - if (mSupportedPreviewSizes != null) { - // for simplicity lets assume that most displays are 16:9 and the remaining ones are 4:3 - // always set 16:9 for videos as many devices support 4:3 only in low quality - mPreviewSize = if (mIsSixteenToNine || mIsInVideoMode) { - getOptimalPreviewSize(mSupportedPreviewSizes!!, mScreenSize.y, mScreenSize.x) - } else { - val newRatioHeight = (mScreenSize.x * (4.toDouble() / 3)).toInt() - setMeasuredDimension(mScreenSize.x, newRatioHeight) - getOptimalPreviewSize(mSupportedPreviewSizes!!, newRatioHeight, mScreenSize.x) - } - val lp = mSurfaceView.layoutParams - - // make sure to occupy whole width in every case - if (mScreenSize.x > mPreviewSize!!.height) { - val ratio = mScreenSize.x.toFloat() / mPreviewSize!!.height - lp.width = (mPreviewSize!!.height * ratio).toInt() - if (mIsSixteenToNine || mIsInVideoMode) { - lp.height = mScreenSize.y - } else { - lp.height = (mPreviewSize!!.width * ratio).toInt() - } - } else { - lp.width = mPreviewSize!!.height - lp.height = mPreviewSize!!.width - } - - if (mSetupPreviewAfterMeasure) { - if (mCamera != null) { - mSetupPreviewAfterMeasure = false - mCamera!!.stopPreview() - setupPreview() - } - } - } - } - - override fun setFlashlightState(state: Int) { - mFlashlightState = state - checkFlashlight() - } - - override fun toggleFlashlight() { - val newState = ++mFlashlightState % if (mIsInVideoMode) 2 else 3 - setFlashlightState(newState) - } - - override fun checkFlashlight() { - when (mFlashlightState) { - FLASH_OFF -> disableFlash() - FLASH_ON -> enableFlash() - FLASH_AUTO -> setAutoFlash() - } - mActivity?.updateFlashlightState(mFlashlightState) - } - - private fun disableFlash() { - mFlashlightState = FLASH_OFF - mParameters?.flashMode = Camera.Parameters.FLASH_MODE_OFF - updateCameraParameters() - } - - private fun enableFlash() { - mFlashlightState = FLASH_ON - mParameters?.flashMode = Camera.Parameters.FLASH_MODE_TORCH - updateCameraParameters() - } - - private fun setAutoFlash() { - mFlashlightState = FLASH_AUTO - mParameters?.flashMode = Camera.Parameters.FLASH_MODE_OFF - updateCameraParameters() - - Handler().postDelayed({ - mActivity?.runOnUiThread { - mParameters?.flashMode = Camera.Parameters.FLASH_MODE_AUTO - } - }, 1000) - } - - override fun initPhotoMode() { - stopRecording() - cleanupRecorder() - mIsRecording = false - mIsInVideoMode = false - refreshPreview() - } - - // VIDEO RECORDING - override fun initVideoMode(): Boolean { - if (mCamera == null || mRecorder != null || !mIsSurfaceCreated) { - return false - } - - refreshPreview() - mSwitchToVideoAsap = false - - mIsRecording = false - mIsInVideoMode = true - mRecorder = MediaRecorder().apply { - setCamera(mCamera) - setVideoSource(MediaRecorder.VideoSource.DEFAULT) - setAudioSource(MediaRecorder.AudioSource.DEFAULT) - } - - mCurrVideoPath = mActivity!!.getOutputMediaFile(false) - if (mCurrVideoPath.isEmpty()) { - mActivity?.toast(R.string.video_creating_error) - return false - } - - if (mRecorder == null) { - mActivity?.toast(R.string.unknown_error_occurred) - return false - } - - val resolution = getSelectedResolution() - val profile = if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH)) { - CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH) - } else { - CamcorderProfile.get(CamcorderProfile.QUALITY_LOW) - } - - if (profile == null) { - mActivity?.toast(R.string.unknown_error_occurred) - return false - } - - profile.apply { - videoFrameWidth = resolution.width - videoFrameHeight = resolution.height - mRecorder!!.setProfile(this) - } - - checkPermissions() - if (mRecorder == null) { - return false - } - mRecorder!!.setPreviewDisplay(mSurfaceHolder.surface) - - val rotation = getVideoRotation() - mRecorder!!.setOrientationHint(rotation) - - try { - mRecorder!!.prepare() - } catch (e: Exception) { - setupFailed(e) - return false - } - - return true - } - - private fun checkPermissions(): Boolean { - if (mActivity!!.needsStupidWritePermissions(mCurrVideoPath)) { - if (mConfig.treeUri.isEmpty()) { - mActivity!!.toast(R.string.save_error_internal_storage) - mConfig.savePhotosFolder = Environment.getExternalStorageDirectory().toString() - releaseCamera() - return false - } - - try { - var document = mActivity!!.getDocumentFile(mCurrVideoPath.getParentPath()) - if (document == null) { - mActivity!!.toast(R.string.unknown_error_occurred) - return false - } - - document = document.createFile("video/mp4", mCurrVideoPath.substring(mCurrVideoPath.lastIndexOf('/') + 1)) - val fileDescriptor = context.contentResolver.openFileDescriptor(document.uri, "rw") - mRecorder!!.setOutputFile(fileDescriptor!!.fileDescriptor) - } catch (e: Exception) { - setupFailed(e) - } - } else { - mRecorder!!.setOutputFile(mCurrVideoPath) - } - return true - } - - private fun setupFailed(e: Exception) { - mActivity!!.showErrorToast(e) - releaseCamera() - } - - private fun updateCameraParameters() { - try { - mCamera?.parameters = mParameters - } catch (e: RuntimeException) { - } - } - - override fun setTargetUri(uri: Uri) { - mTargetUri = uri - } - - override fun setIsImageCaptureIntent(isImageCaptureIntent: Boolean) { - mIsImageCaptureIntent = isImageCaptureIntent - } - - override fun toggleRecording() { - if (mIsRecording) { - stopRecording() - initVideoMode() - } else { - startRecording() - } - } - - private fun getVideoRotation(): Int { - val deviceRot = compensateDeviceRotation(mActivity!!.mLastHandledOrientation, getIsUsingFrontCamera()) - val previewRot = getPreviewRotation(mCurrCameraId) - return (deviceRot + previewRot) % 360 - } - - override fun deviceOrientationChanged() { - if (mIsInVideoMode && !mIsRecording) { - mRecorder = null - initVideoMode() - } - } - - private fun startRecording() { - try { - mCamera!!.unlock() - toggleShutterSound(true) - mRecorder!!.start() - toggleShutterSound(false) - mIsRecording = true - mActivity!!.setRecordingState(true) - } catch (e: Exception) { - mActivity!!.showErrorToast(e) - releaseCamera() - } - } - - private fun stopRecording() { - if (mRecorder != null && mIsRecording) { - try { - toggleShutterSound(true) - mRecorder!!.stop() - mActivity!!.rescanPaths(arrayListOf(mCurrVideoPath)) { - mActivity!!.videoSaved(Uri.fromFile(File(mCurrVideoPath))) - toggleShutterSound(false) - } - } catch (e: RuntimeException) { - mActivity!!.showErrorToast(e) - toggleShutterSound(false) - File(mCurrVideoPath).delete() - mRecorder = null - mIsRecording = false - releaseCamera() - } - } - - mRecorder = null - if (mIsRecording) { - mActivity!!.setRecordingState(false) - } - mIsRecording = false - - val file = File(mCurrVideoPath) - if (file.exists() && file.length() == 0L) { - file.delete() - } - } - - private fun toggleShutterSound(mute: Boolean?) { - if (!mConfig.isSoundEnabled) { - (mActivity!!.getSystemService(Context.AUDIO_SERVICE) as AudioManager).setStreamMute(AudioManager.STREAM_SYSTEM, mute!!) - } - } - - private fun hasFlash(camera: Camera?): Boolean { - if (camera == null) { - return false - } - - if (camera.parameters.flashMode == null) { - return false - } - - val supportedFlashModes = camera.parameters.supportedFlashModes - if (supportedFlashModes == null || supportedFlashModes.isEmpty() || - supportedFlashModes.size == 1 && supportedFlashModes[0] == Camera.Parameters.FLASH_MODE_OFF) { - return false - } - - return true - } - - private fun getScreenSize(): Point { - val display = mActivity!!.windowManager.defaultDisplay - val size = Point() - display.getSize(size) - size.y += mActivity!!.resources.getNavBarHeight() - return size - } - - private fun getPreviewRotation(cameraId: Int): Int { - val info = getCameraInfo(cameraId) - val degrees = when (mActivity!!.windowManager.defaultDisplay.rotation) { - Surface.ROTATION_90 -> 90 - Surface.ROTATION_180 -> 180 - Surface.ROTATION_270 -> 270 - else -> 0 - } - - var result: Int - if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { - result = (info.orientation + degrees) % 360 - result = 360 - result - } else { - result = info.orientation - degrees + 360 - } - - return result % 360 - } - - private fun getCameraInfo(cameraId: Int): Camera.CameraInfo { - val info = android.hardware.Camera.CameraInfo() - Camera.getCameraInfo(cameraId, info) - return info - } -} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 364f4b05..245f504e 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,12 +6,6 @@ android:layout_height="match_parent" android:background="@android:color/black"> - - @@ -38,8 +32,8 @@ android:id="@+id/change_resolution" android:layout_width="@dimen/icon_size" android:layout_height="@dimen/icon_size" - android:layout_alignParentRight="true" android:layout_below="@+id/toggle_photo_video" + android:layout_alignParentRight="true" android:padding="@dimen/normal_margin" android:src="@drawable/ic_resolution"/> @@ -47,8 +41,8 @@ android:id="@+id/last_photo_video_preview" android:layout_width="@dimen/icon_size" android:layout_height="@dimen/icon_size" - android:layout_alignParentRight="true" android:layout_below="@+id/change_resolution" + android:layout_alignParentRight="true" android:padding="@dimen/medium_margin"/> + android:paddingBottom="@dimen/activity_margin"> @@ -40,18 +40,18 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -62,10 +62,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -86,10 +86,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -110,10 +110,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -135,10 +135,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -164,8 +164,8 @@ android:id="@+id/shutter_label" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/bigger_margin" android:layout_marginStart="@dimen/bigger_margin" + android:layout_marginLeft="@dimen/bigger_margin" android:layout_marginTop="@dimen/activity_margin" android:text="@string/shutter" android:textAllCaps="true" @@ -177,10 +177,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -201,10 +201,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -230,8 +230,8 @@ android:id="@+id/startup_label" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/bigger_margin" android:layout_marginStart="@dimen/bigger_margin" + android:layout_marginLeft="@dimen/bigger_margin" android:layout_marginTop="@dimen/activity_margin" android:text="@string/startup" android:textAllCaps="true" @@ -243,10 +243,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -267,10 +267,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> @@ -296,8 +296,8 @@ android:id="@+id/saving_label" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/bigger_margin" android:layout_marginStart="@dimen/bigger_margin" + android:layout_marginLeft="@dimen/bigger_margin" android:layout_marginTop="@dimen/activity_margin" android:text="@string/saving_label" android:textAllCaps="true" @@ -309,10 +309,10 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/activity_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/activity_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/activity_margin"> + android:paddingBottom="@dimen/activity_margin"> - - - - - - + android:paddingBottom="@dimen/activity_margin"> @@ -381,18 +357,18 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/bigger_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/bigger_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/bigger_margin"> + android:paddingBottom="@dimen/bigger_margin"> @@ -416,18 +392,18 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingBottom="@dimen/bigger_margin" android:paddingLeft="@dimen/normal_margin" + android:paddingTop="@dimen/bigger_margin" android:paddingRight="@dimen/normal_margin" - android:paddingTop="@dimen/bigger_margin"> + android:paddingBottom="@dimen/bigger_margin"> diff --git a/app/src/main/res/layout/dialog_change_resolution.xml b/app/src/main/res/layout/dialog_change_resolution.xml index fa327814..aa726cd1 100644 --- a/app/src/main/res/layout/dialog_change_resolution.xml +++ b/app/src/main/res/layout/dialog_change_resolution.xml @@ -19,8 +19,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_toLeftOf="@+id/change_resolution_photo" android:layout_toStartOf="@+id/change_resolution_photo" + android:layout_toLeftOf="@+id/change_resolution_photo" android:text="@string/photo"/> - - - - - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index b2bea78a..b04b82ae 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -3,10 +3,9 @@ -