【问题标题】:Oreo - Widget services and broadcast receiver: Not allowed to start service IntentOreo - 小部件服务和广播接收器:不允许启动服务意图
【发布时间】:2018-06-22 08:52:46
【问题描述】:

我有一个监视 wifi 连接的小部件,因此我启动了一项服务来启动广播接收器以检测网络变化。一切正常,除非我退出主应用程序:服务停止。

所以我在小部件中启动了一个警报管理器,它大约每分钟唤醒一次并检查主应用程序是否已退出。如果是这种情况,我会尝试重新启动我的 wifi 监控服务,但这次它会崩溃并显示以下消息:

不允许启动服务 Intent { cmp=package.CallbackNetworkWidgetService(有附加功能)}:应用在 背景 uid UidRecord{f6e65b9 u0a154 RCVR 空闲更改:空闲|未缓存 procs:1 seq(0,0,0)}

问题在于 oreo 的新意图/服务模型。它一直有效到牛轧糖。

问题:

  1. 我的方法正确吗?

  2. 我有点迷失了前台/后台服务的概念。小部件是背景 svce? wifi监控服务/BR也是后台svce?

  3. 这里有什么问题?

清单:

<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

@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

 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);
    }

【问题讨论】:

    标签: android android-intent service broadcastreceiver android-8.0-oreo


    【解决方案1】:

    您需要为此使用前台服务。

    ContextCompat.startForegroundService(context, intentNetwork);
    

    不要忘记 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);
       }
       //...
    }
    

    【讨论】:

    • 我做了很多测试,我不能 100% 确定,但我相信这还不够。它改善了这种情况,但对我来说,解决 pb 的方法是使用警报管理器并从那里启动服务/BR。
    • @heyalex 你愿意调查一下吗?stackoverflow.com/questions/53578252/…
    • @BiswajitDas 检查答案,让我知道它是否有效。
    • @heyAlex 它的作品。你救了我。第一次仍然存在一些小部件刷新问题,但它起作用了。
    • @BiswajitDas 很高兴看到它有效。你现在有什么问题?
    猜你喜欢
    • 2018-12-23
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 2011-11-27
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    相关资源
    最近更新 更多