应用程序关闭时运行React Native代码

时间:2016-05-03 07:50:49

标签: android react-native

问题

我一直在尝试创建一个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代码的任何信息,或者如果您知道在触发事件时启动应用程序的方法。我非常感谢这些信息。

0 个答案:

没有答案