diff --git a/app/src/main/java/com/simplemobiletools/flashlight/MyCameraImpl.java b/app/src/main/java/com/simplemobiletools/flashlight/MyCameraImpl.java index 1b9dc9b..f05f335 100644 --- a/app/src/main/java/com/simplemobiletools/flashlight/MyCameraImpl.java +++ b/app/src/main/java/com/simplemobiletools/flashlight/MyCameraImpl.java @@ -2,6 +2,7 @@ package com.simplemobiletools.flashlight; import android.content.Context; import android.hardware.Camera; +import android.os.Handler; import android.util.Log; import com.squareup.otto.Bus; @@ -13,9 +14,12 @@ public class MyCameraImpl { private static Bus mBus; private Context mContext; private MarshmallowCamera mMarshmallowCamera; + private volatile boolean mShouldStroboscopeStop; + private volatile boolean mIsStroboscopeRunning; private static boolean mIsFlashlightOn; private static boolean mIsMarshmallow; + private static boolean mShouldEnableFlashlight; public MyCameraImpl(Context cxt) { mContext = cxt; @@ -35,6 +39,31 @@ public class MyCameraImpl { handleCameraSetup(); } + public boolean toggleStroboscope() { + if (!mIsStroboscopeRunning) + disableFlashlight(); + + if (mCamera == null) { + initCamera(); + } + + if (mCamera == null) { + Utils.showToast(mContext, R.string.camera_error); + return false; + } + + if (mIsStroboscopeRunning) { + stopStroboscope(); + } else { + new Thread(stroboscope).start(); + } + return true; + } + + private void stopStroboscope() { + mShouldStroboscopeStop = true; + } + public void handleCameraSetup() { if (mIsMarshmallow) { setupMarshmallowCamera(); @@ -55,15 +84,19 @@ public class MyCameraImpl { return; if (mCamera == null) { - try { - mCamera = Camera.open(); - mParams = mCamera.getParameters(); - mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); - mCamera.setParameters(mParams); - } catch (Exception e) { - Log.e(TAG, "setup mCamera " + e.getMessage()); - mBus.post(new Events.CameraUnavailable()); - } + initCamera(); + } + } + + private void initCamera() { + try { + mCamera = Camera.open(); + mParams = mCamera.getParameters(); + mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); + mCamera.setParameters(mParams); + } catch (Exception e) { + Log.e(TAG, "setup mCamera " + e.getMessage()); + mBus.post(new Events.CameraUnavailable()); } } @@ -76,6 +109,12 @@ public class MyCameraImpl { } public void enableFlashlight() { + mShouldStroboscopeStop = true; + if (mIsStroboscopeRunning) { + mShouldEnableFlashlight = true; + return; + } + mIsFlashlightOn = true; if (mIsMarshmallow) { toggleMarshmallowFlashlight(true); @@ -88,12 +127,19 @@ public class MyCameraImpl { mCamera.setParameters(mParams); mCamera.startPreview(); } - mBus.post(new Events.StateChanged(true)); + + Runnable mainRunnable = new Runnable() { + @Override + public void run() { + mBus.post(new Events.StateChanged(true)); + } + }; + new Handler(mContext.getMainLooper()).post(mainRunnable); } private void disableFlashlight() { mIsFlashlightOn = false; - if (isMarshmallow()) { + if (mIsMarshmallow) { toggleMarshmallowFlashlight(false); } else { if (mCamera == null || mParams == null) { @@ -129,4 +175,51 @@ public class MyCameraImpl { private boolean isMarshmallow() { return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M; } + + private Runnable stroboscope = new Runnable() { + @Override + public void run() { + if (mIsStroboscopeRunning) { + return; + } + + mShouldStroboscopeStop = false; + mIsStroboscopeRunning = true; + + if (mCamera == null) { + initCamera(); + } + + Camera.Parameters torchOn = mCamera.getParameters(); + Camera.Parameters torchOff = mCamera.getParameters(); + torchOn.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); + torchOff.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); + + while (!mShouldStroboscopeStop) { + try { + mCamera.setParameters(torchOn); + Thread.sleep(500); + mCamera.setParameters(torchOff); + Thread.sleep(500); + } catch (InterruptedException ignored) { + mShouldStroboscopeStop = true; + } catch (RuntimeException ignored) { + mShouldStroboscopeStop = true; + } + } + + if (mCamera != null) { + mCamera.setParameters(torchOff); + mCamera.release(); + mCamera = null; + } + mIsStroboscopeRunning = false; + mShouldStroboscopeStop = false; + + if (mShouldEnableFlashlight) { + enableFlashlight(); + mShouldEnableFlashlight = false; + } + } + }; } diff --git a/app/src/main/java/com/simplemobiletools/flashlight/activities/MainActivity.java b/app/src/main/java/com/simplemobiletools/flashlight/activities/MainActivity.java index eb587f9..ef1b42b 100644 --- a/app/src/main/java/com/simplemobiletools/flashlight/activities/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/flashlight/activities/MainActivity.java @@ -1,8 +1,12 @@ package com.simplemobiletools.flashlight.activities; +import android.Manifest; import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.PorterDuff; import android.os.Bundle; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -24,6 +28,8 @@ import butterknife.ButterKnife; import butterknife.OnClick; public class MainActivity extends SimpleActivity { + private static final int CAMERA_PERMISSION = 1; + @BindView(R.id.toggle_btn) ImageView mToggleBtn; @BindView(R.id.bright_display_btn) ImageView mBrightDisplayBtn; @BindView(R.id.stroboscope_btn) ImageView mStroboscopeBtn; @@ -70,6 +76,7 @@ public class MainActivity extends SimpleActivity { @OnClick(R.id.toggle_btn) public void toggleFlashlight() { + mStroboscopeBar.setVisibility(View.INVISIBLE); mCameraImpl.toggleFlashlight(); } @@ -79,8 +86,33 @@ public class MainActivity extends SimpleActivity { } @OnClick(R.id.stroboscope_btn) - public void launchStroboscope() { + public void tryToggleStroboscope() { + toggleStroboscope(); + } + private void toggleStroboscope() { + // use the old Camera API for stroboscope, the new Camera Manager is way too slow + if (isCameraPermissionGranted()) { + if (mCameraImpl.toggleStroboscope()) { + mStroboscopeBar.setVisibility(mStroboscopeBar.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE); + } + } else { + final String[] permissions = {Manifest.permission.CAMERA}; + ActivityCompat.requestPermissions(this, permissions, CAMERA_PERMISSION); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if (requestCode == CAMERA_PERMISSION) { + if (isCameraPermissionGranted()) { + toggleStroboscope(); + } else { + Utils.showToast(getApplicationContext(), R.string.camera_permission); + } + } } @Override @@ -123,6 +155,10 @@ public class MainActivity extends SimpleActivity { } } + private boolean isCameraPermissionGranted() { + return ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; + } + @Subscribe public void stateChangedEvent(Events.StateChanged event) { if (event.getIsEnabled()) { diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e370b8b..82f693f 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -3,6 +3,7 @@ Flashlight Beanspruchen der Kamera fehlgeschlagen OK + Camera permission is necessary for proper stroboscope effect Einstellungen diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 1afc280..0bcbe87 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -3,6 +3,7 @@ Flashlight Rilevamento fotocamera fallito OK + Camera permission is necessary for proper stroboscope effect Impostazioni diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 1377d96..aa4e2f0 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -3,6 +3,7 @@ Flashlight カメラの取得に失敗しました OK + Camera permission is necessary for proper stroboscope effect 設定 diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 8b2bd3a..7ff0201 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -3,6 +3,7 @@ Flashlight Det gick inte att komma åt kameran OK + Camera permission is necessary for proper stroboscope effect Inställningar diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 29e6768..b869157 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,6 +3,7 @@ Flashlight Obtaining the camera failed OK + Camera permission is necessary for proper stroboscope effect Settings