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等)会把非白名单应用的后台服务直接干掉,你得引导用户把应用加入电池优化白名单:- 检测是否被电池优化:
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); } - 最好在应用设置里加个引导说明,告诉用户怎么操作不同品牌的手机(比如小米的“自启动管理”、华为的“后台启动权限”)。
- 检测是否被电池优化:
确保通知权限到位
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
相关产品推荐
相关产品推荐

