use Otto for dispatching events instead of an interface

This commit is contained in:
tibbi 2016-06-20 20:13:13 +02:00
parent a9a9fa9e37
commit f98a9eb496
12 changed files with 178 additions and 58 deletions

View File

@ -30,6 +30,7 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.jakewharton:butterknife:8.0.1' compile 'com.jakewharton:butterknife:8.0.1'
compile 'com.squareup:otto:1.3.8'
apt 'com.jakewharton:butterknife-compiler:8.0.1' apt 'com.jakewharton:butterknife-compiler:8.0.1'
} }

View File

@ -15,3 +15,9 @@
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *; # public *;
#} #}
# Otto
-keepattributes *Annotation*
-keepclassmembers class ** {
@com.squareup.otto.Subscribe public *;
@com.squareup.otto.Produce public *;
}

View File

@ -0,0 +1,11 @@
package com.simplemobiletools.flashlight;
import com.squareup.otto.Bus;
public class BusProvider {
private static final Bus BUS = new Bus();
public static Bus getInstance() {
return BUS;
}
}

View File

@ -0,0 +1,18 @@
package com.simplemobiletools.flashlight;
public class Events {
public static class StateChanged {
private static boolean mIsEnabled;
StateChanged(boolean isEnabled) {
mIsEnabled = isEnabled;
}
public boolean getIsEnabled() {
return mIsEnabled;
}
}
public static class CameraUnavailable {
}
}

View File

@ -7,26 +7,26 @@ import android.hardware.camera2.CameraManager;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
import com.squareup.otto.Bus;
public class MarshmallowCamera { public class MarshmallowCamera {
private static final String TAG = MyCameraImpl.class.getSimpleName(); private static final String TAG = MyCameraImpl.class.getSimpleName();
private MyCamera mCallback;
private Context mContext; private Context mContext;
public MarshmallowCamera(MyCamera camera, Context cxt) { public MarshmallowCamera(Context cxt) {
mCallback = camera;
mContext = cxt; mContext = cxt;
} }
@TargetApi(Build.VERSION_CODES.M) @TargetApi(Build.VERSION_CODES.M)
public void toggleMarshmallowFlashlight(boolean enable) { public void toggleMarshmallowFlashlight(final Bus bus, boolean enable) {
try { try {
final CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); final CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
final String[] list = manager.getCameraIdList(); final String[] list = manager.getCameraIdList();
manager.setTorchMode(list[0], enable); manager.setTorchMode(list[0], enable);
} catch (CameraAccessException e) { } catch (CameraAccessException e) {
Log.e(TAG, "toggle marshmallow flashlight " + e.getMessage()); Log.e(TAG, "toggle marshmallow flashlight " + e.getMessage());
mCallback.cameraUnavailable(); bus.post(new Events.CameraUnavailable());
} }
} }
} }

View File

@ -1,9 +0,0 @@
package com.simplemobiletools.flashlight;
public interface MyCamera {
void enableFlashlight();
void disableFlashlight();
void cameraUnavailable();
}

View File

@ -4,33 +4,35 @@ import android.content.Context;
import android.hardware.Camera; import android.hardware.Camera;
import android.util.Log; import android.util.Log;
import com.squareup.otto.Bus;
public class MyCameraImpl { public class MyCameraImpl {
private static final String TAG = MyCameraImpl.class.getSimpleName(); private static final String TAG = MyCameraImpl.class.getSimpleName();
private static Camera mCamera; private static Camera mCamera;
private static Camera.Parameters mParams; private static Camera.Parameters mParams;
private static MyCamera mCallback;
private static Context mContext; private static Context mContext;
private static MarshmallowCamera mMarshmallowCamera; private static MarshmallowCamera mMarshmallowCamera;
private static Bus mBus;
private static boolean mIsFlashlightOn; private static boolean mIsFlashlightOn;
private static boolean mIsMarshmallow; private static boolean mIsMarshmallow;
public MyCameraImpl(MyCamera camera, Context cxt) { public MyCameraImpl(Context cxt) {
mCallback = camera;
mContext = cxt; mContext = cxt;
mIsMarshmallow = isMarshmallow(); mIsMarshmallow = isMarshmallow();
if (mBus == null) {
mBus = BusProvider.getInstance();
mBus.register(this);
}
handleCameraSetup(); handleCameraSetup();
checkFlashlight();
} }
public void toggleFlashlight() { public void toggleFlashlight() {
handleCameraSetup();
mIsFlashlightOn = !mIsFlashlightOn; mIsFlashlightOn = !mIsFlashlightOn;
handleCameraSetup();
if (mIsFlashlightOn) {
enableFlashlight();
} else {
disableFlashlight();
}
} }
public void handleCameraSetup() { public void handleCameraSetup() {
@ -39,11 +41,12 @@ public class MyCameraImpl {
} else { } else {
setupCamera(); setupCamera();
} }
checkFlashlight();
} }
private void setupMarshmallowCamera() { private void setupMarshmallowCamera() {
if (mMarshmallowCamera == null) { if (mMarshmallowCamera == null) {
mMarshmallowCamera = new MarshmallowCamera(mCallback, mContext); mMarshmallowCamera = new MarshmallowCamera(mContext);
} }
} }
@ -57,17 +60,23 @@ public class MyCameraImpl {
mParams = mCamera.getParameters(); mParams = mCamera.getParameters();
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(mParams); mCamera.setParameters(mParams);
if (mIsFlashlightOn)
enableFlashlight();
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "setup mCamera " + e.getMessage()); Log.e(TAG, "setup mCamera " + e.getMessage());
mCallback.cameraUnavailable(); mBus.post(new Events.CameraUnavailable());
} }
} }
} }
private void enableFlashlight() { public void checkFlashlight() {
if (mIsFlashlightOn) {
enableFlashlight();
} else {
disableFlashlight();
}
}
public void enableFlashlight() {
mIsFlashlightOn = true;
if (mIsMarshmallow) { if (mIsMarshmallow) {
toggleMarshmallowFlashlight(true); toggleMarshmallowFlashlight(true);
} else { } else {
@ -78,10 +87,11 @@ public class MyCameraImpl {
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(mParams); mCamera.setParameters(mParams);
} }
mCallback.enableFlashlight(); mBus.post(new Events.StateChanged(true));
} }
private void disableFlashlight() { private void disableFlashlight() {
mIsFlashlightOn = false;
if (isMarshmallow()) { if (isMarshmallow()) {
toggleMarshmallowFlashlight(false); toggleMarshmallowFlashlight(false);
} else { } else {
@ -92,18 +102,27 @@ public class MyCameraImpl {
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(mParams); mCamera.setParameters(mParams);
} }
mCallback.disableFlashlight(); mBus.post(new Events.StateChanged(false));
} }
private void toggleMarshmallowFlashlight(boolean enable) { private void toggleMarshmallowFlashlight(boolean enable) {
mMarshmallowCamera.toggleMarshmallowFlashlight(enable); mMarshmallowCamera.toggleMarshmallowFlashlight(mBus, enable);
} }
public void releaseCamera() { public void releaseCamera() {
if (mIsFlashlightOn) {
disableFlashlight();
}
if (mCamera != null) { if (mCamera != null) {
mCamera.release(); mCamera.release();
mCamera = null; mCamera = null;
} }
if (mBus != null) {
mBus.unregister(this);
}
mIsFlashlightOn = false;
} }
private boolean isMarshmallow() { private boolean isMarshmallow() {

View File

@ -10,12 +10,17 @@ import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.widget.RemoteViews; import android.widget.RemoteViews;
public class MyWidgetProvider extends AppWidgetProvider implements MyCamera { import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
public class MyWidgetProvider extends AppWidgetProvider {
private static final String TOGGLE = "toggle"; private static final String TOGGLE = "toggle";
private static MyCameraImpl mCameraImpl; private static MyCameraImpl mCameraImpl;
private static RemoteViews mRemoteViews; private static RemoteViews mRemoteViews;
private static AppWidgetManager mWidgetManager; private static AppWidgetManager mWidgetManager;
private static Bitmap mColoredBmp; private static Bitmap mColoredBmp;
private static Bus mBus;
private static Context mContext;
private static int[] mWidgetIds; private static int[] mWidgetIds;
@ -26,6 +31,7 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
} }
private void initVariables(Context context) { private void initVariables(Context context) {
mContext = context;
final ComponentName component = new ComponentName(context, MyWidgetProvider.class); final ComponentName component = new ComponentName(context, MyWidgetProvider.class);
mWidgetManager = AppWidgetManager.getInstance(context); mWidgetManager = AppWidgetManager.getInstance(context);
mWidgetIds = mWidgetManager.getAppWidgetIds(component); mWidgetIds = mWidgetManager.getAppWidgetIds(component);
@ -36,18 +42,23 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.widget); mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
mRemoteViews.setOnClickPendingIntent(R.id.toggle_btn, pendingIntent); mRemoteViews.setOnClickPendingIntent(R.id.toggle_btn, pendingIntent);
mCameraImpl = new MyCameraImpl(this, context); mCameraImpl = new MyCameraImpl(context);
final Resources res = context.getResources(); final Resources res = context.getResources();
final int appColor = res.getColor(R.color.colorPrimary); final int appColor = res.getColor(R.color.colorPrimary);
mColoredBmp = Utils.getColoredIcon(context.getResources(), appColor, R.mipmap.flashlight_small); mColoredBmp = Utils.getColoredIcon(context.getResources(), appColor, R.mipmap.flashlight_small);
if (mBus == null) {
mBus = BusProvider.getInstance();
}
registerBus();
} }
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
final String action = intent.getAction(); final String action = intent.getAction();
if (action.equals(TOGGLE)) { if (action.equals(TOGGLE)) {
if (mCameraImpl == null) { if (mCameraImpl == null || mBus == null) {
initVariables(context); initVariables(context);
} }
@ -56,7 +67,6 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
super.onReceive(context, intent); super.onReceive(context, intent);
} }
@Override
public void enableFlashlight() { public void enableFlashlight() {
mRemoteViews.setImageViewBitmap(R.id.toggle_btn, mColoredBmp); mRemoteViews.setImageViewBitmap(R.id.toggle_btn, mColoredBmp);
for (int widgetId : mWidgetIds) { for (int widgetId : mWidgetIds) {
@ -64,22 +74,34 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
} }
} }
@Override
public void disableFlashlight() { public void disableFlashlight() {
mRemoteViews.setImageViewResource(R.id.toggle_btn, R.mipmap.flashlight_small); mRemoteViews.setImageViewResource(R.id.toggle_btn, R.mipmap.flashlight_small);
for (int widgetId : mWidgetIds) { for (int widgetId : mWidgetIds) {
mWidgetManager.updateAppWidget(widgetId, mRemoteViews); mWidgetManager.updateAppWidget(widgetId, mRemoteViews);
} }
mCameraImpl.releaseCamera();
} }
@Override @Subscribe
public void cameraUnavailable() { public void cameraUnavailable(Events.CameraUnavailable event) {
if (mContext != null) {
Utils.showToast(mContext, R.string.camera_error);
disableFlashlight();
}
}
@Subscribe
public void stateChangedEvent(Events.StateChanged event) {
if (event.getIsEnabled()) {
enableFlashlight();
} else {
disableFlashlight();
}
} }
@Override @Override
public void onDeleted(Context context, int[] appWidgetIds) { public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds); super.onDeleted(context, appWidgetIds);
unregisterBus();
releaseCamera(context); releaseCamera(context);
} }
@ -87,7 +109,20 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
if (mCameraImpl == null) if (mCameraImpl == null)
initVariables(context); initVariables(context);
disableFlashlight();
mCameraImpl.releaseCamera(); mCameraImpl.releaseCamera();
} }
private void registerBus() {
try {
mBus.register(this);
} catch (Exception ignored) {
}
}
private void unregisterBus() {
try {
mBus.unregister(this);
} catch (Exception ignored) {
}
}
} }

View File

@ -24,6 +24,11 @@ public class LicenseActivity extends AppCompatActivity {
openUrl(R.string.butterknife_url); openUrl(R.string.butterknife_url);
} }
@OnClick(R.id.license_otto_title)
public void ottoClicked() {
openUrl(R.string.otto_url);
}
private void openUrl(int id) { private void openUrl(int id) {
final String url = getResources().getString(id); final String url = getResources().getString(id);
final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));

View File

@ -9,18 +9,22 @@ import android.view.MenuItem;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.ImageView; import android.widget.ImageView;
import com.simplemobiletools.flashlight.MyCamera; import com.simplemobiletools.flashlight.BusProvider;
import com.simplemobiletools.flashlight.Events;
import com.simplemobiletools.flashlight.MyCameraImpl; import com.simplemobiletools.flashlight.MyCameraImpl;
import com.simplemobiletools.flashlight.R; import com.simplemobiletools.flashlight.R;
import com.simplemobiletools.flashlight.Utils; import com.simplemobiletools.flashlight.Utils;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
public class MainActivity extends AppCompatActivity implements MyCamera { public class MainActivity extends AppCompatActivity {
@BindView(R.id.toggle_btn) ImageView mToggleBtn; @BindView(R.id.toggle_btn) ImageView mToggleBtn;
private static Bus mBus;
private static MyCameraImpl mCameraImpl; private static MyCameraImpl mCameraImpl;
@Override @Override
@ -29,7 +33,7 @@ public class MainActivity extends AppCompatActivity implements MyCamera {
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
ButterKnife.bind(this); ButterKnife.bind(this);
setupCameraImpl(); mBus = BusProvider.getInstance();
} }
@Override @Override
@ -51,8 +55,8 @@ public class MainActivity extends AppCompatActivity implements MyCamera {
} }
private void setupCameraImpl() { private void setupCameraImpl() {
mCameraImpl = new MyCameraImpl(this, this); mCameraImpl = new MyCameraImpl(this);
mCameraImpl.toggleFlashlight(); mCameraImpl.enableFlashlight();
} }
@OnClick(R.id.toggle_btn) @OnClick(R.id.toggle_btn)
@ -63,28 +67,42 @@ public class MainActivity extends AppCompatActivity implements MyCamera {
@Override @Override
protected void onStart() { protected void onStart() {
super.onStart(); super.onStart();
mCameraImpl.handleCameraSetup(); mBus.register(this);
if (mCameraImpl == null) {
setupCameraImpl();
}
} }
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
mCameraImpl.handleCameraSetup(); mCameraImpl.handleCameraSetup();
} mCameraImpl.checkFlashlight();
@Override
protected void onPause() {
super.onPause();
mCameraImpl.releaseCamera();
} }
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
mCameraImpl.releaseCamera(); mBus.unregister(this);
} }
@Override @Override
protected void onDestroy() {
super.onDestroy();
mCameraImpl.releaseCamera();
mCameraImpl = null;
}
@Subscribe
public void stateChangedEvent(Events.StateChanged event) {
if (event.getIsEnabled()) {
enableFlashlight();
} else {
disableFlashlight();
}
}
public void enableFlashlight() { public void enableFlashlight() {
final int appColor = getResources().getColor(R.color.colorPrimary); final int appColor = getResources().getColor(R.color.colorPrimary);
mToggleBtn.setImageResource(R.mipmap.flashlight_big); mToggleBtn.setImageResource(R.mipmap.flashlight_big);
@ -92,14 +110,13 @@ public class MainActivity extends AppCompatActivity implements MyCamera {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} }
@Override
public void disableFlashlight() { public void disableFlashlight() {
mToggleBtn.setImageResource(R.mipmap.flashlight_big); mToggleBtn.setImageResource(R.mipmap.flashlight_big);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} }
@Override @Subscribe
public void cameraUnavailable() { public void cameraUnavailable(Events.CameraUnavailable event) {
Utils.showToast(this, R.string.camera_error); Utils.showToast(this, R.string.camera_error);
disableFlashlight(); disableFlashlight();
} }

View File

@ -31,5 +31,19 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/butterknife_text"/> android:text="@string/butterknife_text"/>
<TextView
android:id="@+id/license_otto_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:text="@string/otto_title"
android:textColor="@color/colorPrimary"/>
<TextView
android:id="@+id/license_otto_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/otto_text"/>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@ -18,4 +18,7 @@
<string name="butterknife_title">Butter Knife (view injector)</string> <string name="butterknife_title">Butter Knife (view injector)</string>
<string name="butterknife_text">Copyright 2013 Jake Wharton\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions and limitations under the License.</string> <string name="butterknife_text">Copyright 2013 Jake Wharton\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions and limitations under the License.</string>
<string name="butterknife_url">https://github.com/JakeWharton/butterknife</string> <string name="butterknife_url">https://github.com/JakeWharton/butterknife</string>
<string name="otto_title"><u>Otto (event bus)</u></string>
<string name="otto_text">Copyright 2012 Square, Inc.\nCopyright 2010 Google, Inc.\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="otto_url">https://github.com/square/otto</string>
</resources> </resources>