海信Android 5.1.1设备BOOT_COMPLETED接收器失效求助
我之前在国产ROM上踩过类似的BOOT_COMPLETED广播不触发的坑,结合你的代码和描述,给你几个针对性的排查和修复方向:
1. 开启海信设备的自启动权限
很多国产厂商(包括海信)在Android 5.x及以上版本加了自启动管理功能,默认会拦截第三方应用的开机广播。你需要:
- 打开设备「设置」→「应用管理」→找到你的应用
- 手动开启「自启动权限」选项
这是这类问题最常见的原因,系统默认限制了应用的后台启动能力。
2. 先确认广播是否真的被接收
先搞清楚问题是「广播没收到」还是「收到了但闹钟没设置成功」:
在BootReceiver的onReceive方法开头加日志输出:
@Override public void onReceive(Context context, Intent intent) { Log.d("BootReceiver", "收到开机广播:" + intent.getAction()); // 原有的设置闹钟代码... }
重启设备后,用adb logcat过滤BootReceiver标签,看是否有日志。如果没有,说明广播根本没触发;如果有,再排查闹钟设置逻辑。
3. 调整PendingIntent的Flag参数
你当前用的PendingIntent.FLAG_ONE_SHOT是一次性标记,虽然先cancel了旧的PendingIntent,但对重复闹钟来说,更推荐用PendingIntent.FLAG_UPDATE_CURRENT(适配Android 12+也可以加FLAG_IMMUTABLE),避免因Flag导致PendingIntent无法重复触发:
PendingIntent pendingIntent = PendingIntent.getService( context, REQ_MESSAGE_CHECK, messageCheckerIntent, PendingIntent.FLAG_UPDATE_CURRENT // 替换原有的FLAG_ONE_SHOT );
4. 用WakeLock确保广播处理完成
BroadcastReceiver的生命周期极短,可能还没等你设置完闹钟,系统就回收了进程。可以用WakeLock临时保持CPU唤醒,确保操作完成:
首先在Manifest中添加WAKE_LOCK权限:
<uses-permission android:name="android.permission.WAKE_LOCK" />
然后修改BootReceiver代码:
@Override public void onReceive(Context context, Intent intent) { // 获取WakeLock,保持10秒足够完成闹钟设置 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wakeLock = pm.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, "BootReceiver:SetupWakeLock" ); wakeLock.acquire(10 * 1000); try { // 原有的设置闹钟代码... Calendar calendar = Calendar.getInstance(); Intent messageCheckerIntent = new Intent(context, MessageCheckerService.class); PendingIntent pendingIntent = PendingIntent.getService( context, REQ_MESSAGE_CHECK, messageCheckerIntent, PendingIntent.FLAG_UPDATE_CURRENT ); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager.cancel(pendingIntent); alarmManager.setRepeating( AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), ALARM_INTERVAL, pendingIntent ); } finally { // 释放WakeLock if (wakeLock.isHeld()) { wakeLock.release(); } } }
5. 确认应用未被强制停止
从Android 3.1开始,如果用户手动「强制停止」了应用,直到用户再次打开应用前,系统不会给该应用发任何广播(包括BOOT_COMPLETED)。测试前要确保用户至少打开过一次应用,不要处于强制停止状态。
6. 尝试海信专属的开机广播
有些海信设备用了自定义的开机广播动作,你可以在IntentFilter里加上试试:
<intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" /> <!-- 添加海信可能的自定义广播 --> <action android:name="com.hisense.intent.action.BOOT_COMPLETED" /> </intent-filter>
附你提供的原始代码供参考:
BootReceiver类
public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Set instance Alarm on boot Calendar calendar = Calendar.getInstance(); Intent messageCheckerIntent = new Intent(context, MessageCheckerService.class); PendingIntent pendingIntent = PendingIntent.getService(context, REQ_MESSAGE_CHECK, messageCheckerIntent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); // Cancel if any existing alarm for given pendingIntent (MessageCheckerService) alarmManager.cancel(pendingIntent); // Alarm is reset every time when this service is called, // still keep alarm repeating so if one call fails does not affect following calls alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), ALARM_INTERVAL, pendingIntent); } }
Manifest文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.project.myapp"> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> <application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" tools:ignore="AllowBackup"> <activity android:name=".SplashScreen" android:label="@string/app_name" android:launchMode="singleTask" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity" android:configChanges="orientation|screenSize" android:launchMode="singleTask"> </activity> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> <service android:name=".GPSTrack" /> <service android:name=".MessageCheckerService" android:enabled="true" /> <receiver android:name=".BootReceiver" android:directBootAware="true" android:enabled="true" android:exported="true" android:permission="android.permission.RECEIVE_BOOT_COMPLETED"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" /> </intent-filter> </receiver> </application> </manifest>
内容的提问来源于stack exchange,提问作者M N Dhanani

