首页 > 解决方案 > 在 Android 11 上保持后台服务处于活动状态

问题描述

我创建了一个企业移动管理 (EMM) 应用程序。几年前我推出它时,我的客户群可能拥有 Android < 8 设备。我最近不得不更新我的应用程序,客户群现在正在使用 Android 11 设备。

问题:

我有一个不断运行的 BG 服务。它从 500 开始倒计时,然后当它达到 0 时,它会启动一个更新 EMM 门户中状态的 Web 服务。该门户是客户用来在现场查看他们的设备的地方。

在我的 BG 服务的 ondestroy 方法中,我发送了一个广播,该广播使用接收器重新启动被破坏的服务,从而使其保持活动状态。

我的客户需要这项服务,因为它会发送数据使用情况和电池电量信息等信息,这在他们的行业中可能是安全的关键。

我试过的:

我了解 Android Doze 使应用程序进入睡眠状态,我尝试使用我的解决方案向设备发送命令,将其从 Doze 列入白名单,但这不起作用。

我尝试使用 JobIntentService ,但这也不起作用。

注意。我的应用程序是设备管理应用程序,因此不需要在前台,实际上也不应该在前台。设备管理员显然也免于打瞌睡。

错误:

Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=xxxxx/.ConnectivityService }: app is in background 

在 Android 11 上保持此服务在后台运行的最佳方法是什么?

这是我的代码:

<service
            android:name="xxx.ConnectivityService"
            android:enabled="true"
            android:permission="android.permission.BIND_JOB_SERVICE">
        </service>

.

public class ConnectivityServiceRestarterBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e(ConnectivityServiceRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! ");
        context.startService(new Intent(context, ConnectivityService.class));
        //ConnectivityService.enqueueWork(context, new Intent());
    }
}

.

 public class ConnectivityService extends Service {
    
        private static final String TAG = ConnectivityService.class.getSimpleName();
        public int counter=0;
        AppObj appobj;
    
        public ConnectivityService(Context applicationContext) {
            super();
    
            Log.e(TAG, "inside ConnectivityService!");
        }
    
        public ConnectivityService() {
        }
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            super.onStartCommand(intent, flags, startId);
    
            Log.e(TAG, "inside onStartCommand");
    
            appobj = (AppObj)getApplication();
    
            startTimer();
            return START_STICKY;
        }
    
    
      
    
    
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.e(TAG, "ondestroy!");
            Intent broadcastIntent = new Intent("xxx.ActivityRecognition.RestartConnectivityservice");
            sendBroadcast(broadcastIntent);
            stoptimertask();
        }
    
        private Timer timer;
        private TimerTask timerTask;
        long oldTime=0;
        public void startTimer() {
    
            Log.e(TAG, "inside startTimer");
            //set a new Timer
            timer = new Timer();
    
            //initialize the TimerTask's job
            initializeTimerTask();
    
            //schedule the timer, to wake up every 1 second
            timer.schedule(timerTask, 1000, 1000); //
        }
    
        /**
         * it sets the timer to print the counter every x seconds
         */
        public void initializeTimerTask() {
            Log.e(TAG, "inside initializeTimerTask");
    
            timerTask = new TimerTask() {
                public void run() {
                    Log.e(TAG, "in timer ++++  "+ (counter++));
    
                    if(counter == 3600){
    
                        counter = 0;
    
                        appobj.webService.sendPulseToServer();
    
                        Intent myIntent = new Intent(getApplicationContext(), TrafficMonitorService.class);
                        myIntent.setAction("xxx.TrafficMonitorService");
                        getApplicationContext().startService(myIntent);
    
                    }
                }
            };
        }
    
        /**
         * not needed
         */
        public void stoptimertask() {
            //stop the timer, if it's not already null
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    }

.


<receiver
            android:name="xxx.ConnectivityServiceRestarterBroadcastReceiver"
            android:enabled="true"
            android:exported="true"
            android:label="ConnectivityServiceRestartServiceWhenStopped">

            <intent-filter>
                <action android:name="xxx.ActivityRecognition.RestartConnectivityservice"/>
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>

        </receiver>

标签: androidservicedoze

解决方案


推荐阅读