收到指定内容短信触发通知:BroadcastReceiver中无法创建通知的解决方法
解决BroadcastReceiver中创建系统通知的问题
首先明确一点:BroadcastReceiver里完全可以创建并触发系统通知,只是你需要遵循Android的通知规范(尤其是Android 8.0及以上的通知渠道要求),同时修正代码里的小语法问题。下面一步步帮你搞定:
第一步:确认并申请必要权限
在AndroidManifest.xml里添加核心权限:
<!-- 接收短信基础权限 --> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <!-- Android 13+ 发送通知的权限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
注意:这两个都属于危险权限,Android 6.0+系统需要在代码里动态申请,用户授权后才能正常工作。
第二步:适配Android 8.0+的通知渠道
从Android 8.0(API 26)开始,所有通知必须归属一个通知渠道,否则不会显示。我们可以写一个工具方法来创建渠道:
private void createNotificationChannel(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence channelName = "安全提醒通知"; String channelDesc = "收到特定短信时的告警通知"; int importance = NotificationManager.IMPORTANCE_HIGH; // 高优先级,确保通知能弹出 NotificationChannel channel = new NotificationChannel("SAFETY_ALERT_CHANNEL", channelName, importance); channel.setDescription(channelDesc); NotificationManager notificationManager = context.getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } }
第三步:修改BroadcastReceiver代码,替换Toast为系统通知
修正你代码里的语法错误(比如if (sms.equals(ALERT)缺少闭合括号),并添加通知触发逻辑:
public class ReceiveMessage extends BroadcastReceiver { final String ALERT = "A"; final String ALERT2 = "B"; @Override public void onReceive(Context context, Intent intent) { Bundle myBundle = intent.getExtras(); try { if (myBundle != null) { final Object[] pdus = (Object[]) myBundle.get("pdus"); String format = myBundle.getString("format"); // 提前创建通知渠道(适配高版本系统) createNotificationChannel(context); for (int i = 0; i < pdus.length; i++) { SmsMessage mynewsms = SmsMessage.createFromPdu((byte[]) pdus[i], format); String smsContent = mynewsms.getMessageBody(); // 匹配目标短信,触发对应通知 if (smsContent.equals(ALERT)) { showSystemNotification(context, "安全告警", "触发预设告警A"); } if (smsContent.equals(ALERT2)) { showSystemNotification(context, "安全告警", "Your child is out save zone"); } } } } catch (Exception ex) { ex.printStackTrace(); // 别空吞异常,方便调试排查问题 } } // 封装通知创建与发送方法 private void showSystemNotification(Context context, String title, String content) { // 构建通知内容 NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "SAFETY_ALERT_CHANNEL") .setSmallIcon(R.drawable.ic_notification) // 替换成你的项目通知图标(必须设置) .setContentTitle(title) .setContentText(content) .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true); // 点击通知后自动取消 // 发送通知 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); // 用时间戳作为通知ID,保证每次通知唯一;如果需要覆盖旧通知,可固定一个ID notificationManager.notify((int) System.currentTimeMillis(), builder.build()); } // 创建通知渠道的方法 private void createNotificationChannel(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence channelName = "安全提醒通知"; String channelDesc = "收到特定短信时的告警通知"; int importance = NotificationManager.IMPORTANCE_HIGH; NotificationChannel channel = new NotificationChannel("SAFETY_ALERT_CHANNEL", channelName, importance); channel.setDescription(channelDesc); NotificationManager notificationManager = context.getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } } }
关键注意事项
- 通知图标要求:
setSmallIcon必须设置,且建议使用透明背景的图标,避免在不同系统主题下显示异常。 - 动态权限申请:记得在启动Activity里主动申请权限,示例代码如下:
// 检查并申请权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECEIVE_SMS, Manifest.permission.POST_NOTIFICATIONS}, 1001); } - BroadcastReceiver生命周期:
onReceive方法执行时长不能超过10秒,创建通知属于轻量操作,直接执行没问题;如果有额外耗时任务(比如网络请求),建议用WorkManager处理。
内容的提问来源于stack exchange,提问作者Fatima Zahra Boucif
相关产品推荐
相关产品推荐

