Android开发,如何编程实现开启电话的免提功能?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开发,如何编程实现开启电话的免提功能?相关的知识,希望对你有一定的参考价值。

    JAVA编写,对应拨打电话只需要调用ACTION_CALL加对应电话号码可以如下编写:

view plaincopy
void callPhone()    
           Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:110")); //不能调用呼叫    
           intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);     
           startActivity(intent);    
       

    但是当拨打110,119,120等紧急电话时,无法自动呼出,还需要用户进行确认操作,那么就需要实现直接进行呼叫,但是前提app必须用系统级别权限,及system/app/目录下方可。

      首先确保应用具有如下权限:

view plaincopy
<uses-permission android:name="android.permission.READ_PHONE_STATE" />    
<uses-permission android:name="android.permission.CALL_PHONE" />    
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>    
<uses-permission android:name="android.permission.CALL_PRIVILEGED" />

      同样调用intent来开启功能,不过内容有些变化

view plaincopy
void callPhone(String num)    
        Intent intent = new Intent("android.intent.action.CALL_PRIVILEGED",Uri.parse("tel:"+num));    
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);     
        startActivity(intent);    
    


      然后在源码下编译,放到/system/app/即可使用。

    开启拨通电话后设置开启扬声器功能:

      首先,获取音频管理器:audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);

      设置电话监听:

view plaincopy
private class TelListner extends PhoneStateListener  
        boolean comingPhone=false;  
          
        @Override  
        public void onCallStateChanged(int state, String incomingNumber)   
               switch (state)   
               case TelephonyManager.CALL_STATE_IDLE:/* 无任何状态 */  
                   Log.d(tag, "phone idle");  
                  if(this.comingPhone)  
                      this.comingPhone=false;  
                      backMyApp();  
                      setSpeekModle(false);  
                    
                   break;  
               case TelephonyManager.CALL_STATE_OFFHOOK:/* 接起电话 */  
                    Log.d(tag, "phone answer");  
                    this.comingPhone=true;  
                    setSpeekModle(true);  
                   break;  
               case TelephonyManager.CALL_STATE_RINGING:/* 电话进来 */  
                   Log.d(tag, "phone coming");  
                   this.comingPhone=true;  
                   setSpeekModle(true);  
                   break;  
                 
           
    

      注册监听类: 

view plaincopy
TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);  
          TelListner listener = new TelListner() ;  
          telManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);

      开启或关闭免提功能:

view plaincopy
void setSpeekModle(boolean open)  
        //audioManager.setMode(AudioManager.ROUTE_SPEAKER);  
        currVolume = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);  
        audioManager.setMode(AudioManager.MODE_IN_CALL);   
  
        if(!audioManager.isSpeakerphoneOn()&&true==open)   
          audioManager.setSpeakerphoneOn(true);  
          audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,  
                 audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),  
                 AudioManager.STREAM_VOICE_CALL);  
        else if(audioManager.isSpeakerphoneOn()&&false==open)  
                 audioManager.setSpeakerphoneOn(false);  
                 audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,currVolume,  
                            AudioManager.STREAM_VOICE_CALL);  
          
    

      添加权限:

view plaincopy
<uses-permission android:name="android.permission.READ_PHONE_STATE" />  
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

参考技术A 免提就是把Speaker打开。
AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setSpeakerphoneOn(true);
-------------------------------------------------------------
更多疑问解答,请关注@安卓互助平台 新浪微博本回答被提问者采纳

如何通过 Android 中的免提音频网关通过 AG 发起来自 HF 的呼叫?

【中文标题】如何通过 Android 中的免提音频网关通过 AG 发起来自 HF 的呼叫?【英文标题】:How to initiate a call from HF through AG via Handfree Audio Gateway in Android? 【发布时间】:2014-06-17 07:21:39 【问题描述】:

到目前为止,我已经能够通过蓝牙连接从加载了我的应用程序的手机(HF 或免提)向目标手机发起呼叫,从 Android 手机 AG(音频网关) .我已将此代码用于此过程:

   ///////////////////////////////////////////////////////////////////////////////         
           //Here, how to establish voice connectivity from AG to my phone(HF)?
    //////////////////////////////////////////////////////////////////////////////        

        // Calling the target phone from the AG via the HF using bluetooth Handfree Audio Gateway
            try 
                mmOutStream.write(("ATD"+phone_number+"\r").getBytes());
             catch (IOException e1) 
                // TODO Auto-generated catch block
                e1.printStackTrace();
            
            try 
                Thread.sleep(1000);
             catch (InterruptedException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            

现在,我可以通过免提 (HF) 设备拨打电话,但我无法听到铃声或对方说话。

到目前为止,我似乎刚刚能够触发调用机制。如何建立音频连接,以便我既能听到目标手机上的扬声器也能说话?

【问题讨论】:

【参考方案1】:

您似乎正在尝试在电话上实现免提单元角色。 这样做的一种方法是,如果您有 2 部电话,电话 A(表现为 AG),电话 B(免提单元)然后

    电话 B 需要向电话 A 发送适当的 AT 命令,以使其自身显示为蓝牙耳机。如果这样做正确,那么我认为电话 A 不需要任何更改即可将音频路由到蓝牙 SCO 链接。要查看免提单元发送了哪些 AT 命令,连接到标准蓝牙耳机的电话 A (AG) 的日志可能会有所帮助。或免提规范。

    在电话 B 上,假设所有 AT 命令已发送到电话 A 以使其自身显示为 HF 单元,然后通过从电话 B 发送 ATD 来建立呼叫(电话 A 到远程方) , 电话 A 可以像使用标准蓝牙耳机一样设置 SCO。 如果没有,那么电话 B 可能必须调用 AudioManager.startBluetoothSco() 来设置 SCO。 除了设置 SCO 之外,电话 B 还必须将音频路由到 SCO。我认为 API 是 AudioManager.SetMode() 和 AudioManager.setBluetoothScoOn()。

【讨论】:

是的,但是如何让 HF 在 AG 看来就像一个蓝牙耳机? HFU 必须使用 uuid 为 HFU 注册 RFCOMM 服务器,一旦连接成功,向 AG 发送 AT 命令(AT+BRSF 等)。您可能会发现此链接很有用***.com/questions/16610811/… 我已经在使用您提供的链接:)。目前我正在使用它本身(免提音频网关)。但显然,使用它进行连接并不足以使 HF 看起来像 AG 的耳机。我也尝试过(耳机音频网关),但效果不大。 AG 没有其他相关服务可用(我以编程方式检查)。所以我被困住了。 我认为您无法连接 AG-AG。在 HF 端,您是否为 HFU 注册了一个带有相应 SDP 记录的 RFCOMM 套接字?适配器.listenUsingRfcommWithServiceRecord。 AG 和 HFU 有不同的 UUID。这将允许 AG 连接到 HF。另外我认为 HF 侧的设备类别需要更新为音频主要设备和免提次要设备。我不确定是否有 API 可以做到这一点.. 问题是要求我只控制 HF 端,而在 AG 端我不应该以编程方式做任何事情。

以上是关于Android开发,如何编程实现开启电话的免提功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 android Pie 和 UP 中以编程方式打开/关闭扬声器

免提通话期间通过电话扬声器播放声音

小天才电话手表z5的系统既然基于android,那么如何开启adb调试或者如何进入recvory呢

如何通过 Android 中的免提音频网关通过 AG 发起来自 HF 的呼叫?

检测 Android 设备上缺少听筒(仅限扬声器)

Blackberry - EventInjector 激活扬声器