我正在制作一个手电筒小部件,它将打开/关闭手电筒,我也试图在点击小部件按钮时切换小部件按钮的图标,为此我有了Appwidgetprovider,其onUpdate将使用RemoteViews并调用BroadcastReceiver。
在BroadcastReceiver中,onReceive函数将执行手电筒切换和小部件的图标切换。 我面临的问题是onReceive函数没有被调用,并且小部件没有发生任何动作。
下面是代码:
AppWidgetProvider类:
public class WidgetActivity extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Intent receiver = new Intent(context, WidgetActivity.class);
receiver.setAction("COM_FLASHLIGHT");
receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_flash_layout);
views.setOnClickPendingIntent(R.id.imageButton1, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
}
BroadcastReceiver类:
public class WidgetService extends BroadcastReceiver {
private static boolean isLightOn = false;
private static Camera camera;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_flash_layout);
if (isLightOn) {
views.setImageViewResource(R.id.imageButton1,
R.drawable.light_off_widget);
} else {
views.setImageViewResource(R.id.imageButton1,
R.drawable.light_on_widget);
}
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
appWidgetManager.updateAppWidget(new ComponentName(context,
WidgetActivity.class), views);
if (isLightOn) {
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
isLightOn = false;
}
} else {
// Open the default i.e. the first rear facing camera.
camera = Camera.open();
if (camera == null) {
Toast.makeText(context, "no camera", Toast.LENGTH_SHORT).show();
} else {
// Set the torch flash mode
Parameters param = camera.getParameters();
param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
try {
camera.setParameters(param);
camera.startPreview();
isLightOn = true;
} catch (Exception e) {
Toast.makeText(context, "no flash", Toast.LENGTH_SHORT)
.show();
}
}
}
}
}
清单:
<receiver android:name="com.widget.WidgetActivity">
<intent-filter>
<action
android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/flash_widget" />
</receiver>
<receiver android:name="com.widget.WidgetService">
<action android:name="COM_FLASHLIGHT"></action>
</receiver>
在清单中,我不包装了小部件服务的<action>
标记
<intent-filter>
因为它显示警告说&#34;导出的接收器不需要许可&#34;。
答案 0 :(得分:5)
onReceive function is not being called and no action happening with the widget
您的意图component class
应该是Broadcast Receiver class
,而不是WidgetProvider
更改此
Intent receiver = new Intent(context, WidgetActivity.class);
到
Intent receiver = new Intent(context, WidgetService.class);
当您使用PendingIntent.getBroadcast
时,它会指向Intent to be broadcast
。因此,当您点击widget
中的按钮时,系统会调用Broadcast Receiver
onResume
。
您不需要在Action
设置任何receiver
。
但是如果您想使用自定义Intent
,那么您可以像这样设置Intent action
Intent receiver = new Intent("COM_FLASHLIGHT");
并且manifest
中的接收者应该注册intent-filter
来处理自定义操作。
<receiver android:name=".services.WidgetService">
<intent-filter>
<action android:name="COM_FLASHLIGHT"></action>
</intent-filter>
</receiver>
因此,当调用BroadCast Receiver
onReceive
时,您可以检查此类具体操作
public class WidgetService extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equalsIgnoreCase("COM_FLASHLIGHT")){
// do your stuff for this action.
}
}
自定义Actions
通常是在RemoteView
中有多个操作时定义的。
答案 1 :(得分:0)
如果您阅读该文档,则在触发 notifyDataSetChanged()时会调用RemoteViewsService中的onDataSetChanged。
因此,如果您想通过 onReceive()方法更新WidgetService,则可以调用 来自AppWidgetManager的 notifyAppWidgetViewDataChanged()方法
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
int[] ids = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
AppWidgetManager.getInstance(context)
.notifyAppWidgetViewDataChanged(ids, R.id.stack_view_movies);
}