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 'com.android.support:appcompat-v7:23.4.0'
compile 'com.jakewharton:butterknife:8.0.1'
compile 'com.squareup:otto:1.3.8'
apt 'com.jakewharton:butterknife-compiler:8.0.1'
}

View File

@ -15,3 +15,9 @@
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# 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.util.Log;
import com.squareup.otto.Bus;
public class MarshmallowCamera {
private static final String TAG = MyCameraImpl.class.getSimpleName();
private MyCamera mCallback;
private Context mContext;
public MarshmallowCamera(MyCamera camera, Context cxt) {
mCallback = camera;
public MarshmallowCamera(Context cxt) {
mContext = cxt;
}
@TargetApi(Build.VERSION_CODES.M)
public void toggleMarshmallowFlashlight(boolean enable) {
public void toggleMarshmallowFlashlight(final Bus bus, boolean enable) {
try {
final CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
final String[] list = manager.getCameraIdList();
manager.setTorchMode(list[0], enable);
} catch (CameraAccessException e) {
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.util.Log;
import com.squareup.otto.Bus;
public class MyCameraImpl {
private static final String TAG = MyCameraImpl.class.getSimpleName();
private static Camera mCamera;
private static Camera.Parameters mParams;
private static MyCamera mCallback;
private static Context mContext;
private static MarshmallowCamera mMarshmallowCamera;
private static Bus mBus;
private static boolean mIsFlashlightOn;
private static boolean mIsMarshmallow;
public MyCameraImpl(MyCamera camera, Context cxt) {
mCallback = camera;
public MyCameraImpl(Context cxt) {
mContext = cxt;
mIsMarshmallow = isMarshmallow();
if (mBus == null) {
mBus = BusProvider.getInstance();
mBus.register(this);
}
handleCameraSetup();
checkFlashlight();
}
public void toggleFlashlight() {
handleCameraSetup();
mIsFlashlightOn = !mIsFlashlightOn;
if (mIsFlashlightOn) {
enableFlashlight();
} else {
disableFlashlight();
}
handleCameraSetup();
}
public void handleCameraSetup() {
@ -39,11 +41,12 @@ public class MyCameraImpl {
} else {
setupCamera();
}
checkFlashlight();
}
private void setupMarshmallowCamera() {
if (mMarshmallowCamera == null) {
mMarshmallowCamera = new MarshmallowCamera(mCallback, mContext);
mMarshmallowCamera = new MarshmallowCamera(mContext);
}
}
@ -57,17 +60,23 @@ public class MyCameraImpl {
mParams = mCamera.getParameters();
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(mParams);
if (mIsFlashlightOn)
enableFlashlight();
} catch (Exception e) {
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) {
toggleMarshmallowFlashlight(true);
} else {
@ -78,10 +87,11 @@ public class MyCameraImpl {
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(mParams);
}
mCallback.enableFlashlight();
mBus.post(new Events.StateChanged(true));
}
private void disableFlashlight() {
mIsFlashlightOn = false;
if (isMarshmallow()) {
toggleMarshmallowFlashlight(false);
} else {
@ -92,18 +102,27 @@ public class MyCameraImpl {
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(mParams);
}
mCallback.disableFlashlight();
mBus.post(new Events.StateChanged(false));
}
private void toggleMarshmallowFlashlight(boolean enable) {
mMarshmallowCamera.toggleMarshmallowFlashlight(enable);
mMarshmallowCamera.toggleMarshmallowFlashlight(mBus, enable);
}
public void releaseCamera() {
if (mIsFlashlightOn) {
disableFlashlight();
}
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
if (mBus != null) {
mBus.unregister(this);
}
mIsFlashlightOn = false;
}
private boolean isMarshmallow() {

View File

@ -10,12 +10,17 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
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 MyCameraImpl mCameraImpl;
private static RemoteViews mRemoteViews;
private static AppWidgetManager mWidgetManager;
private static Bitmap mColoredBmp;
private static Bus mBus;
private static Context mContext;
private static int[] mWidgetIds;
@ -26,6 +31,7 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
}
private void initVariables(Context context) {
mContext = context;
final ComponentName component = new ComponentName(context, MyWidgetProvider.class);
mWidgetManager = AppWidgetManager.getInstance(context);
mWidgetIds = mWidgetManager.getAppWidgetIds(component);
@ -36,18 +42,23 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
mRemoteViews.setOnClickPendingIntent(R.id.toggle_btn, pendingIntent);
mCameraImpl = new MyCameraImpl(this, context);
mCameraImpl = new MyCameraImpl(context);
final Resources res = context.getResources();
final int appColor = res.getColor(R.color.colorPrimary);
mColoredBmp = Utils.getColoredIcon(context.getResources(), appColor, R.mipmap.flashlight_small);
if (mBus == null) {
mBus = BusProvider.getInstance();
}
registerBus();
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(TOGGLE)) {
if (mCameraImpl == null) {
if (mCameraImpl == null || mBus == null) {
initVariables(context);
}
@ -56,7 +67,6 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
super.onReceive(context, intent);
}
@Override
public void enableFlashlight() {
mRemoteViews.setImageViewBitmap(R.id.toggle_btn, mColoredBmp);
for (int widgetId : mWidgetIds) {
@ -64,22 +74,34 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
}
}
@Override
public void disableFlashlight() {
mRemoteViews.setImageViewResource(R.id.toggle_btn, R.mipmap.flashlight_small);
for (int widgetId : mWidgetIds) {
mWidgetManager.updateAppWidget(widgetId, mRemoteViews);
}
mCameraImpl.releaseCamera();
}
@Override
public void cameraUnavailable() {
@Subscribe
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
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
unregisterBus();
releaseCamera(context);
}
@ -87,7 +109,20 @@ public class MyWidgetProvider extends AppWidgetProvider implements MyCamera {
if (mCameraImpl == null)
initVariables(context);
disableFlashlight();
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);
}
@OnClick(R.id.license_otto_title)
public void ottoClicked() {
openUrl(R.string.otto_url);
}
private void openUrl(int id) {
final String url = getResources().getString(id);
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.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.R;
import com.simplemobiletools.flashlight.Utils;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity implements MyCamera {
public class MainActivity extends AppCompatActivity {
@BindView(R.id.toggle_btn) ImageView mToggleBtn;
private static Bus mBus;
private static MyCameraImpl mCameraImpl;
@Override
@ -29,7 +33,7 @@ public class MainActivity extends AppCompatActivity implements MyCamera {
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
setupCameraImpl();
mBus = BusProvider.getInstance();
}
@Override
@ -51,8 +55,8 @@ public class MainActivity extends AppCompatActivity implements MyCamera {
}
private void setupCameraImpl() {
mCameraImpl = new MyCameraImpl(this, this);
mCameraImpl.toggleFlashlight();
mCameraImpl = new MyCameraImpl(this);
mCameraImpl.enableFlashlight();
}
@OnClick(R.id.toggle_btn)
@ -63,28 +67,42 @@ public class MainActivity extends AppCompatActivity implements MyCamera {
@Override
protected void onStart() {
super.onStart();
mCameraImpl.handleCameraSetup();
mBus.register(this);
if (mCameraImpl == null) {
setupCameraImpl();
}
}
@Override
protected void onResume() {
super.onResume();
mCameraImpl.handleCameraSetup();
}
@Override
protected void onPause() {
super.onPause();
mCameraImpl.releaseCamera();
mCameraImpl.checkFlashlight();
}
@Override
protected void onStop() {
super.onStop();
mCameraImpl.releaseCamera();
mBus.unregister(this);
}
@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() {
final int appColor = getResources().getColor(R.color.colorPrimary);
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);
}
@Override
public void disableFlashlight() {
mToggleBtn.setImageResource(R.mipmap.flashlight_big);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void cameraUnavailable() {
@Subscribe
public void cameraUnavailable(Events.CameraUnavailable event) {
Utils.showToast(this, R.string.camera_error);
disableFlashlight();
}

View File

@ -31,5 +31,19 @@
android:layout_height="wrap_content"
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>
</ScrollView>

View File

@ -18,4 +18,7 @@
<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_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>