エンタープライズ モビリティ管理 (EMM) アプリを作成しました。数年前に立ち上げたとき、私の顧客ベースにはおそらく Android 8 未満のデバイスがありました。最近アプリを更新する必要があり、顧客ベースは現在 Android 11 デバイスを使用しています。
問題:
常に実行されている BG サービスがあります。500 からカウントダウンし、0 になると、EMM ポータルの状態を更新する Web サービスを開始します。ポータルは、顧客が現場でデバイスを確認するために使用するものです。
私の BG サービスの ondestroy メソッドでは、受信機を使用して破壊されたサービスを再起動するブロードキャストを送信し、サービスを存続させます。
私の顧客は、データ使用量やバッテリー レベル情報などの情報を送信するため、このサービスが生きていることを必要としています。
私が試したこと:
Android Doze がアプリをスリープ状態にすることを理解しています。ソリューションを使用して、Doze からホワイトリストに登録するコマンドをデバイスに送信しようとしましたが、これは機能しません。
代わりに JobIntentService を使用してみましたが、これも機能しませんでした。
注意。私のアプリはデバイス管理アプリであるため、フォアグラウンドにある必要はなく、実際にはそうすべきではありません。デバイス管理者も Doze から免除されているようです。
エラー:
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>