概述
jpush-react-native是极光推送官方开发的 React Native 版本插件,可以快速集成推送功能。现在最新版本的 JPush SDK 分离了 JPush 及 JCore,让开发者可以分开集成 JMessage 及 JPush(以前 JMessage 包含了 JPush)。下面就来具体说一下如何快速集成以及使用 jpush-react-native 插件。
安装
打开终端,进入项目文件夹,执行以下命令:
npminstalljcore-react-native--save npminstalljpush-react-native--save npmrunconfigureJPush<yourAppKey><yourModuleName> //modulename指的是你Android项目中的模块名字(对iOS没有影响,不填写的话默认值为app,会影响到查找AndroidManifest问题, //如果没找到AndroidManifest,则需要手动修改,参考下面的AndroidManifest配置相关说明) //举个例子: npmrunconfigureJPushd4ee2375846bc30fa51334f5app react-nativelink
执行完 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{ ... compileproject(':jpush-react-native') compileproject(':jcore-react-native') ... }
接下来打开项目的 settings.gradle,看看有没有包含 jpush-react-native 以及 jcore-react-native,如果没有,则需要加上:
include':app',':jpush-react-native',':jcore-react-native' project(':jpush-react-native').projectDir=newFile(rootProject.projectDir,'../node_modules/jpush-react-native/android') project(':jcore-react-native').projectDir=newFile(rootProject.projectDir,'../node_modules/jcore-react-native/android')
做完以上步骤,这时可以同步(sync)一下项目,然后应该可以看到 jpush-react-native 以及 jcore-react-native 作为 Library 项目导进来了。
将react native项目导入android studio方法: File-->New-->Import Project-->选择reactnative项目下的android
接下来打开模块的 MainApplication.java 文件,加入 JPushPackage:
app/src.../MainApplication.java
privatebooleanSHUTDOWN_TOAST=false; privatebooleanSHUTDOWN_LOG=false; privatefinalReactNativeHostmReactNativeHost=newReactNativeHost(this){ @Override protectedbooleangetUseDeveloperSupport(){ returnBuildConfig.DEBUG; } @Override protectedList<ReactPackage>getPackages(){ returnArrays.<ReactPackage>asList( newMainReactPackage(),//加入JPushPackage newJPushPackage(SHUTDOWN_TOAST,SHUTDOWN_LOG) ); } };
然后在 MainActivity 中加入一些初始化代码即可:
app/src.../MainActivity.java
importandroid.os.Bundle; importcn.jpush.android.api.JPushInterface; publicclassMainActivityextendsReactActivity{ ... @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); JPushInterface.init(this); } @Override protectedvoidonPause(){ super.onPause(); JPushInterface.onPause(this); } @Override protectedvoidonResume(){ super.onResume(); JPushInterface.onResume(this); } }
这样就完成了所有的配置。接下来就可以在 JS 中调用插件提供的 API 了。
使用
收到推送
添加了此事件后,在收到推送时将会触发此事件。
example/react-native-android/push_activity.js
... importJPushModulefrom'jpush-react-native'; ... exportdefaultclassPushActivityextendsReact.Component{ componentDidMount(){ JPushModule.addReceiveNotificationListener((map)=>{ console.log("alertContent:"+map.alertContent); console.log("extras:"+map.extras); //varextra=JSON.parse(map.extras); //console.log(extra.key+":"+extra.value); }); }
点击推送
... componentDidMount(){ JPushModule.addReceiveOpenNotificationListener((map)=>{ console.log("openingnotification!"); console.log("map.extra:"+map.key); }); }
高级应用
修改 JPushModule 中收到点击通知的事件,可以自定义用户点击通知后跳转的界面(现在默认是直接启动应用),只需要修改一点点原生的代码:
jpush-react-native/src.../JPushModule.java
publicstaticclassJPushReceiverextendsBroadcastReceiver{ publicJPushReceiver(){ HeadlessJsTaskService.acquireWakeLockNow(mRAC); } @Override publicvoidonReceive(Contextcontext,Intentdata){ ... }elseif(JPushInterface.ACTION_NOTIFICATION_OPENED.equals(data.getAction())){ Logger.d(TAG,"用户点击打开了通知"); Intentintent=newIntent(); intent.setClassName(context.getPackageName(),context.getPackageName()+".MainActivity"); intent.putExtras(bundle); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); //如果需要跳转到指定的界面,那么需要同时启动MainActivity及指定界面(SecondActivity): //IfyouneedtoopenappointedActivity,youneedtostartMainActivityand //appointedActivityatthesametime. IntentdetailIntent=newIntent(); detailIntent.setClassName(context.getPackageName(),context.getPackageName()+".SecondActivity"); detailIntent.putExtras(bundle); Intent[]intents={intent,detailIntent}; //同时启动MainActivity以及SecondActivity context.startActivities(intents); //或者回调JS的某个方法 } } ... @ReactMethod publicvoidfinishActivity(){ Activityactivity=getCurrentActivity(); if(activity!=null){ activity.finish(); } }
如果修改了此处跳转的界面,需要在 Native 中声明一个 Activity,如 demo 中的 SecondActivity,而 SecondActivity 的界面仍然用 JS 来渲染。只需要改动一下 SecondActivity,让它继承自 ReactActivity 即可:
example/android/app/src.../SecondActivity.java
publicclassSecondActivityextendsReactActivity{ @Override protectedStringgetMainComponentName(){ return"SecondActivity"; } }
然后使用上面返回的字符串注册一个 Component 即可:
example/react-native-android/second.js
'usestrict'; importReactfrom'react'; importReactNativefrom'react-native'; const{ AppRegistry,View,Text,TouchableHighlight,StyleSheet,NativeModules,}=ReactNative; varJPushModule=NativeModules.JPushModule; exportdefaultclasssecondextendsReact.Component{ constructor(props){ super(props); } onBackPress=()=>{ letnavigator=this.props.navigator; if(navigator!=undefined){ this.props.navigator.pop(); }else{ console.log("finishingsecondactivity"); JPushModule.finishActivity(); } } onButtonPress=()=>{ console.log("willjumptosettingpage"); letnavigator=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> <TouchableHighlightunderlayColor='#e4083f' activeOpacity={0.5} style={styles.btnStyle} onPress={this.onButtonPress}> <Textstyle={styles.btnTextStyle}> JumpToSettingpage! </Text> </TouchableHighlight> </View> ); } } varstyles=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,alignSelf:'center',justifyContent:'center' },btnTextStyle:{ textAlign:'center',fontSize:25,color:'#ffffff' },}); AppRegistry.registerComponent('SecondActivity',()=>second);
接收自定义消息
... componentDidMount(){ JPushModule.addReceiveCustomMsgListener((map)=>{ this.setState({ pushMsg:map.message }); console.log("extras:"+map.extras); }); ...得到 RegistrationId
用户注册成功后(一般在用户启动应用后),如果订阅了这个事件,将会收到这个 registrationId。
... componentDidMount(){ JPushModule.addGetRegistrationIdListener((registrationId)=>{ console.log("Deviceregistersucceed,registrationId"+registrationId); }); }清除所有通知
... componentWillUnmount(){ console.log("Willclearallnotifications"); JPushModule.clearAllNotifications(); }设置标签
example/react-native-android/set_activity.js
... setTag(){ if(this.state.tag!==undefined){ /* *请注意这个接口要传一个数组过去,这里只是个简单的示范 */ JPushModule.setTags(["VIP","NOTVIP"],()=>{ console.log("Settagsucceed"); },()=>{ console.log("SettagFailed"); }); } }设置别名
... setAlias(){ if(this.state.alias!==undefined){ JPushModule.setAlias(this.state.alias,()=>{ console.log("Setaliassucceed"); },()=>{ console.log("SetaliasFailed"); }); } }