因?yàn)槔系臑g覽器能夠識(shí)別doctype,但是并不意味它可以處理HTML5標(biāo)簽和功能。
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序定制開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了紅橋免費(fèi)建站歡迎大家使用!
HTML5 a標(biāo)簽電話功能:
1、a href="tel:4008001234" class="call"/a。
2、親測(cè)是可以的,注意tel:的和html中的meta寫法為?meta name="format-detection" content="telephone=yes"。
3、target是打開鏈接時(shí)用什么目標(biāo)打開,是在新窗口中打開就用target=_blank,在父窗口中打開就用target=_parent,在當(dāng)前窗口中打開就用target=_self,
target=_top表示在頂層窗口中打開
最近采用phonegap做一個(gè)APP,需要在應(yīng)用內(nèi)實(shí)現(xiàn)撥打電話,通話結(jié)束後能反饋通話相關(guān)狀態(tài),查看了一番phonegap官方文檔,似乎沒有跟電話相關(guān)的api,在互聯(lián)網(wǎng)上也大概搜了一下,好像沒找到相關(guān)的內(nèi)容。其實(shí)html5是支持直接在網(wǎng)頁上撥打電話的,只要加入如下html代碼即可:
[html] view plaincopy
打電話a href="tel:10086" 移動(dòng)客服/a
發(fā)短信a href="sms:10086" 發(fā)短信/a
但這中方式只能實(shí)現(xiàn)撥打電話和發(fā)送短信,不能反饋結(jié)果,比如我想在應(yīng)用能實(shí)現(xiàn)撥打電話,通話結(jié)束後自動(dòng)保存通話的電話號(hào)碼、通話時(shí)間、時(shí)長(zhǎng)等,默認(rèn)的html功能就不能滿足了。
phonegap官方不提供的功能,我們只有自己通過開發(fā)插件了實(shí)現(xiàn)了
下面我們通過代碼來簡(jiǎn)單介紹下phonegap插件開發(fā)步驟:
一、定義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();
上面的代碼我們定義了一個(gè)Phone插件,插件有一個(gè)call API,我們傳入
[javascript] view plaincopy
successCallback
failureCallback
分別做為電話撥打成功和失敗的回調(diào)函數(shù)
傳入
[javascript] view plaincopy
number
做為電話號(hào)碼
在方法裏邊調(diào)用
phonegap的cordova.exec()
[javascript] view plaincopy
cordova.exec(successCallback, failureCallback, "Phone", "call", [number]);
就是在這個(gè)方法裏將執(zhí)行到native端的功能調(diào)用
最後我們new一個(gè)Phone對(duì)象,把他附件到window對(duì)象上,方便以後調(diào)用。
這樣,插件的JS代碼完成。
二、native端代碼(以android平臺(tái)為例)
先直接上代碼
[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+"不是有效的電話號(hào)碼。");
}
} else {
callbackContext.error("電話號(hào)碼不能為空.");
}
}
//中斷電話
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("未知狀態(tài)");
}
}
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("其他錯(cuò)誤!");
}
}
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(second2second-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();
}
}
}
然後調(diào)用具體實(shí)現(xiàn)撥打電話功能的方法call方法,在call方法內(nèi)我們首先判斷電話號(hào)碼合法性,不合法直接調(diào)用callbackContext.error("不是有效的電話號(hào)碼。"),這個(gè)方法將觸發(fā)JS端的error回調(diào)函數(shù)執(zhí)行,并傳入一個(gè)字符串參數(shù),比如以上的failureCallback
如果電話號(hào)碼合法則彈出呼叫界面,如下代碼
[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+"不是有效的電話號(hào)碼。");
}
在代碼中我們通過變量start_time記錄開始時(shí)間,然後使用this.cordova.startActivityForResult(this, i,PHONE_CALL);啟動(dòng)Activity。
在終止撥號(hào)或掛斷電話時(shí)將執(zhí)行onActivityResult方法,我們將在此方法內(nèi)實(shí)現(xiàn)通話狀態(tài)信息的反饋。主要看一下這段代碼
[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()方法獲得通話時(shí)長(zhǎng),原理就是讀取通話記錄裏邊的duration字段,由於通話剛結(jié)束時(shí)通話記錄可能還沒出現(xiàn)記錄,所以我們要反復(fù)調(diào)用該方法,直到有記錄或到超時(shí)時(shí)間為止。
取得了時(shí)長(zhǎng)我們通過this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));把結(jié)果反饋給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端的代碼完成。
三、客戶端調(diào)用
[javascript] view plaincopy
window.Phone.call(function (obj) { alert(JSON.stringify(obj));
}, function (err) { alert(err); }, "13401100000");
四、配置插件
在config.xml文件中注冊(cè)插件
[html] view plaincopy
plugin name="Phone" value="com.juhuibao.PhoneGapPlugin.Phone"/
在AndroidManifest.xml文件中增加權(quán)限
[html] view plaincopy
uses-permission android:name="android.permission.CALL_PHONE" /
uses-permission android:name="android.permission.READ_CALL_LOG" /
uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /
uses-permission android:name="android.permission.READ_PHONE_STATE"/
這樣寫:a href="tel:123456789"撥號(hào)/a
HTML 運(yùn)行在手機(jī)瀏覽器上的可以調(diào)用手機(jī)的撥號(hào)就是你想要撥打的電話號(hào)碼在頁面中看到“撥號(hào)”的字樣,點(diǎn)一下,就會(huì)自動(dòng)跳到撥打電話的頁面啦。這種方式塞班、安卓與iphone都支持。
例如:
a href=”javascript:phone('+phone+') ”撥打電話/a
function phone(date)
{
window.location.href = 'tel://' + date;
}
用html制作可以撥打電話的鏈接其實(shí)是一個(gè)簡(jiǎn)單的程序可以試著寫一些簡(jiǎn)單的。
這是手機(jī)的安全機(jī)制問題,第三方程序或者軟件撥打電話需要得到系統(tǒng)的權(quán)限,你點(diǎn)Allow Call就可以了。