奥利奥-窗口小部件服务和广播接收器:不允许启动服务意图 [英] Oreo - Widget services and broadcast receiver: Not allowed to start service Intent
问题描述
我有一个监视wifi连接的小部件,所以我启动了一项服务来启动广播接收器以检测网络变化.一切正常,除了我退出主应用程序时:服务停止.
I have a widget that monitors wifi connectivity so I start a service to initiate a broadcast receiver to detect network changes. All works well except when I exit the main app: the service stops.
因此,我在窗口小部件中启动了一个警报管理器,该警报管理器大约每分钟醒来一次,并检查主应用程序是否已退出.如果是这种情况,我尝试重新启动wifi监控服务,这次它崩溃并显示以下消息:
So I initiate in the widget an Alarm Manager that awakes roughly every minute and checks if the main app has exited. If that is the case I attempt to restart my wifi monitoring service and this time it crashes with the message:
不允许启动服务意图{ cmp = package .CallbackNetworkWidgetService(有其他功能)}:应用程序已在 后台uid UidRecord {f6e65b9 u0a154 RCVR空闲更改:空闲|未缓存 procs:1 seq(0,0,0)}
Not allowed to start service Intent { cmp=package.CallbackNetworkWidgetService (has extras) }: app is in background uid UidRecord{f6e65b9 u0a154 RCVR idle change:idle|uncached procs:1 seq(0,0,0)}
问题出在oreo新的意图/服务模型上.直到牛轧糖都可以使用.
The issue is with the oreo new intent/service model. It works until nougat.
问题:
-
我的方法正确吗?
is my approach correct?
我对前台/后台服务的概念有些迷惑.小部件是背景svce? wifi监控服务/BR还是后台服务吗?
I'm a little bit lost with the notion of foreground/background service. The widget is a background svce? The wifi monitoring service/BR is also a background svce?
这是什么问题?
清单:
<receiver android:name=".Widget.TestWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<intent-filter>
<action android:name="AUTO_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/test_widget_info" />
</receiver>
<service android:name=".Widget.CallbackNetworkWidgetService"></service>
CallbackWidgetNetworkService
CallbackWidgetNetworkService
@Override
public int onStartCommand(Intent i, int flags, int startId) {
context = this.getApplicationContext();
Log.i("WIDNET", "onStart network");
isWifiConnected();
return Service.START_NOT_STICKY;
}
public void isWifiConnected(){
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
getNetworkInfo();
// Log.i("WIDNET", "broadcastReceiver ipwan: "+ipwan+" type: "+type);
}
};
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(broadcastReceiver, intentFilter);
}
Appwidget-startNetworkService
Appwidget - startNetworkService
public static void startNetworkService(Context context){
int[] allWidgetIds = new int[0];
Log.i("WIDNET", "start network service");
ComponentName thisWidget = new ComponentName(context,
TestWidget.class);
if(widgetManager != null)
allWidgetIds = widgetManager.getAppWidgetIds(thisWidget);
if(intentNetwork != null) {
CallbackNetworkWidgetService cnws = new CallbackNetworkWidgetService();
cnws.stopSelf();
Log.i("WIDNET", "stop network service");
}
intentNetwork = new Intent(context.getApplicationContext(),
CallbackNetworkWidgetService.class);
intentNetwork.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.startService(intentNetwork);
}
推荐答案
您需要为此使用前台服务.
You need to use foreground service for this purpose.
ContextCompat.startForegroundService(context, intentNetwork);
不要忘记api 26+的通知:
Don't forget for notification for api 26+ :
@Override
public int onStartCommand(Intent i, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID)
.setContentTitle("wifi listener bla bla bla")
.setContentText(text)
.setAutoCancel(true);
Notification notification = builder.build();
startForeground(1, notification);
}
//...
}
这篇关于奥利奥-窗口小部件服务和广播接收器:不允许启动服务意图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!