【问题标题】:Long running Android service only running on specific devices仅在特定设备上运行的长期运行的 Android 服务
【发布时间】:2024-04-28 01:00:02
【问题描述】:

一般

我对如何使服务长时间运行进行了大量研究,我认为我已经成功了,但根本没有,因为我发现我的应用程序无法在特定设备上正确运行。 即使相应的活动关闭,我的服务也应该运行,所以我已经注册了一个 BOOT_COMPLETED 接收器并通过警报管理器启动我的服务。

发现

我的测试包括:

  • 华为P7/安卓V6.0
  • 华为P8/安卓V6.0
  • 华为P9/安卓V7.0
  • NEXUS(模拟器)/Android V6.0

在 HUAWEI P9 和 Android Emulator 上,应用程序任务关闭后服务会继续运行,甚至在启动设备后服务也会运行。 如果我手动终止服务,服务甚至会自行重启。

在华为 P7 和 P8 上,每次我销毁任务时服务都会被销毁,并且它不会自行重启。我的 Boot 接收器也没有启动我的服务。

服务

public class QuestionService extends Service {
    /* Attributes */

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        /* Some Code*/

        new QuestionTask().execute();

        return START_NOT_STICKY;
    }


    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopSelf();
    }

    private class QuestionTask extends AsyncTask<Void, Long, Void> {

        @Override
        protected Void doInBackground(Void... params) {
           /* Task to be executed periodically */
            return null;
        }

        @Override
        protected void onProgressUpdate(Long... values) {
            super.onProgressUpdate(values);

            /* gets periodically called and executes some code */
        }
    }
}

接收器

 public class DeviceBootReceiver extends BroadcastReceiver {

    private static final long REPEAT_TIME = 1000 * 30;
    private SharedPreferences sp;

    @Override
    public void onReceive(Context context, Intent intent) {
        sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
        //if(!sp.getBoolean("firstStart",true)) {

            /* AppActivationService starten */
        AlarmManager service = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);

        Calendar cal = Calendar.getInstance();
        // start 15 seconds after boot completed
        cal.add(Calendar.SECOND, 15);



            /* QuestionService starten */
        Intent iq = new Intent(context, QuestionStartReceiver.class);
        PendingIntent quest = PendingIntent.getBroadcast(context, 0, iq, PendingIntent.FLAG_CANCEL_CURRENT);



        service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                cal.getTimeInMillis(), REPEAT_TIME, quest);


        //}

    }
}

问题开始接收器:

public class QuestionStartReceiver extends BroadcastReceiver {
    public QuestionStartReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context, QuestionService.class);
        context.startService(i);
    }
}

清单

<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<receiver android:name=".receiver.QuestionStartReceiver" />
<receiver android:name=".receiver.DeviceBootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
</receiver>
<service android:name=".services.QuestionService"
            android:exported="false" />

我也尝试过使用 WakeLocker,但这似乎并不能解决我的问题,因为服务只是在不处于睡眠模式时破坏并且不会自行启动。

【问题讨论】:

    标签: java android service task


    【解决方案1】:

    我刚刚在测试另一个应用时偶然发现了答案!

    华为有一个名为“受保护的应用程序”的内置功能。当主进程被破坏时,未标记为受保护的已安装应用程序(以及所有相应的服务)将被系统杀死。将我的应用程序标记为“受保护”解决了我的问题,现在每个服务都在后台运行,即使在手动终止我的应用程序之后也是如此。

    本主题描述了如何处理这种斗争: "Protected Apps" setting on Huawei phones, and how to handle it

    【讨论】:

      最近更新 更多