pc 电脑web浏览器js通过usb控制安卓手机打电话挂电话

pc 电脑web浏览器js通过usb控制安卓手机打电话挂电话

分析与介绍

基于js/javascript通过usb数据线控制安卓手机打电话拔号或挂断的需求即浏览器通过usb数据线控制安卓手机打电话拔号或挂断的一键拔号。

技术构架: PC电脑(google浏览器,firefox浏览器,360浏览器) 的js/javascripts 通过usb数据线连接安卓手机,控制安卓手机打电话拔号或挂断。

应用场景:CRM客户管理系统,产品订单系统 等需要大量对客户进行电话访问的工作,工作人员戴上耳机,通过网页按钮一键拔号和挂断,可直接不再需要工作人员拿起电话 按键拔号 挂断电话等重复劳动。

特点:趋近于零成本,这年头安卓手机普及率非常高,即使没有,无游戏需求的通话型安卓手机,其价格也才几百元左右,客服团队增加十人,也只是加十台手机。
相对于租用传统电话呼叫中心,根据使用规模定义出 小型电话呼叫中心 中型电话呼叫中心 大型电话呼叫中心,其价格就几万至几十万不等每年。

时代背景:在以前,电脑就是电脑,电话就是电话,手机就是手机,而我们的大量客户资料管理。客户服务都是电脑端,如果不购买价格昂贵的电话呼叫中心,就需要重复的拿起电话,对着客户资料按键号码,按键呼叫,再挂断,放下电话。完成一次通话,固定得要付出1-2分钟用于非通话操作。 而安卓手机时代,就改变了这样的格局,我们能够通过只是原来百分之一的成本,就能够实现原来的需求。

原始测试界面 (号码为随便书写 )
112.jpg

视频演示: http://www.meipai.com/media/861369712

开发技术组成

html+ js+websocket ,在电脑上浏览器的权限是有限的,这是为了电脑安全而设定的规则,要在浏览器上与电脑通信 与安卓通信,那么必然是使用 websocket。

adb , adb全名Andorid Debug Bridge. 顾名思义, 这是一个Debug工具,是一个桥,实现usb连接电脑和手机的桥,在这里主要实现websocke端口转发。

websocket server ,在手机端,安卓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桥代码实现部分

@ECHO ON
C:
cd C:\android
::BY SHW 2017/09/18
::功能描述
::通用服务调用,每秒实时检查 1. USB是否连接 2.app是否已安装/安装 3.app是否已启动/启动

::检查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响应电脑拔号请求或挂断请求代码

//初始化app 监听拔号请求
    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);

    }
    
    //拔号
    public void 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 = new Intent(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();
        }
    }

标签: 移动开发

非特殊说明,本博所有文章均为博主原创。

最新文章

2 条评论

  1. 芃芃

    大神,你好,我们的app是webapp,app响应电脑拔号请求或挂断请求代码该怎么改,还有adb代码放在哪里,我没懂这个

    1. shw3588
      @芃芃

      你好,你的app是webapp,说明是H5 且不需要adb代理,也无法开启socket服务端。 应该在网络中另搭建一台服务器部署socket服务端。电脑网页上点击要拔号,请求是转到socket服务端,socket服务端再转发给相就手机,手机响应并拔号即可。这是那会我不使用USB数据线的另一个方式。 其实现在市面上有蛮多成型的低成本硬件软件可以用,未必要这么折腾。

发表评论 取消回复