概述
jpush-react-native 是極光推送官方開發的 React Native 版本外掛,可以快速整合推送功能。現在最新版本的 JPush SDK 分離了 JPush 及 JCore,讓開發者可以分開整合 JMessage 及 JPush(以前 JMessage 包含了 JPush)。下面就來具體說一下如何快速整合以及使用 jpush-react-native 外掛。
安裝
開啟終端,進入專案資料夾,執行以下命令:
npm install jcore-react-native --save npm install jpush-react-native --save npm run configureJPush <yourAppKey> <yourModuleName> //module name 指的是你 Android 專案中的模組名字(對 iOS 沒有影響,不填寫的話預設值為 app,會影響到查詢 AndroidManifest 問題, //如果沒找到 AndroidManifest,則需要手動修改,參考下面的 AndroidManifest 配置相關說明) //舉個例子: npm run configureJPush d4ee2375846bc30fa51334f5 app react-native link
執行完 link 專案後可能會出現報錯,這沒關係,需要手動配置一下 build.gradle 檔案。在 Android Studio 中開啟你的專案,然後找到 app 或者你自己定義的需要整合 jpush-react-native 的模組,開啟此模組下的 build.gradle 檔案,做以下改動:
app/build.gradle
android { ... defaultConfig { applicationId "com.pushdemo" // 此處改成你在極光官網上申請應用時填寫的包名 ... manifestPlaceholders = [ JPUSH_APPKEY: "d4ee2375846bc30fa51334f5", //在此替換你的APPKey APP_CHANNEL: "developer-default" //應用渠道號 ] } }
檢查一下在 dependencies 中有沒有加入 jpush-react-native 以及 jcore-react-native 這兩個依賴,如果沒有,則需要加上:
dependencies { ... compile project(':jpush-react-native') compile project(':jcore-react-native') ... }
接下來開啟專案的 settings.gradle,看看有沒有包含 jpush-react-native 以及 jcore-react-native,如果沒有,則需要加上:
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')
做完以上步驟,這時可以同步(sync)一下專案,然後應該可以看到 jpush-react-native 以及 jcore-react-native 作為 Library 專案導進來了。
將react native專案匯入android studio方法: File-->New-->Import Project-->選擇react native專案下的android
接下來開啟模組的 MainApplication.java 檔案,加入 JPushPackage:
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) ); } };
然後在 MainActivity 中加入一些初始化程式碼即可:
app/src.../MainActivity.java
import android.os.Bundle; import cn.jpush.android.api.JPushInterface; 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 了。
使用
收到推送
新增了此事件後,在收到推送時將會觸發此事件。
example/react-native-android/push_activity.js
... import JPushModule from 'jpush-react-native'; ... export default class PushActivity extends React.Component { componentDidMount() { 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); }); }
高階應用
修改 JPushModule 中收到點選通知的事件,可以自定義使用者點選通知後跳轉的介面(現在預設是直接啟動應用),只需要修改一點點原生的程式碼:
jpush-react-native/src.../JPushModule.java
public static class JPushReceiver extends BroadcastReceiver { public JPushReceiver() { HeadlessJsTaskService.acquireWakeLockNow(mRAC); } @Override public void onReceive(Context context, Intent data) { ... } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(data.getAction())) { Logger.d(TAG, "使用者點選開啟了通知"); Intent intent = new Intent(); intent.setClassName(context.getPackageName(), context.getPackageName() + ".MainActivity"); intent.putExtras(bundle); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); // 如果需要跳轉到指定的介面,那麼需要同時啟動 MainActivity 及指定介面(SecondActivity): // If you need to open appointed Activity, you need to start MainActivity and // appointed Activity at the same time. Intent detailIntent = new Intent(); detailIntent.setClassName(context.getPackageName(), context.getPackageName() + ".SecondActivity"); detailIntent.putExtras(bundle); Intent[] intents = {intent, detailIntent}; // 同時啟動 MainActivity 以及 SecondActivity context.startActivities(intents); // 或者回撥 JS 的某個方法 } } ... @ReactMethod public void finishActivity() { Activity activity = getCurrentActivity(); if (activity != null) { activity.finish(); } }
如果修改了此處跳轉的介面,需要在 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"; } }
然後使用上面返回的字串註冊一個 Component 即可:
example/react-native-android/second.js
'use strict'; import React from 'react'; import ReactNative from 'react-native'; const { AppRegistry, View, Text, TouchableHighlight, StyleSheet, NativeModules, } = ReactNative; var JPushModule = NativeModules.JPushModule; export default class second extends React.Component { constructor(props) { super(props); } onBackPress = () => { let navigator = this.props.navigator; if (navigator != undefined) { this.props.navigator.pop(); } else { console.log("finishing second activity"); JPushModule.finishActivity(); } } onButtonPress = () => { console.log("will jump to setting page"); let navigator = this.props.navigator; if (navigator != undefined) { this.props.navigator.push({ name: "setActivity" }); } else { } } render() { return ( <View> <TouchableHighlight style={styles.backBtn} underlayColor = '#e4083f' activeOpacity = {0.5} onPress = {this.onBackPress}> <Text> Back </Text> </TouchableHighlight> <Text style={styles.welcome}> Welcome ! </Text> <TouchableHighlight underlayColor = '#e4083f' activeOpacity = {0.5} style = {styles.btnStyle} onPress = {this.onButtonPress}> <Text style={styles.btnTextStyle}> Jump To Setting page! </Text> </TouchableHighlight> </View> ); } } var styles = StyleSheet.create({ backBtn: { padding: 10, marginTop: 10, marginLeft: 10, borderWidth: 1, borderColor: '#3e83d7', backgroundColor: '#3e83d7', borderRadius: 8, alignSelf: 'flex-start' }, welcome: { textAlign: 'center', margin: 10, }, btnStyle: { marginTop: 10, borderWidth: 1, borderColor: '#3e83d7', borderRadius: 8, backgroundColor: '#3e83d7', alignSelf: 'center', justifyContent: 'center' }, btnTextStyle: { textAlign: 'center', fontSize: 25, color: '#ffffff' }, }); AppRegistry.registerComponent('SecondActivity', () => second);
這樣就完成了使用者點選通知後的自定義跳轉介面。
接收自定義訊息
在使用者收到自定義訊息後觸發。
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"); }); } }
以上就是外掛提供的主要介面的示例。總的來說,配置和使用都比較簡單,適合開發者快速整合推送功能。