pc 电脑web浏览器js通过usb控制安卓手机打电话挂电话
效果预览
分析与介绍
基于js/javascript通过usb数据线控制安卓手机打电话拔号或挂断的需求即浏览器通过usb数据线控制安卓手机打电话拔号或挂断的一键拔号。
技术构架: PC电脑(google浏览器,firefox浏览器,360浏览器) 的js/javascripts通过usb数据线连接安卓手机,控制安卓手机打电话拔号或挂断。
应用场景:CRM客户管理系统,产品订单系统 等需要大量对客户进行电话访问的工作,工作人员戴上耳机,通过网页按钮一键拔号和挂断,可直接不再需要工作人员拿起电话按键拔号 挂断电话等重复劳动。
特点:趋近于零成本,这年头安卓手机普及率非常高,即使没有,无游戏需求的通话型安卓手机,其价格也才几百元左右,客服团队增加十人,也只是加十台手机。
相对于租用传统电话呼叫中心,根据使用规模定义出 小型电话呼叫中心 中型电话呼叫中心 大型电话呼叫中心,其价格就几万至几十万不等每年。
时代背景:在以前,电脑就是电脑,电话就是电话,手机就是手机,而我们的大量客户资料管理。客户服务都是电脑端,如果不购买价格昂贵的电话呼叫中心,就需要重复的拿起电话,对着客户资料按键号码,按键呼叫,再挂断,放下电话。完成一次通话,固定得要付出1-2分钟用于非通话操作。而安卓手机时代,就改变了这样的格局,我们能够通过只是原来百分之一的成本,就能够实现原来的需求。
原始测试界面 (号码为随便书写 )
视频演示: http://www.meipai.com/media/861369712
开发技术组成
html+js+websocket ,在电脑上浏览器的权限是有限的,这是为了电脑安全而设定的规则,要在浏览器上与电脑通信与安卓通信,那么必然是使用websocket。
adb , adb全名AndoridDebug Bridge. 顾名思义, 这是一个Debug工具,是一个桥,实现usb连接电脑和手机的桥,在这里主要实现websocke端口转发。
websocketserver ,在手机端,安卓app实现websocket的服务端,实现对websocket客户端拔号,挂断的请求响应。
程序健壮性开发
adb的运行是基于usb数据库连通的情况下,如果用户拔出了usb数据线,在下次重新插上usb数据线,adb是不会重新运行的,这里则需要实现自动化重新运行。同时,端口转发也是需要实现usb断开后连接的自动重新设置。
app需要防止异常关闭异常退出,这里需要做监控,一旦app异常关闭,则马上自动启动,避免响应拔号请求失败。
开发代码段介绍
html+js+websocket 实现部分
function call(number){
if(number != '10086' && number !='10010'&& number !='0'){
var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
if(!myreg.test(number)) {
alert('手机号码格式错误');
return;
}
}
var ws = new WebSocket('ws://127.0.0.1:50000');
ws.onopen = function(event) {
ws.send(number)
};
ws.onerror = function(event){
alert('手机连接失败,请检查USB连接是否拔除,如果已重新连接USB,请等待一小会');
}
ws.onmessage = function(event) { //监听中
var content = event.data;
//返回输入的号码
console.log('即将拔打:'+content)
//用完就关
ws.close();
};
ws.onclose = function(event){
console.log('关闭连接');
}
}
adb桥代码实现部分
::检查USB连通性,通过端口转发监听是否存在
netstat -ano | findstr 127.0.0.1 | findstr 50000
IF ERRORLEVEL 1 (
echo usb is not connect > debug.txt
adb forward tcp:50000 tcp:8888
adb start-server
exit
)
::检查app是否已经安装
adb shell pm list packages telhelper | findstr "com.example.admin.telhelper"
IF ERRORLEVEL 1 (
echo install and start > debug.txt
::安装并启动
adb install -f c:\android\app20170920.apk
adb shell am start -n com.example.admin.telhelper/com.example.admin.telhelper.MainActivity
) else (
::如果已经安装 检查是否运行
adb shell "ps | grep u0_" | findstr "com.example.admin.telhelper"
IF ERRORLEVEL 1 (
echo install but not run > debug.txt
adb shell am start -n com.example.admin.telhelper/com.example.admin.telhelper.MainActivity
)
)
exit;
::-----------------------------------------
app响应电脑拔号请求或挂断请求代码
拔打电话
publicvoid call(){
if(serverManager != null) {
if (serverManager.tel != null) {
String tel = serverManager.tel;
if(tel.equals("0")){
serverManager.tel = null;
closeCall();
}else {
serverManager.tel = null;
Intent intent = newIntent(Intent.ACTION_CALL, Uri.parse("tel:" + tel));
startActivity(intent);
}
//删除通话记录 功能已移动到通话状态监听事件中
/**
ContentResolver cResolver =getContentResolver();
Uri callUri =Uri.parse("content://call_log/calls");
cResolver.delete(callUri, null,null);
**/
}
}
//call(serverManager);
}
//挂断电话
private void closeCall()
{
try
{
//通过反射拿到android.os.ServiceManager里面的getService这个方法的对象
Method method =Class.forName("android.os.ServiceManager").getMethod("getService",String.class);
//通过反射调用这个getService方法,然后拿到IBinder对象
IBinder iBinder = (IBinder)method.invoke(null, new Object[] {TELEPHONY_SERVICE});
ITelephony telephony =ITelephony.Stub.asInterface(iBinder);
telephony.endCall();
}
catch (Exception e)
{
e.printStackTrace();
}
}
初始化websocket server并监听请求,自动下载 包 java-websocket-1.3.0.jar
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView t1 = (TextView)findViewById(R.id.t1);
t1.setText("拔号服务运行中...");
serverManager=new ServerManager();
serverManager.Start(8888);
Timer timer = new Timer();
TimerTask task = new TimerTask(){
public void run() {
call();
}
};
timer.schedule (task, 100, 100);
moveTaskToBack(true);
}