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

Firebase通知部分设备无法接收及自定义铃声播放技术咨询

解决Firebase通知部分设备收不到+自定义闹钟铃声的问题

嘿,我来帮你搞定这两个Firebase通知的棘手问题!

一、处理部分设备未启动Firebase服务的情况

首先得明确:Firebase Messaging严重依赖Google Play Services,而且很多国产安卓厂商的后台管控会直接干掉相关服务,导致收不到推送。这里有几个关键修复步骤:

  • 先检查Google Play Services状态
    应用启动时先判断设备的Google服务是否正常,避免白忙活。用这段代码检测:

    int resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
    if (resultCode != ConnectionResult.SUCCESS) {
        // 提示用户更新/安装Google Play Services
        GoogleApiAvailability.getInstance().getErrorDialog(activity, resultCode, 9000).show();
    } else {
        // 正常初始化Firebase Messaging
        FirebaseMessaging.getInstance().getToken().addOnCompleteListener(task -> {
            if (task.isSuccessful()) {
                String token = task.getResult();
                // 把token上传到你的服务器
            }
        });
    }
    
  • 绕开厂商的后台杀进程
    很多国产手机(小米、华为、OPPO等)会把非白名单应用的后台服务直接干掉,你得引导用户把应用加入电池优化白名单:

    1. 检测是否被电池优化:
      PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
      boolean isIgnoringBatteryOptimizations = pm.isIgnoringBatteryOptimizations(getPackageName());
      if (!isIgnoringBatteryOptimizations) {
          // 跳转电池优化设置页面
          Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
          intent.setData(Uri.parse("package:" + getPackageName()));
          startActivity(intent);
      }
      
    2. 最好在应用设置里加个引导说明,告诉用户怎么操作不同品牌的手机(比如小米的“自启动管理”、华为的“后台启动权限”)。
  • 确保通知权限到位
    Android 13(API 33)及以上必须动态申请POST_NOTIFICATIONS权限,不然通知根本发不出来:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
            ActivityResultContracts.RequestPermission requestPermission = new ActivityResultContracts.RequestPermission();
            registerForActivityResult(requestPermission, isGranted -> {
                if (!isGranted) {
                    // 提示用户开启通知权限
                }
            }).launch(Manifest.permission.POST_NOTIFICATIONS);
        }
    }
    
  • 检查网络与Token有效性

    • 确保设备有稳定的网络(后台推送需要长连接,弱网或代理可能会断)
    • 定期刷新Firebase Token,因为Token可能会过期或变更,在FirebaseMessagingService的onNewToken方法里更新服务器上的Token。

二、实现通知到达时播放自定义闹钟铃声

要让通知播放自定义闹钟铃声,得分Android版本处理,核心是给通知设置正确的音频属性:

1. 准备铃声文件

把你的自定义闹钟铃声(比如custom_alarm.mp3)放到res/raw目录下;如果是本地存储的铃声,需要处理读取权限(Android 10+用MediaStore,低版本用READ_EXTERNAL_STORAGE)。

2. 针对Android 8.0+(API 26+):通过NotificationChannel设置

Android 8.0之后必须用通知渠道,所以要先创建渠道并设置声音:

// 定义渠道ID和名称
String channelId = "alarm_notification_channel";
String channelName = "Alarm Notifications";

// 创建音频属性,设置为闹钟用途(这样会用闹钟音量播放)
AudioAttributes audioAttributes = new AudioAttributes.Builder()
        .setUsage(AudioAttributes.USAGE_ALARM)
        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
        .build();

// 构建通知渠道
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
channel.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.custom_alarm), audioAttributes);
channel.setVibrationPattern(new long[]{0, 1000, 500, 1000}); // 可选,设置震动

// 注册渠道到系统
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);

3. 构建通知时关联渠道

创建通知的时候,指定刚才的渠道ID,这样通知就会用渠道设置的铃声:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle("闹钟通知")
        .setContentText("该起床啦!")
        .setPriority(NotificationCompat.PRIORITY_HIGH);

// 发送通知
notificationManager.notify(1, builder.build());

4. 低版本Android(API <26)直接设置声音

如果要兼容低版本,直接在NotificationCompat.Builder里调用setSound():

Uri soundUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.custom_alarm);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle("闹钟通知")
        .setContentText("该起床啦!")
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setSound(soundUri, AudioManager.STREAM_ALARM); // 指定用闹钟流播放

注意事项

  • 确保铃声格式是系统支持的(MP3、WAV、OGG等)
  • 如果要让铃声重复播放,可能需要配合MediaPlayer在通知点击或接收时手动播放,因为系统通知的铃声默认只播放一次。

内容的提问来源于stack exchange,提问作者Gagandeep

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:41:02