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();
    }
}
相关推荐
熊的猫30 分钟前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
瑶琴AI前端1 小时前
uniapp组件实现省市区三级联动选择
java·前端·uni-app
会发光的猪。1 小时前
如何在vscode中安装git详细新手教程
前端·ide·git·vscode
我要洋人死2 小时前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人2 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人2 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR2 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香3 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596933 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai3 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书