You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

收到指定内容短信触发通知: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:24:49