Reputation: 375
I an trying to create an application thet will catch the incoming calls to the cellphone using a BroadcastReciver. From my BroadcastReciver i whould like to sent the number as an event to my JS file using this method.
I have checked that my Java code is working and is catching the calls and number but my application craches with the error that mentions that the react context is null. I am guessing that this is because the manifest (or something) is creating a new instance of the class when the event from the android system is catched and that the new instance does not have a ReactContext. Is there any way to access the ReactContext from the Java code or send a ReactContext to the BroadcastReciver through the manifest?
This is my 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);
}
}
Upvotes: 9
Views: 5043
Reputation: 546
You can access reactContext like this:
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
ReactInstanceManager reactInstanceManager = getReactNativeHost().getReactInstanceManager();
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if(reactContext != null) {
// Use reactContext here
} else {
reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext context) {
// Use context here
reactInstanceManager.removeReactInstanceEventListener(this);
}
});
}
Upvotes: 2
Reputation: 81
As Fury's solution did not work for me(got "cannot find symbol" for getApplication()) in the broadcast receiver, i tried applying a similar logic with what i knew is working. So:
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());
This worked for me.
Upvotes: 8
Reputation: 3442
I faced a same problem and am using this.
((MainApplication)getApplication()).getReactNativeHost().getReactInstanceManager().getCurrentReactContext()
Upvotes: 2
Reputation: 375
I solved the problem. I created a ReactContextBaseJavaModule
with a singleton pattern and got access to ReactContext
through it (This might be a huge "nono").
If there is another smarter way to solve this problem, please inform me.
Upvotes: 1