cordova插件实现拨打电话,支持两种形式:
1,直接拨号;
2,跳转到拨号界面,但不拨号,自动填充号码;
最近项目上有个需求,点击客服电话拨打电话,在github上找了一下,用下面这个插件实现了效果:
插件地址:
https://github.com/Rohfosho/CordovaCallNumberPlugin
1,安装插件
sudo cordova plugin add https://github.com/Rohfosho/CordovaCallNumberPlugin.git
2,js中使用
$$(document).on('click','#tel_number_content',function () {
//弹出拨号确认框(Framework7框架)
myApp.confirm("确认拨打电话?",function(){
//调用插件
window.plugins.CallNumber.callNumber(function onSuccess(result){
console.log("Success:call number"+result);
},
function onError(result) {
console.log("Error:call number"+result);
},
"18589082142",true);
},function(){
console.log("cancle call number");
});
});
后来领导又提出不能直接拨号,要求点击客服电话后跳转到拨号界面,自动填充电话号码但不拨号。我在github上翻了个遍,网上的插件都是只支持直接拨号的,没办法,只有自己动手改造插件以满足需求了。好在搞过两年安卓,就先从安卓开始。
我先去看了下这个插件作者是怎么写的,安卓交互是在CFCallNumber.java文件,实现拨号的是下面这个方法:
private void callPhone(JSONArray args) throws JSONException {
String number = args.getString(0);
number = number.replaceAll("#", "%23");
if (!number.startsWith("tel:")) {
number = String.format("tel:%s", number);
}
try {
Intent intent = new Intent(isTelephonyEnabled() ? Intent.ACTION_CALL : Intent.ACTION_VIEW);
intent.setData(Uri.parse(number));
boolean bypassAppChooser = Boolean.parseBoolean(args.getString(1));
if (bypassAppChooser) {
intent.setPackage(getDialerPackage(intent));
}
cordova.getActivity().startActivity(intent);
callbackContext.success();
} catch (Exception e) {
callbackContext.error("CouldNotCallPhoneNumber");
}
}
恍然大悟,作者这样写的那肯定就是直接拨号啊,立刻顺手就改了,改后如下:
private void callPhone(JSONArray args) throws JSONException {
String number = args.getString(0);
number = number.replaceAll("#", "%23");
if (!number.startsWith("tel:")) {
number = String.format("tel:%s", number);
}
try {
/* //自动拨号
Intent intent = new Intent(isTelephonyEnabled() ? Intent.ACTION_CALL : Intent.ACTION_VIEW);
intent.setData(Uri.parse(number));
boolean bypassAppChooser = Boolean.parseBoolean(args.getString(1));
if (bypassAppChooser) {
intent.setPackage(getDialerPackage(intent));
}
*/
//跳转到拨号界面,填充号码,不自动拨号我在修改CFCallNumber.java文件时碰到了权限问题,这个文件被锁定了,所以先修改文件权限,执行如下命令:
Intent intent = new Intent(isTelephonyEnabled() ? Intent.ACTION_DIAL : Intent.ACTION_VIEW);
intent.setData(Uri.parse(number));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
cordova.getActivity().startActivity(intent);
callbackContext.success();
} catch (Exception e) {
callbackContext.error("CouldNotCallPhoneNumber");
}
}
sudo chmod -R 777 (文件路径)
修改文件权限后再按照上面所说的修改插件代码,运行,ok。以前没写过插件,都是网上搜的现成的也没去研究具体怎么实现的,这次顺便研究了下,才发现插件的实现方式还是很好理解的,只要写过安卓就能写了。不能畏惧。
安卓下是ok了,开始改造ios的。同样先去看下插件作者是怎么写的,ios实现拨号是在CFCallNumber.m文件,实现方式如下:
[self.commandDelegate runInBackground:^{虽然能看懂,但也确实不知道怎么改,尝试了网上的各种方法都只能实现直接拨号,翻遍了论坛、博客,最后得出结论:ios没有提供跳转到拨号界面的API!只能直接拨号!可参看以下帖子:
CDVPluginResult* pluginResult = nil;
NSString* number = [command.arguments objectAtIndex:0];
number = [number stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if( ! [number hasPrefix:@"tel:"]){
number = [NSString stringWithFormat:@"tel:%@", number];
}
if(![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:number]]) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"NoFeatureCallSupported"];
}
else if(![[UIApplication sharedApplication] openURL:[NSURL URLWithString:number]]) {
// missing phone number
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"CouldNotCallPhoneNumber"];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
}
// return result
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];
http://www.cocoachina.com/bbs/read.php?tid-1693841-page-1.html
没办法,只能作区分了。最后是在js中先判断设备类型,如果是android设备就直接跳转到拨号界面,是ios设备就在底部弹出拨号确认框(模仿的支付宝,支付宝、美团UI也都是这样做的),代码如下:
$$(document).on('click','#tel_number_content',function () {
var device = Framework7.prototype.device;
if (device.iphone) {
console.log('this is iPhone');
var button_number = [
{
text: '18589082142',
onClick: function () {
window.plugins.CallNumber.callNumber(
function onSuccess(result){
console.log("Success:call number"+result);
},
function onError(result) {
console.log("Error:call number"+result);
},
"18589082142",true);
}
}
];
var button_cancle = [
{
text: '取消',
color: 'red',
onClick: function () {
console.log('ios cancle call 18589082142');
}
}
];
var groups = [button_number, button_cancle];
myApp.actions(groups);
}else{
console.log('this is android');
window.plugins.CallNumber.callNumber(
function onSuccess(result){
console.log("Success:call number"+result);
},
function onError(result) {
console.log("Error:call number"+result);
},
"18589082142",true);
}
});
IOS效果如下: