永发信息网

phonegap 什么插件能打电话

答案:1  悬赏:40  手机版
解决时间 2021-03-21 06:48
  • 提问者网友:萌卜娃娃
  • 2021-03-20 09:57
phonegap 什么插件能打电话
最佳答案
  • 五星知识达人网友:煞尾
  • 2021-03-20 11:24
最近采用phonegap做一个APP,需要在应用内实现拨打电话,通话结束後能反馈通话相关状态,查看了一番phonegap官方文档,似乎没有跟电话相关的api,在互联网上也大概搜了一下,好像没找到相关的内容。其实html5是支持直接在网页上拨打电话的,只要加入如下html代码即可:
  [html] view plaincopy
  打电话移动客服
  发短信发短信

  但这中方式只能实现拨打电话和发送短信,不能反馈结果,比如我想在应用能实现拨打电话,通话结束後自动保存通话的电话号码、通话时间、时长等,默认的html功能就不能满足了。
  phonegap官方不提供的功能,我们只有自己通过开发插件了实现了
  下面我们通过代码来简单介绍下phonegap插件开发步骤:
  一、定义JS插件API
  [javascript] view plaincopy
  var Phone = function() {
  };
  Phone.prototype.call = function (successCallback, failureCallback,number) {
  cordova.exec(successCallback, failureCallback, "Phone", "call", [number]);
  };
  window.Phone = new Phone();

  上面的代码我们定义了一个Phone插件,插件有一个call API,我们传入
  [javascript] view plaincopy
  successCallback
  failureCallback
  分别做为电话拨打成功和失败的回调函数
  传入
  [javascript] view plaincopy
  number
  做为电话号码
  在方法裏边调用
  phonegap的cordova.exec()
  [javascript] view plaincopy
  cordova.exec(successCallback, failureCallback, "Phone", "call", [number]);

  就是在这个方法裏将执行到native端的功能调用
  最後我们new一个Phone对象,把他附件到window对象上,方便以後调用。
  这样,插件的JS代码完成。
  二、native端代码(以android平台为例)
  先直接上代码
  [java] view plaincopy
  package com.juhuibao.PhoneGapPlugin;
  import java.util.Date;
  import org.apache.cordova.api.CallbackContext;
  import org.apache.cordova.api.CordovaPlugin;
  import org.apache.cordova.api.PluginResult;
  import org.json.JSONArray;
  import org.json.JSONException;
  import android.app.Activity;
  import android.content.Intent;
  import android.database.Cursor;
  import android.net.Uri;
  import android.provider.CallLog.Calls;
  import android.telephony.PhoneNumberUtils;
  public class Phone extends CordovaPlugin {
  private static final int PHONE_CALL = 0; // 拨打电话
  private static final int PHONE_ABORT = 1; // 挂断电话
  private Date start_time;
  private CallbackContext callbackContext;
  private String phonenumber;
  @Override
  public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
  try{
  this.callbackContext = callbackContext;
  if ("call".equals(action)) {
  this.phonenumber=args.getString(0);
  this.call(args.getString(0),callbackContext);
  return true;
  }
  if ("abort".equals(action)) {
  this.abort(callbackContext);
  return true;
  }
  return false;
  }
  catch(Exception e){
  callbackContext.error(e.getMessage());
  }
  return false;
  }
  //拨打电话
  private void call(String phonenumber, CallbackContext callbackContext) {
  if (phonenumber != null && phonenumber.length() > 0) {
  if(PhoneNumberUtils.isGlobalPhoneNumber(phonenumber)){
  Intent i = new Intent();
  i.setAction(Intent.ACTION_CALL);
  i.setData(Uri.parse("tel:"+phonenumber));
  start_time=new Date();
  this.cordova.startActivityForResult(this, i,PHONE_CALL);
  }
  else{
  callbackContext.error(phonenumber+"不是有效的电话号码。");
  }
  } else {
  callbackContext.error("电话号码不能为空.");
  }
  }
  //中断电话
  private void abort(CallbackContext callbackContext) {
  }
  public void onActivityResult(int requestCode, int resultCode, Intent intent) {
  Date end_time=new Date();
  if (resultCode == Activity.RESULT_OK) {
  if (requestCode == PHONE_CALL) {
  this.callbackContext.error("未知状态");
  }
  }
  else if (resultCode == Activity.RESULT_CANCELED) {
  try{
  if (requestCode == PHONE_CALL) {
  long duration=GetLastCallDuration();
  PhoneResult result=new PhoneResult();
  result.setNumber(Phone.this.phonenumber);
  result.setStartTime(Phone.this.start_time);
  result.setEndTime(end_time);
  result.setDuration(duration);
  this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));
  }
  }
  catch(Exception e){
  this.callbackContext.error(e.getMessage());
  }
  }
  else {
  this.callbackContext.error("其他错误!");
  }
  }
  long delayTime=0;
  long timeOut=2000;
  long GetLastCallDuration() throws InterruptedException{
  Activity activity = this.cordova.getActivity();
  Cursor cursor = activity.getContentResolver().query(Calls.CONTENT_URI,
  new String[] {Calls.NUMBER,Calls.DATE, Calls.DURATION, Calls.TYPE, Calls.DATE },
  "number=?and type=?",
  new String[]{this.phonenumber,"2"},
  Calls.DEFAULT_SORT_ORDER);
  activity.startManagingCursor(cursor);
  boolean hasRecord = cursor.moveToFirst();
  if (hasRecord) {
  long endTime=cursor.getLong(cursor.getColumnIndex(Calls.DATE));
  Date date = new Date(endTime);
  long duration = cursor.getLong(cursor.getColumnIndex(Calls.DURATION));
  long dif=this.start_time.getTime()-date.getTime();
  long second=dif/1000;
  if(second<2&&second>-2){
  return duration;
  }else{
  if(delayTime>=timeOut){
  return 0;
  }
  Thread.sleep(200);
  delayTime+=200;
  return GetLastCallDuration();
  }
  }else{
  if(delayTime>=timeOut){
  return 0;
  }
  Thread.sleep(200);
  delayTime+=200;
  return GetLastCallDuration();
  }
  }
  }
  然後调用具体实现拨打电话功能的方法call方法,在call方法内我们首先判断电话号码合法性,不合法直接调用callbackContext.error("不是有效的电话号码。"),这个方法将触发JS端的error回调函数执行,并传入一个字符串参数,比如以上的failureCallback
  如果电话号码合法则弹出呼叫界面,如下代码
  [java] view plaincopy
  if(PhoneNumberUtils.isGlobalPhoneNumber(phonenumber)){
  Intent i = new Intent();
  i.setAction(Intent.ACTION_CALL);
  i.setData(Uri.parse("tel:"+phonenumber));
  start_time=new Date();
  this.cordova.startActivityForResult(this, i,PHONE_CALL);
  }
  else{
  callbackContext.error(phonenumber+"不是有效的电话号码。");
  }

  在代码中我们通过变量start_time记录开始时间,然後使用this.cordova.startActivityForResult(this, i,PHONE_CALL);启动Activity。
  在终止拨号或挂断电话时将执行onActivityResult方法,我们将在此方法内实现通话状态信息的反馈。主要看一下这段代码
  [java] view plaincopy
  else if (resultCode == Activity.RESULT_CANCELED) {
  try{
  if (requestCode == PHONE_CALL) {
  long duration=GetLastCallDuration();
  PhoneResult result=new PhoneResult();
  result.setNumber(Phone.this.phonenumber);
  result.setStartTime(Phone.this.start_time);
  result.setEndTime(end_time);
  result.setDuration(duration);
  this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));
  }
  }
  catch(Exception e){
  this.callbackContext.error(e.getMessage());
  }
  }
  不管电话有没有接通,resultCode总是等於Activity.RESULT_CANCELED。
  我们通过GetLastCallDuration()方法获得通话时长,原理就是读取通话记录裏边的duration字段,由於通话刚结束时通话记录可能还没出现记录,所以我们要反复调用该方法,直到有记录或到超时时间为止。
  取得了时长我们通过this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));把结果反馈给JS端。
  附 PhoneResult.java
  [java] view plaincopy
  package com.juhuibao.PhoneGapPlugin;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import org.json.JSONException;
  import org.json.JSONObject;
  public class PhoneResult {
  private String number = "";
  private Date startTime;
  private Date endTime;;
  private long duration = 0;
  public JSONObject toJSONObject() throws JSONException {
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:S");
  return new JSONObject(
  "{number:" + JSONObject.quote(number) +
  ",startTime:" + JSONObject.quote(sdf.format(startTime)) +
  ",endTime:" + JSONObject.quote(sdf.format(endTime)) +
  ",duration:" + duration + "}");
  }
  public String getNumber() {
  return number;
  }
  public void setNumber(String number) {
  this.number = number;
  }
  public Date getStartTime() {
  return startTime;
  }
  public void setStartTime(Date startTime) {
  this.startTime = startTime;
  }
  public Date getEndTime() {
  return endTime;
  }
  public void setEndTime(Date endTime) {
  this.endTime = endTime;
  }
  public long getDuration() {
  return duration;
  }
  public void setDuration(long duration) {
  this.duration = duration;
  }
  }

  这样native端的代码完成。
  三、客户端调用
  [javascript] view plaincopy
  window.Phone.call(function (obj) { alert(JSON.stringify(obj));
  }, function (err) { alert(err); }, "13401100000");
  四、配置插件
  在config.xml文件中注册插件
  [html] view plaincopy
  

  在AndroidManifest.xml文件中增加权限
  [html] view plaincopy
  
  
  
  
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯