couple more updates of the Preview class

This commit is contained in:
tibbi 2017-03-19 21:36:45 +01:00
parent 1095ed56e5
commit 0cfebacd01
2 changed files with 67 additions and 86 deletions

View File

@ -12,16 +12,21 @@ import android.net.Uri
import android.os.Environment import android.os.Environment
import android.os.Handler import android.os.Handler
import android.util.Log import android.util.Log
import android.view.* import android.view.ScaleGestureDetector
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.ViewGroup
import com.simplemobiletools.camera.activities.MainActivity import com.simplemobiletools.camera.activities.MainActivity
import com.simplemobiletools.commons.extensions.scanPaths import com.simplemobiletools.camera.extensions.config
import com.simplemobiletools.commons.extensions.needsStupidWritePermissions
import com.simplemobiletools.commons.extensions.scanPath
import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.commons.extensions.toast
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.io.Serializable import java.io.Serializable
import java.util.* import java.util.*
class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.OnClickListener, MediaScannerConnection.OnScanCompletedListener { class Preview : ViewGroup, SurfaceHolder.Callback, MediaScannerConnection.OnScanCompletedListener {
companion object { companion object {
val PHOTO_PREVIEW_LENGTH = 1000 val PHOTO_PREVIEW_LENGTH = 1000
private val TAG = Preview::class.java.simpleName private val TAG = Preview::class.java.simpleName
@ -32,31 +37,31 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
lateinit var mActivity: MainActivity lateinit var mActivity: MainActivity
lateinit var mCallback: PreviewListener lateinit var mCallback: PreviewListener
lateinit var mScreenSize: Point lateinit var mScreenSize: Point
lateinit var config: Config
private var mCamera: Camera? = null private var mCamera: Camera? = null
private var mSupportedPreviewSizes: List<Camera.Size>? = null private var mSupportedPreviewSizes: List<Camera.Size>? = null
private var mPreviewSize: Camera.Size? = null private var mPreviewSize: Camera.Size? = null
private var mParameters: Camera.Parameters? = null private var mParameters: Camera.Parameters? = null
private var mRecorder: MediaRecorder? = null private var mRecorder: MediaRecorder? = null
private var mCurrVideoPath: String? = null
private var mTargetUri: Uri? = null private var mTargetUri: Uri? = null
private var mScaleGestureDetector: ScaleGestureDetector? = null private var mScaleGestureDetector: ScaleGestureDetector? = null
private var mZoomRatios: List<Int>? = null private var mZoomRatios: List<Int>? = null
private var mConfig: Config? = null
private var mCanTakePicture: Boolean = false private var mCurrVideoPath = ""
private var mIsFlashEnabled: Boolean = false private var mCanTakePicture = false
private var mIsRecording: Boolean = false private var mIsFlashEnabled = false
private var mIsVideoMode: Boolean = false private var mIsRecording = false
private var mIsSurfaceCreated: Boolean = false private var mIsVideoMode = false
private var mSwitchToVideoAsap: Boolean = false private var mIsSurfaceCreated = false
private var mSetupPreviewAfterMeasure: Boolean = false private var mSwitchToVideoAsap = false
private val mForceAspectRatio: Boolean = false private var mSetupPreviewAfterMeasure = false
private var mWasZooming: Boolean = false private val mForceAspectRatio = false
private var mLastClickX: Int = 0 private var mWasZooming = false
private var mLastClickY: Int = 0 private var mLastClickX = 0
private var mInitVideoRotation: Int = 0 private var mLastClickY = 0
private var mCurrCameraId: Int = 0 private var mInitVideoRotation = 0
private var mMaxZoom: Int = 0 private var mCurrCameraId = 0
private var mMaxZoom = 0
} }
constructor(context: Context) : super(context) constructor(context: Context) : super(context)
@ -69,15 +74,31 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
mSurfaceHolder.addCallback(this) mSurfaceHolder.addCallback(this)
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
mCanTakePicture = false mCanTakePicture = false
mSurfaceView.setOnTouchListener(this)
mSurfaceView.setOnClickListener(this)
mIsFlashEnabled = false mIsFlashEnabled = false
mIsVideoMode = false mIsVideoMode = false
mIsSurfaceCreated = false mIsSurfaceCreated = false
mSetupPreviewAfterMeasure = false mSetupPreviewAfterMeasure = false
mCurrVideoPath = "" mCurrVideoPath = ""
mScreenSize = Utils.getScreenSize(mActivity) config = activity.config
mScreenSize = Utils.getScreenSize(activity)
initGestureDetector() initGestureDetector()
mSurfaceView.setOnTouchListener { view, event ->
mLastClickX = event.x.toInt()
mLastClickY = event.y.toInt()
if (mMaxZoom > 0)
mScaleGestureDetector!!.onTouchEvent(event)
false
}
mSurfaceView.setOnClickListener {
if (!mWasZooming)
focusArea(false)
mWasZooming = false
mSurfaceView.isSoundEffectsEnabled = true
}
} }
fun trySwitchToVideo() { fun trySwitchToVideo() {
@ -95,7 +116,7 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
newCamera = Camera.open(cameraId) newCamera = Camera.open(cameraId)
mCallback.setIsCameraAvailable(true) mCallback.setIsCameraAvailable(true)
} catch (e: Exception) { } catch (e: Exception) {
Utils.showToast(mActivity, R.string.camera_open_error) mActivity.toast(R.string.camera_open_error)
Log.e(TAG, "setCamera open " + e.message) Log.e(TAG, "setCamera open " + e.message)
mCallback.setIsCameraAvailable(false) mCallback.setIsCameraAvailable(false)
return false return false
@ -132,7 +153,6 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
Log.e(TAG, "setCamera setPreviewDisplay " + e.message) Log.e(TAG, "setCamera setPreviewDisplay " + e.message)
return false return false
} }
} }
mCallback.setFlashAvailable(Utils.hasFlash(mCamera)) mCallback.setFlashAvailable(Utils.hasFlash(mCamera))
@ -207,7 +227,7 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
mParameters.setPictureSize(maxSize.width, maxSize.height);*/ mParameters.setPictureSize(maxSize.width, maxSize.height);*/
mParameters!!.setRotation(rotation % 360) mParameters!!.setRotation(rotation % 360)
if (mConfig!!.isSoundEnabled) { if (config.isSoundEnabled) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val volume = audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM) val volume = audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM)
if (volume != 0) { if (volume != 0) {
@ -227,7 +247,7 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
} }
private val takePictureCallback = Camera.PictureCallback { data, cam -> private val takePictureCallback = Camera.PictureCallback { data, cam ->
if (mConfig!!.isShowPreviewEnabled) { if (config.isShowPreviewEnabled) {
Handler().postDelayed({ resumePreview() }, PHOTO_PREVIEW_LENGTH.toLong()) Handler().postDelayed({ resumePreview() }, PHOTO_PREVIEW_LENGTH.toLong())
} else { } else {
resumePreview() resumePreview()
@ -237,19 +257,15 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
} }
private fun resumePreview() { private fun resumePreview() {
if (mCamera != null) { mCamera?.startPreview()
mCamera!!.startPreview()
}
mCanTakePicture = true mCanTakePicture = true
} }
val supportedVideoSizes: List<Camera.Size> fun getSupportedVideoSizes(): List<Camera.Size> {
get() { return if (mParameters!!.supportedVideoSizes != null) {
if (mParameters!!.supportedVideoSizes != null) { mParameters!!.supportedVideoSizes
return mParameters!!.supportedVideoSizes
} else { } else {
return mParameters!!.supportedPreviewSizes mParameters!!.supportedPreviewSizes
} }
} }
@ -297,22 +313,16 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
fun releaseCamera() { fun releaseCamera() {
stopRecording() stopRecording()
mCamera?.stopPreview()
if (mCamera != null) { mCamera?.release()
mCamera!!.stopPreview()
mCamera!!.release()
mCamera = null mCamera = null
}
cleanupRecorder() cleanupRecorder()
} }
override fun surfaceCreated(holder: SurfaceHolder) { override fun surfaceCreated(holder: SurfaceHolder) {
mIsSurfaceCreated = true mIsSurfaceCreated = true
try { try {
if (mCamera != null) { mCamera?.setPreviewDisplay(mSurfaceHolder)
mCamera!!.setPreviewDisplay(mSurfaceHolder)
}
if (mSwitchToVideoAsap) if (mSwitchToVideoAsap)
initRecorder() initRecorder()
@ -332,10 +342,7 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
override fun surfaceDestroyed(holder: SurfaceHolder) { override fun surfaceDestroyed(holder: SurfaceHolder) {
mIsSurfaceCreated = false mIsSurfaceCreated = false
if (mCamera != null) { mCamera?.stopPreview()
mCamera!!.stopPreview()
}
cleanupRecorder() cleanupRecorder()
} }
@ -414,23 +421,12 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
if (mSetupPreviewAfterMeasure) { if (mSetupPreviewAfterMeasure) {
mSetupPreviewAfterMeasure = false mSetupPreviewAfterMeasure = false
if (mCamera != null) mCamera?.stopPreview()
mCamera!!.stopPreview()
setupPreview() setupPreview()
} }
} }
} }
override fun onTouch(v: View, event: MotionEvent): Boolean {
mLastClickX = event.x.toInt()
mLastClickY = event.y.toInt()
if (mMaxZoom > 0)
mScaleGestureDetector!!.onTouchEvent(event)
return false
}
fun enableFlash() { fun enableFlash() {
mParameters!!.flashMode = Camera.Parameters.FLASH_MODE_TORCH mParameters!!.flashMode = Camera.Parameters.FLASH_MODE_TORCH
mCamera!!.parameters = mParameters mCamera!!.parameters = mParameters
@ -481,7 +477,7 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
mRecorder!!.setAudioSource(MediaRecorder.AudioSource.DEFAULT) mRecorder!!.setAudioSource(MediaRecorder.AudioSource.DEFAULT)
mCurrVideoPath = Utils.getOutputMediaFile(mActivity, false) mCurrVideoPath = Utils.getOutputMediaFile(mActivity, false)
if (mCurrVideoPath!!.isEmpty()) { if (mCurrVideoPath.isEmpty()) {
mActivity.toast(R.string.video_creating_error) mActivity.toast(R.string.video_creating_error)
return false return false
} }
@ -492,10 +488,10 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
cpHigh.videoFrameHeight = videoSize.height; cpHigh.videoFrameHeight = videoSize.height;
mRecorder.setProfile(cpHigh);*/ mRecorder.setProfile(cpHigh);*/
if (Utils.needsStupidWritePermissions(context, mCurrVideoPath!!)) { if (mActivity.needsStupidWritePermissions(mCurrVideoPath)) {
if (mConfig!!.treeUri.isEmpty()) { if (config.treeUri.isEmpty()) {
mActivity.toast(R.string.save_error_internal_storage) mActivity.toast(R.string.save_error_internal_storage)
mConfig!!.savePhotosFolder = Environment.getExternalStorageDirectory().toString() config.savePhotosFolder = Environment.getExternalStorageDirectory().toString()
releaseCamera() releaseCamera()
return false return false
} }
@ -569,11 +565,10 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
try { try {
toggleShutterSound(true) toggleShutterSound(true)
mRecorder!!.stop() mRecorder!!.stop()
val paths = arrayListOf<String>(mCurrVideoPath!!) mActivity.scanPath(mCurrVideoPath) {}
mActivity.scanPaths(paths) {}
} catch (e: RuntimeException) { } catch (e: RuntimeException) {
toggleShutterSound(false) toggleShutterSound(false)
File(mCurrVideoPath!!).delete() File(mCurrVideoPath).delete()
mActivity.toast(R.string.video_saving_error) mActivity.toast(R.string.video_saving_error)
Log.e(TAG, "stopRecording " + e.message) Log.e(TAG, "stopRecording " + e.message)
mRecorder = null mRecorder = null
@ -586,26 +581,18 @@ class Preview : ViewGroup, SurfaceHolder.Callback, View.OnTouchListener, View.On
mRecorder = null mRecorder = null
mIsRecording = false mIsRecording = false
val file = File(mCurrVideoPath!!) val file = File(mCurrVideoPath)
if (file.exists() && file.length() == 0L) { if (file.exists() && file.length() == 0L) {
file.delete() file.delete()
} }
} }
private fun toggleShutterSound(mute: Boolean?) { private fun toggleShutterSound(mute: Boolean?) {
if (!mConfig!!.isSoundEnabled) { if (!config.isSoundEnabled) {
(mActivity.getSystemService(Context.AUDIO_SERVICE) as AudioManager).setStreamMute(AudioManager.STREAM_SYSTEM, mute!!) (mActivity.getSystemService(Context.AUDIO_SERVICE) as AudioManager).setStreamMute(AudioManager.STREAM_SYSTEM, mute!!)
} }
} }
override fun onClick(v: View) {
if (!mWasZooming)
focusArea(false)
mWasZooming = false
mSurfaceView.isSoundEffectsEnabled = true
}
override fun onScanCompleted(path: String, uri: Uri) { override fun onScanCompleted(path: String, uri: Uri) {
mCallback.videoSaved(uri) mCallback.videoSaved(uri)
toggleShutterSound(false) toggleShutterSound(false)

View File

@ -9,8 +9,6 @@ import android.graphics.Point
import android.hardware.Camera import android.hardware.Camera
import android.support.v4.content.ContextCompat import android.support.v4.content.ContextCompat
import android.view.Surface import android.view.Surface
import com.simplemobiletools.commons.extensions.getFileDocument
import com.simplemobiletools.commons.extensions.needsStupidWritePermissions
import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.commons.extensions.toast
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -102,10 +100,6 @@ class Utils {
fun hasAudioPermission(cxt: Context) = ContextCompat.checkSelfPermission(cxt, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED fun hasAudioPermission(cxt: Context) = ContextCompat.checkSelfPermission(cxt, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
fun needsStupidWritePermissions(context: Context, path: String) = context.needsStupidWritePermissions(path)
fun getFileDocument(context: Context, path: String, treeUri: String) = context.getFileDocument(path, treeUri)
fun getRotationDegrees(activity: Activity): Int { fun getRotationDegrees(activity: Activity): Int {
return when (activity.windowManager.defaultDisplay.rotation) { return when (activity.windowManager.defaultDisplay.rotation) {
Surface.ROTATION_0 -> 0 Surface.ROTATION_0 -> 0