android 13 解决无法推送问题(notifications 相关)

最近,接手的 app (react native 技术栈) 需要添加一些关于推送的流程,根据后端返回的 json 到达对应的页面,这个也不难,根据旧代码添加相应的流程就行了。加上,让 qa 人员测试,发现 android 13 无法推送。以下是总结的解决思路

添加权限

在 AndroidManifest.xml 加上 POST_NOTIFICATIONS 权限

xml 复制代码
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

请求权限

在上面我们添加了通知权限,但默认是关闭的,需要用户长按 app 的图标到应用程序信息那手动把通知权限打开,这肯定是不现实的,因此得主动请求,并让用户选择是否给予通知权限

既然是用 react naitve,那就用 js 代码请求好了,由于只有在安卓13需要用到,因此需要判断系统和版本

javascript 复制代码
import React, {Component} from 'react';
import {
  Platform,
  PermissionsAndroid,
} from 'react-native';

export default class App extends Component {

  componentDidMount() {
    if (Platform.OS === 'android' && Platform.Version === 13) {
      PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS);
    }
  }

}

但实际上出了问题,PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONSundefined,github 也有相关的 issue,是跟 RN 的版本有关,v0.70.7 版本才解决了这个问题,很显然升级 rn 的代价太大(接手的项目还不支持 function component 和 hook 呢),因此采用原生方法请求

在 MainActivity.java 添加下列代码,其中 requestPermissions 的第二个参数 requestCode 是自定义的,不重复即可,下面我就定义为了 101

java 复制代码
import android.Manifest;
import android.os.Build;

public class MainActivity extends ReactActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // 同样判断 android 版本为 13
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.TIRAMISU) {
            requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, 101);
        }
    }
}

好了,重新编译安装后,打开 app 会出现 "运行 app 向你发送通知吗" 的类似弹窗,如果用户拒绝的话,还是得手动去应用程序信息那里设置,当然,如果用户选择允许的话,我们的问题就解决了。

引导用户打开权限

如果用户选择不允许的话,又有重要的需要推送,就可能需要引导用户去打开权限了,因此我们写个桥接文件,提供两个方法,checkEnablejumpToNotificationsSettingPage,第一个判断权限有没有打开,第二个跳转到设置页面

NotificationsModule.java

java 复制代码
package com.xxxapp;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;

import androidx.annotation.NonNull;
import androidx.core.app.NotificationManagerCompat;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class NotificationsModule extends ReactContextBaseJavaModule {

    private final Context context;

    public NotificationsModule(ReactApplicationContext reactApplicationContext) {
        super(reactApplicationContext);
        context = reactApplicationContext;
    }

    @NonNull
    @Override
    public String getName() {
        return "Notifications";
    }

    @ReactMethod
    public void checkEnable(final Promise promise) {
        promise.resolve(NotificationManagerCompat.from(context).areNotificationsEnabled());
    }

    @ReactMethod
    public void jumpToNotificationsSettingPage() {
        final ApplicationInfo applicationInfo = context.getApplicationInfo();
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
        intent.putExtra("android.provider.extra.APP_PACKAGE", applicationInfo.packageName);
        context.startActivity(intent);
    }

}

NotificationsPackage.java

java 复制代码
package com.xxxapp;

import androidx.annotation.NonNull;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class NotificationsPackage implements ReactPackage {

    @NonNull
    @Override
    public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
        return new ArrayList<>(Collections.singletonList(new NotificationsModule(reactContext)));
    }

    @NonNull
    @Override
    public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}
相关推荐
Rhi63719 分钟前
从零搭建项目:React 19 + Vite 8 + Tailwind CSS v4 实战配置
前端
竹林81826 分钟前
用Viem替代ethers.js:从一次签名失败到完整迁移的实战记录
前端·javascript
之歆31 分钟前
DAY08_CSS浮动与行内块布局实战指南(上)
前端·css
light blue bird1 小时前
主子端台二分法任务汇总组件
前端·数据库·.net·桌面端winform
jeffwang2 小时前
我做了个让 AI 看屏幕跑测试的工具,因为 Playwright 测不了我的 Flutter Web
前端
HSunR2 小时前
dify 搭建ai作业批改流
开发语言·前端·javascript
代码不加糖2 小时前
2026 跨境电商独立站实战:从 0 到 1 搭建高转化 SaaS 商城(附源码)
开发语言·前端·javascript
亲亲小宝宝鸭3 小时前
拖一拖控件,拖出个问卷(低代码平台)
前端·低代码
江南十四行3 小时前
ReAct Agent 基本理论与项目实战(一)
前端·react.js·前端框架
We་ct3 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·leetcode·typescript·动态规划