React Native发送通知
一、使用第三方库做本地/远程消息推送
推荐:https://github.com/zo0r/react-native-push-notification
demo解析:
AndroidManifest.xml:配置基本权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:allowBackup="false" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" /> <receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="${applicationId}" /> </intent-filter> </receiver> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/> <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> </intent-filter> </service> <meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name" android:value="Example-Channel"/> <meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description" android:value="Super channel description"/> <meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@android:color/white"/> </application> <uses-permission android:name="android.permission.WAKE_LOCK" /> <permission android:name="${applicationId}.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> </manifest>
NotifService.js:配置各类推送的消息显示
import PushNotification from 'react-native-push-notification'; export default class NotifService { constructor(onRegister, onNotification) { this.configure(onRegister, onNotification); this.lastId = 0; } configure(onRegister, onNotification, gcm = "") { PushNotification.configure({ // (optional) Called when Token is generated (iOS and Android) onRegister: onRegister, //this._onRegister.bind(this), // (required) Called when a remote or local notification is opened or received onNotification: onNotification, //this._onNotification, // ANDROID ONLY: GCM Sender ID (optional - not required for local notifications, but is need to receive remote push notifications) senderID: gcm, // IOS ONLY (optional): default: all - Permissions to register. permissions: { alert: true, badge: true, sound: true }, // Should the initial notification be popped automatically // default: true popInitialNotification: true, /** * (optional) default: true * - Specified if permissions (ios) and token (android and ios) will requested or not, * - if not, you must call PushNotificationsHandler.requestPermissions() later */ requestPermissions: true, }); } localNotif() { this.lastId++; PushNotification.localNotification({ /* Android Only Properties */ id: ''+this.lastId, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID ticker: "My Notification Ticker", // (optional) autoCancel: true, // (optional) default: true largeIcon: "ic_launcher", // (optional) default: "ic_launcher" smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher" bigText: "My big text that will be shown when notification is expanded", // (optional) default: "message" prop subText: "This is a subText", // (optional) default: none color: "red", // (optional) default: system default vibrate: true, // (optional) default: true vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000 tag: 'some_tag', // (optional) add tag to message group: "group", // (optional) add group to message ongoing: false, // (optional) set whether this is an "ongoing" notification /* iOS only properties */ alertAction: 'view', // (optional) default: view category: null, // (optional) default: null userInfo: null, // (optional) default: null (object containing additional notification data) /* iOS and Android properties */ title: "Local Notification", // (optional) message: "My Notification Message", // (required) playSound: false, // (optional) default: true soundName: 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played) number: '10', // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero) actions: '["Yes", "No"]', // (Android only) See the doc for notification actions to know more }); } scheduleNotif() { this.lastId++; PushNotification.localNotificationSchedule({ date: new Date(Date.now() + (30 * 1000)), // in 30 secs /* Android Only Properties */ id: ''+this.lastId, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID ticker: "My Notification Ticker", // (optional) autoCancel: true, // (optional) default: true largeIcon: "ic_launcher", // (optional) default: "ic_launcher" smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher" bigText: "My big text that will be shown when notification is expanded", // (optional) default: "message" prop subText: "This is a subText", // (optional) default: none color: "blue", // (optional) default: system default vibrate: true, // (optional) default: true vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000 tag: 'some_tag', // (optional) add tag to message group: "group", // (optional) add group to message ongoing: false, // (optional) set whether this is an "ongoing" notification /* iOS only properties */ alertAction: 'view', // (optional) default: view category: null, // (optional) default: null userInfo: null, // (optional) default: null (object containing additional notification data) /* iOS and Android properties */ title: "Scheduled Notification", // (optional) message: "My Notification Message", // (required) playSound: true, // (optional) default: true soundName: 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played) }); } checkPermission(cbk) { return PushNotification.checkPermissions(cbk); } cancelNotif() { PushNotification.cancelLocalNotifications({id: ''+this.lastId}); } cancelAll() { PushNotification.cancelAllLocalNotifications(); } }
App.js:消息显示
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */ import React, { Component } from 'react'; import { TextInput, StyleSheet, Text, View, TouchableOpacity, Alert } from 'react-native'; import NotifService from './NotifService'; import appConfig from './app.json'; type Props = {}; export default class App extends Component<Props> { constructor(props) { super(props); this.state = { senderId: appConfig.senderID }; this.notif = new NotifService(this.onRegister.bind(this), this.onNotif.bind(this)); } render() { return ( <View style={styles.container}> <Text style={styles.title}>Example app react-native-push-notification</Text> <View style={styles.spacer}></View> <TextInput style={styles.textField} value={this.state.registerToken} placeholder="Register token" /> <View style={styles.spacer}></View> <TouchableOpacity style={styles.button} onPress={() => { this.notif.localNotif() }}><Text>Local Notification (now)</Text></TouchableOpacity> <TouchableOpacity style={styles.button} onPress={() => { this.notif.scheduleNotif() }}><Text>Schedule Notification in 30s</Text></TouchableOpacity> <TouchableOpacity style={styles.button} onPress={() => { this.notif.cancelNotif() }}><Text>Cancel last notification (if any)</Text></TouchableOpacity> <TouchableOpacity style={styles.button} onPress={() => { this.notif.cancelAll() }}><Text>Cancel all notifications</Text></TouchableOpacity> <TouchableOpacity style={styles.button} onPress={() => { this.notif.checkPermission(this.handlePerm.bind(this)) }}><Text>Check Permission</Text></TouchableOpacity> <View style={styles.spacer}></View> <TextInput style={styles.textField} value={this.state.senderId} onChangeText={(e) => {this.setState({ senderId: e })}} placeholder="GCM ID" /> <TouchableOpacity style={styles.button} onPress={() => { this.notif.configure(this.onRegister.bind(this), this.onNotif.bind(this), this.state.senderId) }}><Text>Configure Sender ID</Text></TouchableOpacity> {this.state.gcmRegistered && <Text>GCM Configured !</Text>} <View style={styles.spacer}></View> </View> ); } onRegister(token) { Alert.alert("Registered !", JSON.stringify(token)); console.log(token); this.setState({ registerToken: token.token, gcmRegistered: true }); } onNotif(notif) { console.log(notif); Alert.alert(notif.title, notif.message); } handlePerm(perms) { Alert.alert("Permissions", JSON.stringify(perms)); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, button: { borderWidth: 1, borderColor: "#000000", margin: 5, padding: 5, width: "70%", backgroundColor: "#DDDDDD", borderRadius: 5, }, textField: { borderWidth: 1, borderColor: "#AAAAAA", margin: 5, padding: 5, width: "70%" }, spacer: { height: 10, }, title: { fontWeight: "bold", fontSize: 20, textAlign: "center", } });
最终效果:

二、使用极光开发者服务做远程消息推送
1.官网注册极光开发者账号,并创建应用

2.安装
npm install jpush-react-native --save
npm install jcore-react-native --save
3.关联
react-native link jpush-react-native
react-native link jcore-react-native
4.打开 project/android/app/src/main/java/com/项目名/下的 MainApplication.java 文件,然后加入 JPushPackage
import cn.jpush.reactnativejpush.JPushPackage; public class MainApplication extends Application implements ReactApplication { // 设置为 true 将不会弹出 toast private boolean SHUTDOWN_TOAST = false; // 设置为 true 将不会打印 log private boolean SHUTDOWN_LOG = false; private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new JPushPackage(SHUTDOWN_TOAST, SHUTDOWN_LOG) ); }
5.打开 project/android/app/src/main/java/com/项目名/下的MainActivity.java 文件,然后加入 如下代码:
import android.os.Bundle; import com.facebook.react.ReactActivity; 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); } @Override protected void onDestroy() { super.onDestroy(); } }
6.使用
(1)RN工程代码:
import React, { Component } from "react";
import { Dimensions, Text, Platform, Linking, Alert } from "react-native";
import JPushModule from 'jpush-react-native'
const deviceHeight = Dimensions.get('window').height;
export default class Login extends Component {
constructor(props){
super(props);
this.state = {
}
}
componentDidMount() {
/****************************通知 start **************************************************/
if (Platform.OS === 'android') {
JPushModule.initPush()
// 新版本必需写回调函数
JPushModule.notifyJSDidLoad(resultCode => {
if (resultCode === 0) {
}
})
} else {
JPushModule.setupPush()
}
// 接收自定义消息
this.receiveCustomMsgListener = map => {
this.setState({
pushMsg: map.content
})
console.log('extras: ' + map.extras)
}
// 接收自定义消息JPushModule.addReceiveCustomMsgListener(this.receiveCustomMsgListener)
this.receiveNotificationListener = map => {
console.log('alertContent: ' + map.alertContent)
console.log('extras: ' + map.extras)
}
// 接收推送通知
JPushModule.addReceiveNotificationListener(this.receiveNotificationListener)
// 打开通知
this.openNotificationListener = map => {
// console.log('Opening notification!')
// console.log('map.extra: ' + map.extras)
let webUrl= JSON.parse(map.extras).webUrl
let url = webUrl.replace(new RegExp("\/", 'g'), "/")
Linking.canOpenURL(url).then(supported => {
if (!supported) {
Alert.alert('您的系统不支持打开浏览器!')
} else {
return Linking.openURL(url);
}
}).catch(err => { });
}
JPushModule.addReceiveOpenNotificationListener(this.openNotificationListener)
// this.getRegistrationIdListener = registrationId => {
// console.log('Device register succeed, registrationId ' + registrationId)
// }
// JPushModule.addGetRegistrationIdListener(this.getRegistrationIdListener)
/****************************通知 end **************************************************/
}
componentWillUnmount() {
JPushModule.removeReceiveCustomMsgListener(this.receiveCustomMsgListener)
JPushModule.removeReceiveNotificationListener(this.receiveNotificationListener)
JPushModule.removeReceiveOpenNotificationListener(this.openNotificationListener)
// JPushModule.removeGetRegistrationIdListener(this.getRegistrationIdListener)
// console.log('Will clear all notifications')
// JPushModule.clearAllNotifications()
}
render() {
return (
<Text>push notification test</Text>
);
}
}
(2)极光官网推送

7.最终效果

三、APP内消息通知
使用antd组件NoticeBar通告栏:https://rn.mobile.ant.design/components/notice-bar-cn/ 即可
最终效果:


浙公网安备 33010602011771号