Alarm Manager在魅族Flyme OS中无法触发闹钟的解决方法
兄弟,我之前也碰到过Flyme上闹钟死活不触发的坑,太懂这种崩溃的感觉了!结合我踩过的坑和社区里的解决方案,给你几个针对性的办法,应该能搞定:
优先使用
setAlarmClock()替代其他闹钟方法
Flyme对普通闹钟的限制非常严格,哪怕是setExactAndAllowWhileIdle()都可能被系统拦截,但setAlarmClock()是系统为原生闹钟类应用预留的高优先级接口,系统会优先保证它的触发。代码示例:AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(this, YourAlarmReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); // 设置闹钟时间(这里以10分钟后为例) long triggerTime = System.currentTimeMillis() + 10 * 60 * 1000; AlarmManager.AlarmClockInfo clockInfo = new AlarmManager.AlarmClockInfo(triggerTime, pendingIntent); alarmManager.setAlarmClock(clockInfo, pendingIntent);手动开启Flyme专属的权限白名单
Flyme的电池优化和后台管控是出了名的严,必须手动给应用开几个关键权限:- 自启动权限:「设置 → 应用管理 → 找到你的应用 → 权限管理 → 自启动 → 允许」
- 后台耗电无限制:「设置 → 电池 → 耗电管理 → 找到你的应用 → 设置为「无限制」」
- 后台保护:在多任务界面下拉你的应用卡片,点击「锁定」,避免被一键清理杀掉
在广播接收器中快速启动前台服务
Flyme对后台广播的存活时间限制极短,如果你在闹钟触发后的广播接收器里做耗时操作,大概率会被系统直接杀死。建议在onReceive()里立即启动一个前台服务,保证后续逻辑能执行:@Override public void onReceive(Context context, Intent intent) { // 启动前台服务 Intent serviceIntent = new Intent(context, YourAlarmService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(serviceIntent); } else { context.startService(serviceIntent); } }然后在服务里调用
startForeground()显示一个通知(哪怕是静默通知也行),避免被系统回收。检查通知权限是否开启
有些Flyme版本会把通知权限和后台活动权限绑定,如果你的应用没有开启通知权限,系统可能会限制它的后台触发能力。可以在应用启动时检查并引导用户开启:if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, 1001); }避免使用重复闹钟,改用单次闹钟循环设置
setRepeating()在Flyme上基本是无效的,哪怕是精确重复的setExactRepeating()也会被系统限制。建议每次闹钟触发后,在服务里重新设置下一次的闹钟,这样能保证每次都是高优先级触发。
这些方法我之前在魅族18和魅族16上都试过,基本能解决闹钟不触发的问题。如果还是不行,可以试试把应用注册为系统闹钟应用(在AndroidManifest里添加对应的intent-filter),不过这个操作比较复杂,一般前面的方法就够用了。
内容的提问来源于stack exchange,提问作者user9757518

