Android导出APK推送通知失效问题排查求助
我之前碰到过几乎一模一样的问题,核心原因是Debug和Release环境的配置差异,导致Geofence事件无法正常触发或通知无法显示。咱们一步步排查解决:
1. 最可能的原因:Google Cloud Console未配置Release签名的SHA-1
Geofencing依赖Google Play Services,而Google会验证应用的签名SHA-1。你用Android Studio直接安装的Debug版用的是默认debug keystore,对应的SHA-1应该已经在Google Cloud Console配置过了;但导出的Release APK用的是正式签名,SHA-1未配置,导致Geofence无法注册或触发。
解决步骤:
- 获取Release签名的SHA-1:执行以下命令(替换你的keystore路径和别名):
keytool -list -v -keystore your-release-keystore.jks -alias your-release-alias - 登录Google Cloud Console,找到你的项目,进入APIs & Services -> Credentials,在对应的Android API密钥里添加这个Release SHA-1。
- 下载最新的
google-services.json文件,替换项目里的旧文件,重新打包Release APK。
2. 检查权限配置(尤其是后台定位权限)
Debug环境下部分权限可能被默认放行,但Release版需要严格的权限声明和动态申请:
第一步:在AndroidManifest.xml中添加权限
<!-- 定位核心权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 10+ 后台定位权限(Geofence必须) --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <!-- 可选:开机后重新注册Geofence --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
第二步:运行时动态申请权限
在启动Geofence的Activity里,添加权限申请逻辑:
private static final int REQUEST_LOCATION_PERMISSIONS = 1001; private void requestLocationPermissions() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> { boolean fineGranted = result.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false); boolean backgroundGranted = result.getOrDefault(Manifest.permission.ACCESS_BACKGROUND_LOCATION, false); if (fineGranted && backgroundGranted) { // 权限已获取,注册Geofence registerGeofences(); } else { Toast.makeText(this, "需要定位权限才能使用Geofence功能", Toast.LENGTH_LONG).show(); } }); launcher.launch(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION}); } else { // 权限已存在,直接注册Geofence registerGeofences(); } }
3. 修复Notification Channel的ID问题
你的NotificationHelper中,CHANNEL_ID拼接了带空格的CHANNEL_NAME:
private String CHANNEL_ID = "com.example.notifications" + CHANNEL_NAME; // 结果是"com.example.notificationsHigh priority channel",包含空格
虽然Android允许带空格的Channel ID,但部分设备的Release环境可能无法识别,导致通知通道创建失败,无法显示通知。
修改为规范的无空格ID:
private String CHANNEL_NAME = "High priority channel"; private String CHANNEL_ID = "com.example.geofence_notifications_high"; // 无空格,统一命名
4. 适配Android 12+的PendingIntent Flag
Android 12(API 31)及以上要求PendingIntent必须指定FLAG_IMMUTABLE或FLAG_MUTABLE,否则会抛出异常。你的代码中使用的FLAG_UPDATE_CURRENT在高版本系统的Release环境下可能失效。
修改sendHighPriorityNotification中的PendingIntent创建:
public void sendHighPriorityNotification(String title, String body, Class activityName) { Intent intent = new Intent(this, activityName); int flags; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12+ 必须指定IMMUTABLE或MUTABLE flags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE; } else { flags = PendingIntent.FLAG_UPDATE_CURRENT; } PendingIntent pendingIntent = PendingIntent.getActivity(this, 267, intent, flags); // 后续代码保持不变... }
5. 检查厂商后台限制
国内部分厂商(小米、华为、OPPO等)对Release版应用有严格的后台管控,即使权限齐全,也可能阻止GeofenceBroadcastReceiver触发。
手动设置白名单:
- 进入手机设置 -> 应用管理 -> 你的应用 -> 电池优化 -> 设置为不优化
- 开启允许后台活动权限
- 部分厂商需要开启自启动权限
6. 验证Geofence注册状态
在Release版中添加日志,确认Geofence是否成功注册:
GeofencingClient geofencingClient = LocationServices.getGeofencingClient(this); geofencingClient.addGeofences(geofencingRequest, getGeofencePendingIntent()) .addOnSuccessListener(this, unused -> Log.d(TAG, "Geofence注册成功")) .addOnFailureListener(this, e -> Log.e(TAG, "Geofence注册失败:" + e.getMessage()));
按以上步骤排查后,Release APK的Geofence推送应该就能正常工作了!
内容的提问来源于stack exchange,提问作者KerryKilian

