概述
jpush-react-native 是极光推送官方开发的 React Native 版本插件,可以快速集成推送功能(Github 项目中包含了 example,文中提到的 demo 来源于此)。现在最新版本的 JPush SDK 分离了 JPush 及 JCore,让开发者可以分开集成 JMessage 及 JPush(以前 JMessage 包含了 JPush)。下面就来具体说一下如何快速集成以及使用 jpush-react-native 插件。
安装
npm install jpush-react-native --save
npm install jcore-react-native --save ## jpush-react-native 1.4.2 版本以后需要同时安装 jcore-react-native
配置
配置包括两个步骤,自动配置和手动操作。
一、自动配置部分(以下命令均在你的 React Native Project 目录下运行,自动配置后仍需手动配置一部分)
- 执行脚本
npm run configureJPush <yourAppKey> <yourModuleName>
//module name 指的是你 Android 项目中的模块名字(对 iOS 没有影响,不填写的话默认值为 app,会影响到查找 AndroidManifest 问题,
//如果没找到 AndroidManifest,则需要手动修改,参考下面的 AndroidManifest 配置相关说明)
//举个例子:
npm run configureJPush d4ee2375846bc30fa51334f5 app
- Link 项目
//执行自动配置脚本后再执行 link 操作
react-native link
二、手动操作部分 (3个步骤)
- 第一步:修改 app 下的 build.gradle 配置:
your react native project/android/app/build.gradle
android {
defaultConfig {
applicationId "yourApplicationId"
...
manifestPlaceholders = [
JPUSH_APPKEY: "yourAppKey", //在此替换你的APPKey
APP_CHANNEL: "developer-default" //应用渠道号
]
}
}
...
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile project(':jpush-react-native') // 添加 jpush 依赖
compile project(':jcore-react-native') // 添加 jcore 依赖
compile "com.facebook.react:react-native:+" // From node_modules
}
将此处的 yourApplicationId 替换为你的项目的包名;yourAppKey 替换成你在官网上申请的应用的 AppKey。
- 第二步:检查是否导入以下配置项:
i. 检查一下 dependencies 中有没有添加 jpush-react-native 及 jcore-react-native 这两个依赖。
your react native project/android/app/build.gradle
...
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile project(':jpush-react-native') // 添加 jpush 依赖
compile project(':jcore-react-native') // 添加 jcore 依赖
compile "com.facebook.react:react-native:+" // From node_modules
}
ii. 检查 android 项目下的 settings.gradle 配置有没有包含以下内容:
settings.gradle
include ':app', ':jpush-react-native', ':jcore-react-native'
project(':jpush-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/jpush-react-native/android')
project(':jcore-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/jcore-react-native/android')
iii. 检查一下 app 下的 AndroidManifest 配置,有没有增加 <meta-data> 部分。
your react native project/android/app/AndroidManifest.xml
<application
...
<!-- Required . Enable it you can get statistics data with channel -->
<meta-data android:name="JPUSH_CHANNEL" android:value="${APP_CHANNEL}"/>
<meta-data android:name="JPUSH_APPKEY" android:value="${JPUSH_APPKEY}"/>
</application>
iiii. 现在重新 sync 一下项目(点击 Android Studio sync 按钮),应该能看到 jpush-react-native 以及 jcore-react-native 作为 android Library 项目导进来了。
- 第三步:加入 JPushPackage (找到 app 下的 MainApplication.java):
app/src.../MainApplication.java
private boolean SHUTDOWN_TOAST = false;
private boolean SHUTDOWN_LOG = false;
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
//加入 JPushPackage
new JPushPackage(SHUTDOWN_TOAST, SHUTDOWN_LOG)
);
}
};
上面 JPushPackage 的两个参数是 bool 类型的,第一个参数设置为 true 表示关闭 toast 提示,第二个设置为 true 表示关闭日志打印,建议在 debug 版本中打开。然后在 MainActivity 中加入一些初始化代码即可:
app/src.../MainActivity.java
public class MainActivity extends ReactActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
JPushInterface.init(this);
}
@Override
protected void onPause() {
super.onPause();
JPushInterface.onPause(this);
}
@Override
protected void onResume() {
super.onResume();
JPushInterface.onResume(this);
}
}
这样就完成了所有的配置。接下来就可以在 JS 中调用插件提供的 API 了。
使用
收到推送
添加了此事件后,在收到推送时将会触发此事件。
需要注意的是,v1.6.6 版本以后,增加了 notifyJSDidLoad 方法,在监听所有相关事件之前要调用此方法,否则不会收到点击通知事件。
example/react-native-android/push_activity.js
...
import JPushModule from 'jpush-react-native';
...
export default class PushActivity extends React.Component {
componentDidMount() {
// 在收到点击事件之前调用此接口
JPushModule.notifyJSDidLoad((resultCode) => {
if (resultCode === 0) {
}
});
JPushModule.addReceiveNotificationListener((map) => {
console.log("alertContent: " + map.alertContent);
console.log("extras: " + map.extras);
// var extra = JSON.parse(map.extras);
// console.log(extra.key + ": " + extra.value);
});
}
点击通知
在用户点击通知后,将会触发此事件。
...
componentDidMount() {
JPushModule.addReceiveOpenNotificationListener((map) => {
console.log("Opening notification!");
console.log("map.extra: " + map.key);
});
}
高级应用
点击通知跳转到指定界面
第一种方式 使用 react-navigation
如果使用 react-navigation,直接可以在 JS 中实现跳转,而不必添加 ReactActivity。
安装 react-navigation:
npm install react-navigation --save
在 index.js(或者 index.android.js, rn 0.5.0 后入口改为 index.js)中:
import {
StackNavigator
} from 'react-navigation';
import JPushModule from 'jpush-react-native';
const PushDemoApp = StackNavigator({
Home: {
screen: PushActivity
},
Setting: {
screen: SetActivity
},
Push: {
screen: SecondActivity
}
})
AppRegistry.registerComponent('PushDemoApp', () => PushDemoApp);
上面定义了三个界面,在点击通知的跳转事件中即可选择跳转到哪个界面(本例中为 Push)。监听点击通知事件:
JPushModule.addReceiveOpenNotificationListener((map) => {
//console.log("Opening notification!");
//console.log("map.extra: " + map.extras);
// 跳转到 Push 界面
this.props.navigation.navigate("Push");
});
第二种方式 使用 ReactActivity
需要在 Native 中声明一个 Activity,如 demo 中的 SecondActivity,而 SecondActivity 的界面仍然用 JS 来渲染。只需要改动一下 SecondActivity,让它继承自 ReactActivity 即可:
example/android/app/src.../SecondActivity.java
public class SecondActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "SecondActivity";
}
}
声明完成后,需要在 AndroidManifest 中声明一下(必要的时候可以声明 Activity 的启动模式,以更好地适配自己的需求)。
AndroidManifest.xml
...
<application>
...
<activity android:name=".SecondActivity"/>
</application>
然后使用 SecondActivity 中返回的字符串 “SecondActivity” 注册一个 Component 即可:
example/react-native-android/second.js
import React from 'react';
import ReactNative from 'react-native';
const {
AppRegistry,
Text,
} = ReactNative;
export default class second extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Text> Welcome ! </Text>
);
}
}
AppRegistry.registerComponent('SecondActivity', () => second);
最后监听点击通知事件,并完成跳转:
JPushModule.addReceiveOpenNotificationListener((map) => {
console.log("Opening notification!");
console.log("map.extra: " + map.extras);
JPushModule.jumpToPushActivity("SecondActivity");
});
这样就完成了用户点击通知后的自定义跳转界面。
接收自定义消息
在用户收到自定义消息后触发。
example/react-native-android/push_activity.js
...
componentDidMount() {
JPushModule.addReceiveCustomMsgListener((map) => {
this.setState({
pushMsg: map.message
});
console.log("extras: " + map.extras);
});
...
得到 RegistrationId
用户注册成功后(一般在用户启动应用后),如果订阅了这个事件,将会收到这个 registrationId。
...
componentDidMount() {
JPushModule.addGetRegistrationIdListener((registrationId) => {
console.log("Device register succeed, registrationId " + registrationId);
});
}
清除所有通知
建议在用户退出前台后调用。
...
componentWillUnmount() {
console.log("Will clear all notifications");
JPushModule.clearAllNotifications();
}
设置标签
example/react-native-android/set_activity.js
...
setTag() {
if (this.state.tag !== undefined) {
/*
* 请注意这个接口要传一个数组过去,这里只是个简单的示范
*/
JPushModule.setTags(["VIP", "NOTVIP"], () => {
console.log("Set tag succeed");
}, () => {
console.log("Set tag failed");
});
}
}
设置别名
...
setAlias() {
if (this.state.alias !== undefined) {
JPushModule.setAlias(this.state.alias, () => {
console.log("Set alias succeed");
}, () => {
console.log("Set alias failed");
});
}
}
以上就是插件提供的主要接口的示例。总的来说,配置和使用都比较简单,适合开发者快速集成推送功能。
网友评论
在官方的rn Demo里面 点击物理返回键退出app,接收到推送消息,点击消息,并没有跳转到指定页面(Demo中的SecondActivity)给了一个警告:
warn: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op. Please check the code for the Navigation Container component.
如果不退出app是正常的
请指教
JPushModule.addGetRegistrationIdListener((registretionId) =>{
alert("Device register succeed, registrationId " + registrationId)
});
看看这个方法有没有调用
我在设置点击通知跳转的时候,出现了这个问题。来回对比官方Demo和自己的代码几遍,发现还是这个问题。我在设置那里加了一个SecondActivity,然后用Intent[],把Main的和Second的都传过去,通过日志发现Android那里并没有问题。但是转到Rn里面却是这个错误。我用的dva的router框架,在路由列表里面也注册了,不知道是什么问题。
楼主能看懂我的描述吗?求帮忙~