记一次坑爹的ReactNative应用集成推送

来源:互联网 发布:tgp优化dnf 编辑:程序博客网 时间:2024/06/04 00:42

公司有个需求,实现纯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);                }            }        }    };}
0 0