我一直在尝试创建一个React Native应用程序,用于捕获电话并将数字发送到API。我创建了一个工作的本机模块,用于捕获Java中的电话。我还设法将一个事件发送到我的JavaScript代码并设法捕获此事件并通过JavaScript中的console.log记录该数字。
现在我的问题是我需要应用程序才能工作,即使应用程序已关闭(在后台)。我无法找到任何方法用Java模块唤醒react本机代码或在不启动应用程序的情况下运行Javascript。
这是我的BroadcastReciver:
package com.wavyassist;
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 CallCatcher extends BroadcastReceiver {
private CallCatcherModule module;
public CallCatcher (){
this.module = CallCatcherModule.getInstance();
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING))
{
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, "Call from:" +incomingNumber, Toast.LENGTH_LONG).show();
module.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();
}
}
}
这是我的模块:
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.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import javax.annotation.Nullable;
import java.util.Map;
public class CallCatcherModule extends ReactContextBaseJavaModule {
private ReactContext reactContext;
private static CallCatcherModule instance;
public static CallCatcherModule getInstance(ReactApplicationContext reactContext){
if (instance == null) {
instance = new CallCatcherModule(reactContext);
}
return instance;
}
private CallCatcherModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName(){
return "CallCatcherModule";
}
public static CallCatcherModule getInstance(){
return instance;
}
public void sendCallEvent(String incomingNumber){
WritableMap params = Arguments.createMap();
params.putString("Number", incomingNumber);
sendEvent(this.reactContext ,"CallRecevied", params);
}
private void sendEvent(ReactContext reactContext,
String eventName,
@Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
Log.d("CallCatcherModule", "Event Emitted");
}
}
这些类将始终在捕获呼叫时发送号码。要在javascript中接收事件,我目前正在使用此工作示例。 (此代码仅在重新启动整个应用程序时有效。)
"use strict";
import React, {
AppRegistry,
Component,
StyleSheet,
Text,
View,
TouchableOpacity,
Navigator,
TextInput,
DeviceEventEmitter
} from 'react-native';
var emitter;
class RegDone extends Component {
constructor(props) {
super(props);
this.handleCall = this.handleCall.bind(this);
this.changeListenerState = this.changeListenerState.bind(this);
this.state = {test: ''};
}
componentWillMount(){
console.log('RecivingCall: Starting Listener');
emitter = DeviceEventEmitter.addListener('CallRecevied', this.handleCall);
}
componentWillUnmount(){
console.log('RecivingCall: Stoping Listener')
emitter.remove();
this.setState({text: ''});
}
handleCall(Event){
console.log('RecivingCall: Call Recevied! Number: ' + Event.Number);
this.setState({test: Event.Number});
}
render() {
return (
<View style={styles.container}>
<Text >
{this.state.test}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
button: {
backgroundColor: '#aaaaaa',
padding: 20,
},
});
module.exports = RegDone;
我试图在一个不是视图的单独类中编写JS代码。我失败了。我无法联系新类中的方法,最终再次在视图类中编写代码。
我也尝试按下按钮启动和停止DeviceEventEmitter,但这根本没有做任何事情。(不知道为什么!)
问题似乎是JavaScript仅在应用程序启动并运行时才可用,并且显示包含JS代码的特定视图。
如果有人在应用程序关闭时有关于如何运行React本机JS代码的任何信息,或者如果您知道在触发事件时启动应用程序的方法。我非常感谢这些信息。