从小部件启动/停止服务 [英] Start/Stop Service from Widget
问题描述
我想从小部件内部启动服务,我知道我可以像使用PendingIntent一样
I want to start a service from inside the widget, I know that i can do it using PendingIntent like
PendingIntent intent = PendingIntent.getService(context, 0, new Intent(context, MyService.class), Intent.FLAG_ACTIVITY_NEW_TASK);
remoteViews.setOnClickPendingIntent(R.id.buttonWidgetStartService, intent);
,但是问题是我已经在该按钮上使用了PendingIntent用于其他用途. 因此,我尝试使用
but the problem is that I've already used PendingIntent on that button for some other purpose. So, I tried starting the service using
context.startService(new Intent(context, MyService.class));
在这里我得到NullPointerException
.
这是我的代码:
public class WiNetWidget extends AppWidgetProvider {
public static String TOGGLE_WINET = "ToggleWiNetService";
private static boolean serviceRunning = false;
private static Intent serviceIntent;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
serviceIntent = new Intent(context, WiNetService.class);
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_winet);
remoteViews.setViewVisibility(R.id.buttonWidgetLoading, View.INVISIBLE);
remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.VISIBLE);
Intent newIntent = new Intent(context, WiNetWidget.class);
newIntent.setAction(TOGGLE_WINET);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.buttonWidgetStartService, pendingIntent);
remoteViews.setOnClickPendingIntent(R.id.buttonWidgetStopService, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
Log.i(TOGGLE_WINET, "updated");
}
}
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(TOGGLE_WINET)) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_winet);
if(serviceRunning) {
context.stopService(serviceIntent);
remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.VISIBLE);
remoteViews.setViewVisibility(R.id.buttonWidgetStopService, View.INVISIBLE);
Toast.makeText(context, "serviceStopped", Toast.LENGTH_SHORT).show();
} else {
context.startService(serviceIntent);
remoteViews.setViewVisibility(R.id.buttonWidgetStopService, View.VISIBLE);
remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.INVISIBLE);
Toast.makeText(context, "serviceStarted", Toast.LENGTH_SHORT).show();
}
serviceRunning=!serviceRunning;
ComponentName componentName = new ComponentName(context, WiNetWidget.class);
AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);
}
super.onReceive(context, intent);
}
}
注意:如果删除包含startService
和stopService
的行,则一切运行顺利.
Note: If I remove the lines containing startService
and stopService
, everything is running smoothly.
先谢谢了!! :)
推荐答案
问题是您一次创建一个一次性的Intent
,但多次使用它.每次您要启动或停止Service
时,最好创建一个新的Intent
,如下所示:
The issue is that you create a one-shot Intent
once, but use it multiple times. Better to create a fresh Intent
every time you want to start or stop the Service
as follows:
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(TOGGLE_WINET)) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_winet);
// Create a fresh intent
Intent serviceIntent = new Intent(context, WiNetService.class);
if(serviceRunning) {
context.stopService(serviceIntent);
remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.VISIBLE);
remoteViews.setViewVisibility(R.id.buttonWidgetStopService, View.INVISIBLE);
Toast.makeText(context, "serviceStopped", Toast.LENGTH_SHORT).show();
} else {
context.startService(serviceIntent);
remoteViews.setViewVisibility(R.id.buttonWidgetStopService, View.VISIBLE);
remoteViews.setViewVisibility(R.id.buttonWidgetStartService, View.INVISIBLE);
Toast.makeText(context, "serviceStarted", Toast.LENGTH_SHORT).show();
}
serviceRunning=!serviceRunning;
ComponentName componentName = new ComponentName(context, WiNetWidget.class);
AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);
}
super.onReceive(context, intent);
}
这篇关于从小部件启动/停止服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!