在Android上接收推送通知时,应用程序崩溃

时间:2018-01-25 15:48:19

标签: java android react-native

我正在使用React Native为Android和iOS开发一个应用程序,我在这里使用react-native-fcm:https://github.com/evollu/react-native-fcm,但由于某些原因,应用程序崩溃时接收推送通知时应用程序崩溃前景状态/开放! 当app关闭时,它可以在后台运行!

清单文件如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest package="ap.iue.a"
    xmlns:android="http://schemas.android.com/apk/res/android">

  <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
  <uses-permission android:name="com.example.healthgps.permission.MAPS_RECEIVE" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  <uses-permission android:name="android.permission.VIBRATE" />
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


  <uses-feature android:name="android.hardware.location.gps" />

  <application
      android:name=".MainApplication"
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:supportsRtl="true">
    <activity android:name=".MainActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:theme="@style/Theme.Exponent.Light"
        android:windowSoftInputMode="adjustResize"
        android:launchMode="singleTop">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>

      <intent-filter>
        <data android:scheme="exp6a747c4f7f604b89a93d9f3d281cbb77"/>

        <action android:name="android.intent.action.VIEW"/>

        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
      </intent-filter>
    </activity>

    <service android:name="com.evollu.react.fcm.MessagingService" android:enabled="true" android:exported="true">
           <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
           </intent-filter>
         </service>

       <service android:name="com.evollu.react.fcm.InstanceIdService" android:exported="false">
         <intent-filter>
           <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
         </intent-filter>
       </service>

    <!-- The Facebook SDK runs FacebookInitProvider on startup and crashes if there isn't an ID here -->
    <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb0"/>
    <!-- react-native-background-geolocation licence -->
    <meta-data android:name="com.transistorsoft.locationmanager.license" android:value="14ef777231a8412c8b2d109443999356a2c13e62c07e2868345f5e13f01b3c83" />


    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@mipmap/ic_launcher"/>
    <receiver android:name="com.evollu.react.fcm.FIRLocalMessagingPublisher"/>
    <receiver android:enabled="true" android:exported="true"  android:name="com.evollu.react.fcm.FIRSystemBootEventReceiver">
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
        <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
    </receiver>

  </application>

</manifest>

MainApplication.java

  public List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        // TODO: add cool native modules
            new RNBackgroundGeolocation(),
            new FIRMessagingPackage(),
            new VectorIconsPackage()
    );
  }

React Native app:

 componentDidMount() {
    // iOS: show permission prompt for the first call. later just check permission in user settings
    // Android: check permission in user settings
    FCM.requestPermissions().then(()=>console.log('granted')).catch(()=>console.log('notification permission rejected'));

    FCM.getFCMToken().then(token => {
        console.log(token)
        // store fcm token in your server
    });

    this.notificationListener = FCM.on(FCMEvent.Notification, async (notif) => {
        // optional, do some component related stuff
    });

    // initial notification contains the notification that launchs the app. If user launchs app by clicking banner, the banner notification info will be here rather than through FCM.on event
    // sometimes Android kills activity when app goes to background, and when resume it broadcasts notification before JS is run. You can use FCM.getInitialNotification() to capture those missed events.
    // initial notification will be triggered all the time even when open app by icon so send some action identifier when you send notification
    FCM.getInitialNotification().then(notif => {
       console.log(notif)
    });
}

componentWillUnmount() {
    // stop listening for events
    this.notificationListener.remove();
}
import FCM, {FCMEvent, RemoteNotificationResult, WillPresentNotificationResult, NotificationType} from 'react-native-fcm';

// this shall be called regardless of app state: running, background or not running. Won't be called when app is killed by user in iOS
FCM.on(FCMEvent.Notification, async (notif) => {
    // there are two parts of notif. notif.notification contains the notification payload, notif.data contains data payload
    if(notif.local_notification){
      //this is a local notification
    }
    if(notif.opened_from_tray){
      //iOS: app is open/resumed because user clicked banner
      //Android: app is open/resumed because user clicked banner or tapped app icon
    }
    // await someAsyncCall();

    if(Platform.OS ==='ios'){
      //optional
      //iOS requires developers to call completionHandler to end notification process. If you do not call it your background remote notifications could be throttled, to read more about it see https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application.
      //This library handles it for you automatically with default behavior (for remote notification, finish with NoData; for WillPresent, finish depend on "show_in_foreground"). However if you want to return different result, follow the following code to override
      //notif._notificationType is available for iOS platfrom
      switch(notif._notificationType){
        case NotificationType.Remote:
          notif.finish(RemoteNotificationResult.NewData) //other types available: RemoteNotificationResult.NewData, RemoteNotificationResult.ResultFailed
          break;
        case NotificationType.NotificationResponse:
          notif.finish();
          break;
        case NotificationType.WillPresent:
          notif.finish(WillPresentNotificationResult.All) //other types available: WillPresentNotificationResult.None
          break;
      }
    }
});
FCM.on(FCMEvent.RefreshToken, (token) => {
    console.log(token)
    // fcm token may not be available on first load, catch it here
});

0 个答案:

没有答案