自己动手开发phonegap插件之《phonegap拨打电话插件》

最近采用phonegap做一个APP,需要在应用内实现拨打电话,通话结束后能反馈通话相关状态,查看了一番phonegap官方文档,似乎没有跟电话相关的api,在互联网上也大概搜了一下,好像没找到相关的内容。其实html5是支持直接在网页上拨打电话的,只要加入如下html代码即可:

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

如果电话号码合法则弹出呼叫界面,如下代码

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+"不是有效的电话号码。");  
            }    

自己动手开发phonegap插件之《phonegap拨打电话插件》

在代码中我们通过变量start_time记录开始时间,然后使用this.cordova.startActivityForResult(this, i,PHONE_CALL);启动Activity。

在终止拨号或挂断电话时将执行onActivityResult方法,我们将在此方法内实现通话状态信息的反馈。主要看一下这段代码

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自己动手开发phonegap插件之《phonegap拨打电话插件》

我们通过GetLastCallDuration()方法获得通话时长,原理就是读取通话记录里边的duration字段,由于通话刚结束时通话记录可能还没出现记录,所以我们要反复调用该方法,直到有记录或到超时时间为止。

取得了时长我们通过this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));把结果反馈给JS端。

附 PhoneResult.java

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
 
  1. window.Phone.call(function (obj) { alert(JSON.stringify(obj));  
  2.                           
  3.                     }, function (err) { alert(err); }, "13401100000");  

四、配置插件

在config.xml文件中注册插件

[html] view plaincopy
 
  1. <plugin name="Phone" value="com.juhuibao.PhoneGapPlugin.Phone"/>  


在AndroidManifest.xml文件中增加权限

[html] view plaincopy
 
  1. <uses-permission android:name="android.permission.CALL_PHONE" />  
  2. <uses-permission android:name="android.permission.READ_CALL_LOG" />  
  3. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />   
  4. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>  

《完》

相关推荐