代码之家  ›  专栏  ›  技术社区  ›  narb

oreo-小工具服务和广播接收器:不允许启动服务意图

  •  1
  • narb  · 技术社区  · 6 年前

    我有一个监控WiFi连接的小部件,所以我启动一个服务来启动一个广播接收器来检测网络变化。除了当我退出主应用程序:服务停止时,所有的工作都很好。

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

    不允许启动服务意图{ 凸轮轴位置= 包裹 .callbackNetworkWidgetService(有附加项):应用程序位于 后台uid uid记录f6e65b9 u0a154 rcvr空闲更改:空闲未缓存 程序:1顺序(0,0,0)

    问题在于OREO新的意图/服务模型。它一直工作到牛轧糖。

    问题:

    1. 我的方法正确吗?

    2. 我对前台/后台服务的概念有点迷茫。小部件是后台服务?wifi监控服务/br也是后台服务?

    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-启动网络服务

     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);
        }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   HeyAlex    6 年前

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