[Android] 小米2S AlarmManager唤醒系统的问题

文章讨论了在小米2S设备上使用AlarmManager监控剪贴板变化时遇到的问题,由于该设备对唤醒操作有限制,因此提出了使用RTC(Real-Time Clock)替代AlarmManager的解决方案。对于需要唤醒操作的情况,建议使用后台长期运行的服务。

1. 源起

    使用AlarmManager+IntentService来监控某个程序在前台的剪贴板变化,在小米2S上面,AlarmManager没有启动。看了一些文章,说是小米2S为了省电,对唤醒操作是5分钟一次。。。


2. 解决

    我的工作是不需要唤醒操作的,因此,使用RTC代替RTC_WAKEUP即可。

    如果是需要唤醒的操作,使用一个后台长期的Service也是可以的。


3. 参考

    小米2S关于AlarmManager唤醒系统问题

    小米2s手机下AlarmManager应用

<think>我们正在讨论如何防止Android后台服务被系统杀死。根据引用[1]和引用[2],我们可以采取以下措施: 1. **使用START_STICKY**:在服务的`onStartCommand`方法中返回`START_STICKY`,这样当服务被系统杀死后,系统会尝试重新创建服务。 2. **使用前台服务**:将服务设置为前台服务,通过显示一个持续的通知,让系统知道该服务是用户关注的,从而降低被杀死的概率。 3. **使用部分唤醒锁**:在服务中获取部分唤醒锁(WakeLock),可以防止CPU休眠,但要注意在不需要时及时释放,避免耗电。 4. **在Manifest中设置高优先级**:通过设置服务的`android:priority`属性为999,可以提升服务的优先级。 5. **在onDestroy中重启服务**:在服务被销毁时,重新启动服务。 6. **利用系统广播拉活**:注册系统广播(如屏幕亮灭、网络变化等),在收到广播时检查服务状态,若被杀则重启。 7. **使用JobScheduler/AlarmManager定期重启**:定时唤醒服务,确保服务在需要时运行。 8. **白名单策略**:引导用户手动将应用加入电池优化白名单或后台运行白名单(不同厂商设置不同)。 下面详细说明几种关键方法: ### 1. 使用前台服务 ```java // 在Service的onCreate或onStartCommand中 private void startForeground() { NotificationChannel channel = new NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_LOW); NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); manager.createNotificationChannel(channel); Notification notification = new NotificationCompat.Builder(this, "channel_id") .setContentTitle("服务运行中") .setContentText("后台服务正在运行") .setSmallIcon(R.drawable.ic_notification) .build(); startForeground(1, notification); // 必须使用唯一的通知ID(非0) } ``` ### 2. 在onDestroy中重启服务 ```java @Override public void onDestroy() { super.onDestroy(); // 发送广播重启服务,或者直接启动 Intent intent = new Intent(this, YourService.class); startService(intent); } ``` ### 3. 利用系统广播拉活 在AndroidManifest.xml中注册广播接收器: ```xml <receiver android:name=".BootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.USER_PRESENT" /> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> ``` 在广播接收器中重启服务: ```java public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { context.startService(new Intent(context, YourService.class)); } } ``` ### 4. 白名单设置引导 ```java // 跳转到电池优化设置页面 Intent intent = new Intent(); intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); startActivity(intent); ``` ### 5. 使用JobScheduler定期重启 ```java // 在Service中或AlarmReceiver中 ComponentName serviceComponent = new ComponentName(this, YourService.class); JobInfo jobInfo = new JobInfo.Builder(0, serviceComponent) .setPeriodic(15 * 60 * 1000) // 15分钟 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setPersisted(true) // 重启后依然有效 .build(); JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); scheduler.schedule(jobInfo); ``` ### 注意事项 - 前台服务必须显示通知,否则在Android 8.0+会抛出异常。 - 部分唤醒锁(WakeLock)需要权限`<uses-permission android:name="android.permission.WAKE_LOCK" />`。 - 不同手机厂商(如华为、小米、OPPO等)有自己的后台管理策略,需要单独适配[^2]。 综上所述,防止服务被杀死需要综合运用多种策略,但请注意过度保活可能导致应用被系统列入黑名单或用户主动卸载。 §§相关问题§§ 1. 如何适配不同厂商的Android系统后台管理? 2. 前台服务通知如何隐藏? 3. Android 10+的后台启动限制如何解决?</think>### 防止Android后台服务被系统杀死的解决方案 #### 1. **使用前台服务(最高优先级)** ```java // 在服务中创建前台通知 private void startForegroundService() { NotificationChannel channel = new NotificationChannel("channel_id", "后台服务", IMPORTANCE_LOW); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); Notification notification = new NotificationCompat.Builder(this, "channel_id") .setContentTitle("推流服务运行中") .setSmallIcon(R.drawable.ic_service) .build(); startForeground(1, notification); // 必须使用非0的通知ID } ``` - 在`onStartCommand`中调用此方法 - 添加权限:`<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>` - 优点:系统会优先保留前台服务[^1] #### 2. **设置服务粘性重启** ```java @Override public int onStartCommand(Intent intent, int flags, int startId) { startForegroundService(); return START_STICKY; // 系统会在资源可用时重启服务 } ``` #### 3. **双进程守护(核心方案)** ```java // 主服务 public class MainService extends Service { @Override public void onCreate() { startService(new Intent(this, GuardService.class)); } } // 守护服务 public class GuardService extends Service { @Override public void onCreate() { startService(new Intent(this, MainService.class)); } } ``` - 原理:两个服务互相监控,当一方被杀死时立即重启对方 - 在Manifest中声明两个服务: ```xml <service android:name=".MainService" android:process=":service1"/> <service android:name=".GuardService" android:process=":service2"/> ``` #### 4. **系统广播唤醒** ```java // 注册广播接收器 <receiver android:name=".BootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.USER_PRESENT"/> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver> // 广播接收器实现 public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { context.startService(new Intent(context, MainService.class)); } } ``` #### 5. **厂商白名单设置** ```java // 引导用户手动设置 public void openPowerSetting() { try { Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); startActivity(intent); } catch (Exception e) { // 处理厂商特定设置 if (Build.MANUFACTURER.equalsIgnoreCase("xiaomi")) { openXiaomiSetting(); } } } ``` #### 6. **JobScheduler保活(Android 5.0+)** ```java ComponentName serviceComponent = new ComponentName(this, MainService.class); JobInfo jobInfo = new JobInfo.Builder(1, serviceComponent) .setPeriodic(15 * 60 * 1000) // 每15分钟唤醒 .setPersisted(true) // 重启后依然有效 .build(); JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE); scheduler.schedule(jobInfo); ``` ### 注意事项 1. **功耗优化**: - 避免不必要的唤醒锁 - 使用`AlarmManager.setExactAndAllowWhileIdle()`精准唤醒 - 后台服务应最小化资源占用 2. **厂商适配**: ```java // 华为设备特殊设置 if (Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")) { Intent intent = new Intent(); intent.setClassName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity"); startActivity(intent); } ``` 3. **Android 8.0+限制**: - 后台服务必须使用前台通知 - 后台执行限制:`<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>` ### 效果评估指标 | 策略 | 存活率 | 功耗影响 | 适配难度 | |------|--------|----------|----------| | 前台服务 | ★★★★★ | ★★☆ | ★☆☆ | | 双进程守护 | ★★★★☆ | ★★★☆ | ★★☆ | | 系统广播 | ★★★☆☆ | ★☆☆ | ★☆☆ | | JobScheduler | ★★★☆☆ | ★☆☆ | ★★☆ | > 综合建议:使用**前台服务+双进程守护+JobScheduler**的组合方案,可达到90%以上的存活率[^1][^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值