-
Notifications
You must be signed in to change notification settings - Fork 0
Android 手电筒小程序
ythy edited this page May 10, 2018
·
2 revisions
手电筒小程序涉及2方面内容:
- home widget
- camera
- 需要增加权限,用于手电筒
<!-- 打开Camera的权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.autofocus" />
<!-- 开启闪光灯权限 -->
<uses-permission android:name="android.permission.FLASHLIGHT" />
- 桌面小程序 增加 receiver配置
<receiver
android:name="com.mx.easytouch.receiver.TorchWidgetProvider" //更新小程序文件 继承 AppWidgetProvider
android:icon="@drawable/flash_on" //小程序一览中的图标
android:label="@string/type_torch" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> // 固定代码
</intent-filter>
<intent-filter>
<action android:name="COM_FLASHLIGHT" > // 自定义action 用于手电筒状态切换
</action>
</intent-filter>
<meta-data
android:name="android.appwidget.provider" //固定代码
android:resource="@xml/torch_appwidget_info" /> //小程序布局配置文件
</receiver>
- 桌面小程序布局 分2部分
//第一部分 @xml/torch_appwidget_info
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="60dp"
android:minWidth="60dp"
android:updatePeriodMillis="0" //不自动刷新
android:widgetCategory="home_screen|keyguard" //支持主屏和锁屏(高版本支持)
android:initialLayout="@layout/widget_torch">
</appwidget-provider>
//第二部分 @layout/widget_torch
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<ImageButton
android:id="@+id/btnTorch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"/>
</LinearLayout>
- 基于
AppWidgetProvider
操作小程序。 注意:更新小程序样式,必须通过onUpdate()
生命周期函数进行
onReceive()
函数是此页面所有函数执行的基础,必须调用super.onReceive(context, intent);
否则生命周期函数不再触发
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Intent receiver = new Intent(context, TorchWidgetProvider.class);
receiver.setAction(Intent.ACTION_VIEW);
receiver.setAction(RECEIVE_FLASH);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0); // 广播形式派发intent
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_torch);
views.setOnClickPendingIntent(R.id.btnTorch, pendingIntent); // 点击按钮切换闪光灯状态
if(isLightOn) {
views.setImageViewResource(R.id.btnTorch, R.drawable.flash_on);
startTorchService(context, true);
} else {
views.setImageViewResource(R.id.btnTorch, R.drawable.flash_off);
startTorchService(context, false);
}
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(RECEIVE_FLASH.equals(intent.getAction())){ //此处调用 appWidgetManager.updateAppWidget 无效
handleCamera(context);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context.getApplicationContext());
ComponentName thisWidget = new ComponentName(context.getApplicationContext(), TorchWidgetProvider.class);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
if (appWidgetIds != null && appWidgetIds.length > 0) {
onUpdate(context, appWidgetManager, appWidgetIds);
}
}
}
- 打开闪光灯。
camera
方式在Android 6以后被废弃,需要判断版本调用不同API。 注意: 此处调用基于反射,高版本API不能直接
在此处调用,可以通过其他Class封装调用, 模拟器测试Android API 16报错
//省略调用部分
private void handleCamera(Context context){
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
handleCameraOld();
} else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
handleCameraNew(context);
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void handleCameraNew(Context context){
boolean result = Camera2Utils.torchSwitch(context, isLightOn); //通过公共方法调用API
if(result)
isLightOn = !isLightOn;
}
代码如下
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
manager.setTorchMode("0", isLightOn ? false: true);
- 打开闪光灯时,通知栏显示, 点击通知栏,调用小程序手电状态切换的receiver。 此处增加 TorchService
注意:pendingIntent
必须通过PendingIntent.getBroadcast()
派发broadcast
, 否则receiver
接收不到
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTorchNotification();
return START_NOT_STICKY;
}
private void startTorchNotification(){
Intent notificationIntent = new Intent(this, TorchWidgetProvider.class);
notificationIntent.setAction(Intent.ACTION_VIEW);
notificationIntent.setAction(TorchWidgetProvider.RECEIVE_FLASH);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, 0);
this.torchNotification = new Notification.Builder(getApplicationContext())
.setContentTitle("Torch turned on")
.setContentText("Tap to turn off.")
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.won)
.build();
torchNotification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
startForeground(NOTIFICATION_ID, torchNotification);
}
- 相机操作可以转移到service中进行
- 小程序的外观调整(和桌面快捷方式不一致)
tell me how get back to sunshine