記一次坑爹的ReactNative應用集成推送

公司有個需求,實現純RN應用的接收推送後的界面跳轉,推送使用的是阿里雲推送
坑的地方至少有兩個。
如何知道應用是否已經啓動了呢?
如何將信息發送給RN端呢?
首先第一個問題相對來說還是比較好解決的,用下面的代碼就可以實現。
親測可行

  private boolean _isApplicationRunning(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
            if (processInfo.processName.equals(context.getApplicationContext().getPackageName())) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    for (String d: processInfo.pkgList) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

第二個問題,傳遞的話最好肯定是原生端主動發請求給JS,讓js去處理請求。
想到的是DeviceEventEmitter,但是網上的大多數代碼都是講這個方法嵌套在ReactContextBaseJavaModule的子類中運行的,在外面獲取不到必要的參數
ReactApplicationContext
最後看到一句代碼

  ReactContext reactContext = getReactInstanceManager().getCurrentReactContext();

這句話可以正常返回ReactContext’對象,但是在不合適的時候拿到的對象會是空值。
想到了一個比較蠢的方法,寫一個原生方法,如果react界面已經初始化完成,就發送廣播,MainActivity獲取廣播,在這時在去獲取ReactContext對象,這樣就能獲取到正確的ReactContext對象,並且保證不爲空。

原生方法代碼


import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.sdk.android.push.CloudPushService;
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

/**
 * Created by user on 2017/5/2.
 */

public class AlreadyLoding extends ReactContextBaseJavaModule{
    Context context;
    private static final String TAG = "AlreadyLoding";
    public AlreadyLoding(ReactApplicationContext reactContext) {
        super(reactContext);
        this.context = reactContext;
    }

    @Override
    public String getName() {
        return "alreadyloding";
    }
    /**
     * 當RN端加載完畢發送廣播通知原聲端
     *
     */
    @ReactMethod
    public void haveLoding() {
        Log.e(TAG,"廣播發送成功");
        Intent intent = new Intent();
        intent.setAction("com.alreadyLoding");      //設置Action
        intent.putExtra("msg", "接收動態註冊廣播成功!");      //添加附加信息
        context.sendBroadcast(intent);
    }
}

MainActivity界面



import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import com.cboy.rn.splashscreen.SplashScreen;
import com.facebook.react.ReactActivity;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import javax.annotation.Nullable;

import cn.hlgcb.adtool.modules.push.Push;

public class MainActivity extends ReactActivity {
    ReactContext reactcontext;
    String title = "Login";
    String jumpTo;
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this);  // here
        super.onCreate(savedInstanceState);
        IntentFilter dynamic_filter = new IntentFilter();
        dynamic_filter.addAction("com.alreadyLoding");            //添加動態廣播的Action
        registerReceiver(myReceiver, dynamic_filter);             // 註冊自定義動態廣播消息
        Intent intent = getIntent();                               //接受廣播傳入的信息
        if(intent!=null){
            jumpTo=intent.getStringExtra("extraMap");
        }
    }
    @Override
    protected void onResume() {
        super.onResume();
    }

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "wanghongADToolTrunk";
    }

    public static void sendEvent(ReactContext reactContext, String eventName, String params) {
        System.out.println("reactContext=" + reactContext);
        Log.e("aaaa", "我執行了");
        reactContext
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);
    }

    /**
     *
     * 廣播
     * 如果收到已經加載完成的信息並且收到了推送信息就跳轉
     */
    private BroadcastReceiver myReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("com.alreadyLoding")) {    //動作檢測
                String msg = intent.getStringExtra("msg");
                ReactContext reactContext = getReactInstanceManager().getCurrentReactContext();
                if(jumpTo!=null){
                    sendEvent(reactContext, "push", jumpTo);
                }

            }

        }
    };
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章