草庐IT

javascript - 如何将 twilio 集成到 react native for android 中?

coder 2023-11-30 原文

我正在使用 react native 构建需要 twilio 集成的 android 移动应用程序。我使用了 npm repo 中的示例代码。 .

https://github.com/rogchap/react-native-twilio

const Twilio = require('react-native-twilio');
Twilio.initWithToken('sometoken');

componentWillMount() {
 Twilio.initWithTokenUrl('https://example.com/token');
 // or 
 Twilio.initWithToken('sometoken');
 Twilio.addEventListener('deviceDidStartListening', this._deviceDidStartListening);
 Twilio.addEventListener('deviceDidStopListening', this._deviceDidStopListening);
 Twilio.addEventListener('deviceDidReceiveIncoming', this._deviceDidReceiveIncoming);
 Twilio.addEventListener('connectionDidStartConnecting', this._connectionDidStartConnecting);
 Twilio.addEventListener('connectionDidConnect', this._connectionDidConnect);
 Twilio.addEventListener('connectionDidDisconnect', this._connectionDidDisconnect);
 Twilio.addEventListener('connectionDidFail', this._connectionDidFail);
}

Twilio.connect({To: '+61234567890'});

Twilio.disconnect();

Twilio.accept();

Twilio.reject();

Twilio.ignore();

但是我无法完成它。如果有人对此有想法,请帮助我。

最佳答案

我已经找到方法了。在这里我将逐步解释:

第 1 步:

安装 npm -> npm install react-native-twilio --save。 在 android 项目中添加这两个类,如下所示:

TwilioModule.java

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
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.ReadableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.twilio.client.Connection;
import com.twilio.client.ConnectionListener;
import com.twilio.client.Device;
import com.twilio.client.DeviceListener;
import com.twilio.client.PresenceEvent;
import com.twilio.client.Twilio;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

public class TwilioModule extends ReactContextBaseJavaModule implements    ConnectionListener, DeviceListener {

 private ReactContext rContext;
 private Device twilioDevice;
 private Connection connection;
 private Connection pendingConnection;
 private IntentReceiver _receiver;
 private TwilioModule self;
 private String TAG = "CDMS_TWILIO";

 public class IntentReceiver extends BroadcastReceiver {

              private ConnectionListener _cl;

 public IntentReceiver(ConnectionListener connectionListener) {
  this._cl = connectionListener;
}

public void onReceive(Context context, Intent intent) {
  Log.d(TAG,"onReceive method called");
  pendingConnection =        
 (Connection)intent.getParcelableExtra("com.twilio.client.Connection");
  pendingConnection.setConnectionListener(this._cl);
  pendingConnection.accept();
  connection = pendingConnection;
  pendingConnection = null;
  sendEvent("deviceDidReceiveIncoming", null);
}
 }

public TwilioModule(ReactApplicationContext reactContext) {
super(reactContext);
Log.d(TAG,"TwilioModule constructor called");
rContext = reactContext;
this.rContext = reactContext;
self = this;
this._receiver = new IntentReceiver(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.rogchap.react.modules.twilio.incoming");
this.rContext.registerReceiver(this._receiver, intentFilter);
}

private void sendEvent(String eventName, @Nullable Map<String, String> params) {

if (eventName.equals("connectionDidDisconnect")) {
  //Log.e("mytag", "not emitting an event, just dereferncing the DeviceEventEmitter");
  rContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).toString();
  //Log.e("mytag", "DONE");
}
else {
  rContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, null);
}
}

@Override
public String getName() {
 return "Twilio";
}

@ReactMethod
public void initWithTokenUrl(String tokenUrl) {
Log.d(TAG,"TwilioModule initWithTokenUrl method called");
StringBuilder sb = new StringBuilder();
try {
  URLConnection conn = new URL(tokenUrl).openConnection();
  InputStream in = conn.getInputStream();
  BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
  String line = "";
  while ((line = reader.readLine()) != null) {
    sb.append(line);
  }
} catch (Exception e) {
}
initWithToken(sb.toString());
}

@ReactMethod
public void initWithToken(final String token) {
Log.d(TAG,"TwilioModule initWithToken method called, token = "+token);
if (!Twilio.isInitialized()) {
  Twilio.initialize(rContext, new Twilio.InitListener() {
    @Override
    public void onInitialized() {
      try {
        if (twilioDevice == null) {
          twilioDevice = Twilio.createDevice(token, self);
          if (twilioDevice!=null){
            Log.d(TAG,"twilioDevice is available");
          }
          else{
            Log.d(TAG,"twilioDevice is null");
          }
          Intent intent = new Intent();
          intent.setAction("com.rogchap.react.modules.twilio.incoming");
          PendingIntent pi = PendingIntent.getBroadcast(rContext, 0, intent, 0);
          twilioDevice.setIncomingIntent(pi);
        }
      } catch (Exception e) {
      }
    }

    @Override
    public void onError(Exception e) {
      Log.d(TAG, e.toString() + "Twilio initilization failed");
    }
  });
}
}

@ReactMethod
public void connect(ReadableMap par) {
Log.d(TAG,"twilioDevice connect");
String contact = "";
Map<String, String> params = new HashMap<String, String>();
contact = par.getString("To").trim();
params.put("To", contact);

// Create an outgoing connection
if (twilioDevice != null) {
  connection = twilioDevice.connect(params, self);
}
else {
  Log.d(TAG,"twilioDevice is null");
}
}

@ReactMethod
public void disconnect() {
Log.d(TAG,"disconnect method called");
if (connection != null) {
  connection.disconnect();
  connection = null;
}
}

@ReactMethod
public void accept() {
Log.d(TAG,"accept method called");
}

@ReactMethod
public void reject() {
  Log.d(TAG,"reject method called");
  pendingConnection.reject();
}

@ReactMethod
public void ignore() {
  Log.d(TAG,"ignore method called");
  pendingConnection.ignore();
}

@ReactMethod
public void setMuted(Boolean isMuted) {
Log.d(TAG,"setMuted method called");
if (connection != null && connection.getState() == Connection.State.CONNECTED) {
  connection.setMuted(isMuted);
}
}

/* ConnectionListener */

@Override
public void onConnecting(Connection connection) {
Log.d(TAG,"onConnecting method called");
sendEvent("connectionDidStartConnecting", null);
}

@Override
public void onConnected(Connection connection) {
Log.d(TAG,"onConnected method called");
sendEvent("connectionDidConnect", null);
}

@Override
public void onDisconnected(Connection connection) {
Log.d(TAG,"onDisconnected method called");
if (connection == connection) {
  connection = null;
}
if (connection == pendingConnection) {
  pendingConnection = null;
}
sendEvent("connectionDidDisconnect", null);
}

@Override
public void onDisconnected(Connection connection, int errorCode, String errorMessage) {
Log.d(TAG,"onDisconnected method with error called");
Map errors = new HashMap();
errors.put("err", errorMessage);
sendEvent("connectionDidFail", errors);
}

/* DeviceListener */
@Override
public void onStartListening(Device device) {
Log.d(TAG,"onStartListening method called");
this.sendEvent("deviceDidStartListening", null);
}

@Override
public void onStopListening(Device device) {
Log.d(TAG,"onStopListening method called");
}

@Override
public void onStopListening(Device inDevice, int inErrorCode, String inErrorMessage) {
Log.d(TAG,"onStopListening method with error code called");
}

@Override
public boolean receivePresenceEvents(Device device) {
Log.d(TAG,"receivePresenceEvents method called");
return false;
}

@Override
public void onPresenceChanged(Device inDevice, PresenceEvent  inPresenceEvent) {
Log.d(TAG,"onPresenceChanged method called");
}
}

TwilioPackage.java

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class TwilioPackage implements ReactPackage {

@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
  return Arrays.<NativeModule>asList(
   new TwilioModule(reactContext)
 );
}

@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Arrays.asList();
}
}

第 2 步:

然后在您的主应用程序类中添加包模块:

@Override
protected List<ReactPackage> getPackages() {
  return Arrays.<ReactPackage>asList(
      new MainReactPackage(),
      new TwilioPackage() <-- Here
  );
}

第 3 步:

在 list 文件中添加 Twilio 服务:

   <service
      android:name="com.twilio.client.TwilioClientService"
      android:exported="false"
      android:stopWithTask="true" />

第 4 步:

在 build.gradle 中添加 twilio lib :

 dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
  compile 'com.android.support:appcompat-v7:23.0.1'
  compile 'com.facebook.react:react-native:+'
  compile 'com.twilio:client-android:1.2.15' <-- Here
 }

第 5 步:

现在你必须在你的 react native 中添加这段代码:

Dailer.js

   'use strict';

   import React, { Component } from 'react';
   import {  NativeModules,     NativeAppEventEmitter,AppRegistry,TouchableOpacity,Text,StyleSheet,TextInput,View,TouchableHighlight,Alert,ActivityIndicator,AsyncStorage,Image ,Navigator} from 'react-native';

   var Dimensions = require('Dimensions');
   var windowSize = Dimensions.get('window');
   const Twilio = require('react-native-twilio');

   var styles = StyleSheet.create({
   container: {
   flexDirection: 'column',
   flex: 1,
   backgroundColor: 'transparent'
   },
  });


  class Dialer extends Component {

   constructor(props) {
    super(props);
    this.state = {   phno:'+9112345678',twiliotoken:'xaxaxaxaxaxaxax',statusMessage:'Wait...',jsonData:'',isConnecting:false,connectionFailed:false,};
     }

    componentWillMount() {
    this.InitTwilioClientMethods();
    }

   render() {
   return (
  <Navigator
    renderScene={this.renderScene.bind(this)}
    navigator={this.props.navigator} />
);
}


renderScene(route, navigator) {

return (
  <View style={styles.container}>

    <View
      style={{position: 'absolute',left: 0,top: 0, width: windowSize.width,height: windowSize.height,backgroundColor:'#343B44'}}/>

      <View style = {{flex: 1.1,backgroundColor: 'transparent',flexDirection: 'column',}}>

        <View style = {{justifyContent: 'flex-end',alignItems: 'center',flex: 1,backgroundColor: 'transparent'}}>
          <Text
            style={{color: '#FFFFFF',
            fontFamily: 'Montserrat-Regular',fontWeight: 'bold',
            fontSize:20,}}> {this.state.username}</Text>
        </View>

        <View style = {{justifyContent: 'flex-start',alignItems: 'center',flex: 1,backgroundColor: 'transparent'}}>
          <Text
            style={{color: '#6AF182',
            fontFamily: 'Montserrat-Regular',
            marginTop:10,
            fontSize:17,}}> {this.state.statusMessage} </Text>
        </View>

      </View>

      <View style = {{justifyContent: 'center',alignItems: 'center',flex: 2,backgroundColor: 'transparent'}}>
        <Image
          source={{uri: 'http://servicedrivetoday.com/wp-content/uploads/2015/10/shutterstock_285486080-512x342.jpg'}}
          style={{ width: 112,height: 112,borderRadius: 112/2}}/>
      </View>

      <View style = {{justifyContent: 'center',alignItems: 'center',flex: 1,backgroundColor: 'transparent'}}>
        <TouchableOpacity
          style={{justifyContent: 'center',alignItems: 'center',backgroundColor: 'transparent'}}
          onPress={() => this.endCallAction()}>
            <Image
              source={require('image!icon_call_cancel')}
              style={{height:60,width:60}}/>
        </TouchableOpacity>
      </View>

  </View>
);

 /* Methods for connect Call */
 callNumber(){
   Twilio.connect({To: this.state.phno});
 }


 /* Method for disconnect call */
 endCallAction() {
   this.callDisconnectHandler();
   var navigator = this.props.navigator;
   navigator.pop();
 }

 /*Init Twilio client methods and make call */
 InitTwilioClientMethods(){
  Twilio.initWithToken(this.state.twiliotoken);
  Twilio.addEventListener('deviceDidStartListening', this.deviceDidStartListening);
  Twilio.addEventListener('deviceDidStopListening', this.deviceDidStopListening);
  Twilio.addEventListener('deviceDidReceiveIncoming', this.deviceDidReceiveIncoming);
  Twilio.addEventListener('connectionDidStartConnecting', this.connectionDidStartConnecting);
  Twilio.addEventListener('connectionDidConnect', this.connectionDidConnect);
  Twilio.addEventListener('connectionDidDisconnect', this.connectionDidDisconnect);
Twilio.addEventListener('connectionDidFail', this.connectionDidFail);

setTimeout(() => {
  this.setState({ statusMessage: 'Connecting...' });
  Twilio.connect({To: this.state.phno});
}, 6000);
}


/* call back for  device Did Start Listening*/
deviceDidStartListening(){
 console.log('deviceDidStartListening');
}


/* call back for  device Did Stop Listening*/
deviceDidStopListening(){
 console.log('deviceDidStopListening');
}


/* call back for  device Did Receive Incoming*/
deviceDidReceiveIncoming(){
 console.log('deviceDidReceiveIncoming');
}


/* call back for  connection Did Start Connecting */
connectionDidStartConnecting(){
 //this.setState({ statusMessage: 'Connecting...' });
}

/* call back for connection Did Connect */
connectionDidConnect(){
 //this.setState({ statusMessage: 'Connected' });
}


/* call back for connection Did Disconnect */
connectionDidDisconnect(){
 //this.setState({ statusMessage: 'DisConnected' });
}


/* call back for connection Did Fail */
connectionDidFail(){
 //this.setState({ statusMessage: 'Connection Failed' });
}


/* Handler for disconnect call Twilio */
callDisconnectHandler(){
 Twilio.disconnect();
}

/* Handler for accept incoming call Twilio */
callAcceptHandler(){
 Twilio.accept();
}

/* Handler for reject incoming call Twilio*/
callRejectHandler(){
 Twilio.reject();
}

/* Handler for ignore incoming call Twilio */
callIgnoreHandler(){
  Twilio.ignore();
}
}

module.exports = Dialer;

对于 ios,您必须按照 repo 中的说明进行操作: https://github.com/rogchap/react-native-twilio

如果发现 iOS 有任何问题,请查看此链接: Twilio call is not working in iOS and Android in react-native

快乐编码...

关于javascript - 如何将 twilio 集成到 react native for android 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39653677/

有关javascript - 如何将 twilio 集成到 react native for android 中?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐