如何从 React Native 中的 Java 代码访问 ReactContext?

Eri*_*res 5 java android react-native

我正在尝试创建一个应用程序,它将使用 BroadcastReciver 接听手机的来电。从我的 BroadcastReciver 中,我想使用方法将数字作为事件发送到我的 JS 文件。

我已经检查过我的 Java 代码是否正在工作并且正在捕获调用和号码,但是我的应用程序因提到反应上下文为空的错误而崩溃。我猜这是因为当捕获来自 android 系统的事件并且新实例没有 ReactContext 时,清单(或其他东西)正在创建类的新实例。有没有办法从 Java 代码访问 ReactContext 或通过清单将 ReactContext 发送到 BroadcastReciver?

这是我的 BroadcastReciver:

package com.bridgetest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.JavaScriptModule;


import android.widget.Toast;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;

import javax.annotation.Nullable;

/**
 * Created by Erik on 2016-04-06. 
 */
public class BroadcastReceiverCustom extends BroadcastReceiver {

    ReactContext reactContext;

    public BroadcastReceiverCustom (){
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if             (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
            // This code will execute when the phone has an incoming call

            // get the phone number
            String incomingNumber =     intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            Toast.makeText(context, "Call from:" +incomingNumber, Toast.LENGTH_LONG).show();
            sendCallEvent(incomingNumber);

        } else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
                TelephonyManager.EXTRA_STATE_IDLE)
                || intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
                    TelephonyManager.EXTRA_STATE_OFFHOOK)) {
            // This code will execute when the call is disconnected
            Toast.makeText(context, "Detected call hangup event", Toast.LENGTH_LONG).show();
        }
    }

    public void sendCallEvent(String incomingNumber){
            WritableMap params = Arguments.createMap();
            params.putString("Number", incomingNumber);
            sendEvent("CallRecevied", params);
    }


    private void sendEvent(String eventName,
                          @Nullable WritableMap params) {
        reactContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit(eventName, params);
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 8

由于Fury的解决方案对我来说不起作用(在广播接收器中得到“找不到getApplication()的符号”),我尝试应用与我所知道的工作类似的逻辑。所以:

import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.ReactApplication;
...
// context - is the context you get from broadcastreceivers onReceive
ReactApplication rnApp = (ReactApplication) context.getApplicationContext();

rnApp.getReactNativeHost().getReactInstanceManager()
                                .getCurrentReactContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                                .emit("test", Arguments.createMap());
Run Code Online (Sandbox Code Playgroud)

这对我有用。


Eri*_*res 1

我解决了这个问题。我ReactContextBaseJavaModule单例模式创建了一个并通过它进行访问ReactContext(这可能是一个巨大的“nono”)。

如果有其他更聪明的方法来解决这个问题,请告诉我。