【问题标题】:Programmatically connect to bluetooth headset from android app以编程方式从 Android 应用程序连接到蓝牙耳机
【发布时间】:2021-04-18 01:07:06
【问题描述】:

如何从我的安卓应用程序连接到蓝牙耳机?我找到了很多关于发现蓝牙设备和配对的教程,而关于连接的教程很少。

【问题讨论】:

    标签: android bluetooth


    【解决方案1】:

    首先,您需要确保蓝牙已启用,然后搜索未配对的设备,然后使用设备地址配对设备。

    成功配对后,您需要连接到设备以及 HSP 或 HFP 配置文件。 请注意,如果没有 HSP(耳机配置文件)或 HFP(免提配置文件),您将无法将呼叫连接到您的耳机或扬声器。

    我列出了步骤,您可以通过谷歌搜索每个步骤轻松找到更多详细信息。 希望这对您有所帮助。

    更新

    我会尽力为您提供更多帮助: 您必须在“src”文件夹下添加一个新包,名称为:android.bluetooth 然后创建 IBluetoothHeadset.aidl

    使用以下代码:

    package android.bluetooth;
    
    import android.bluetooth.BluetoothDevice;
    interface IBluetoothHeadset {
    
    // Public API
    boolean connect(in BluetoothDevice device); //Api 11 and above
    boolean connectHeadset(in BluetoothDevice device); // Below Api 11
    
    boolean disconnect(in BluetoothDevice device);
    boolean disconnectHeadset(in BluetoothDevice device);
        
    List<BluetoothDevice> getConnectedDevices();
    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
    int getConnectionState(in BluetoothDevice device);
    int getState(in BluetoothDevice device);
    boolean setPriority(in BluetoothDevice device, int priority);
    int getPriority(in BluetoothDevice device);
    boolean startVoiceRecognition(in BluetoothDevice device);
    boolean stopVoiceRecognition(in BluetoothDevice device);
    boolean isAudioConnected(in BluetoothDevice device);
    boolean sendVendorSpecificResultCode(in BluetoothDevice device,
                                         in String command,
                                         in String arg);
    
    // APIs that can be made public in future
    int getBatteryUsageHint(in BluetoothDevice device);
    
    // Internal functions, not be made public
    boolean acceptIncomingConnect(in BluetoothDevice device);
    boolean rejectIncomingConnect(in BluetoothDevice device);
    int getAudioState(in BluetoothDevice device);
    
    boolean isAudioOn();
    boolean connectAudio();
    boolean disconnectAudio();
    boolean startScoUsingVirtualVoiceCall(in BluetoothDevice device);
    boolean stopScoUsingVirtualVoiceCall(in BluetoothDevice device);
    void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
    void clccResponse(int index, int direction, int status, int mode, boolean mpty,
                      String number, int type);
    }
    

    然后在你的活动中

         BluetoothDevice DeviceToConnect;
         IBluetoothHeadset ibth; 
         //IBluetoothHeadset instance used to connect and disconnect headset afterwards
    
         // Create and Register BroadCastListener for Action "HEADSET_INTERFACE_CONNECTED"
         // In Broadcast your code has to be something like that
         // if(ibth != null) ibth.connect(DeviceToConnect);
    
         
         //Then After Pairing DeviceToConnect;
         Intent i = new Intent(IBluetoothHeadset.class.getName());
    
        if (bindService(i, HSPConnection, Context.BIND_AUTO_CREATE)) {
    
        } else {
           Log.e("HSP FAILED", "Could not bind to Bluetooth HFP Service");
       }
    
         
          //Method for bind
      public static ServiceConnection HSPConnection= new ServiceConnection() {
            
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                ibth = IBluetoothHeadset.Stub.asInterface(service);
                //ibth instance used to connect and disconnect headset afterwards
                Intent intent = new Intent();
                intent.setAction("HEADSET_INTERFACE_CONNECTED");
                //same as the one we register earlier for broadcastreciever
                                ctx.sendBroadcast(intent);
                //ctx is Instance of Context
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                ibth=null;
            }
    
        };
    

    更新 2:

    <intent-filter> 
      <action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
      <action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
      <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
    </intent-filter>
    

    这些是您必须添加到广播接收器的过滤器。

    蓝牙连接时ACL_CONNECTED信号,蓝牙断开时ACL_DISCONNECTED信号

    对于特定设备,您必须检查广播接收器中的意图/上下文

    因此,您的新接收器(包括以前的接收器)将如下所示:

     BroadcastReceiver bcr = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
               //Device found
            }
            else if (BluetoothAdapter.ACTION_ACL_CONNECTED.equals(action)) {
               //Device is now connected
            }
            else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                //Done searching
            }
            else if (BluetoothAdapter.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
               //Device is about to disconnect
            }
            else if (BluetoothAdapter.ACTION_ACL_DISCONNECTED.equals(action)) {
               //Device has disconnected add whatever way u want to be notified here
               //e.g music-vibration-screen light
            }else if("HEADSET_INTERFACE_CONNECTED".equals(action){
               if(ibth != null) ibth.connect(DeviceToConnect);
            }
        }
    };
    

    我忘了在 Manifest 中添加您需要这 2 个权限:

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    

    【讨论】:

    • 您好,非常感谢您的回复和您的时间。我有信心现在我要放弃了。不过,我想再问你一件事。我可以使用上面的代码连接到我车上的蓝牙设备吗?这样当它断开连接或我超出它的范围时,我会收到通知?
    • @user3389247 很高兴我能提供帮助。请检查我刚刚添加的更新 2 将回答您的新问题。请使用左侧的绿色勾号标记答案,以便帮助其他人/
    • 有人可以协作此回复并使其更易于理解吗?
    • 为了使bindService 调用成功,我必须像这样使Intent 明确:intent.component = ComponentName.createRelative("com.android.bluetooth", ".hfp.HeadsetService")。可以通过运行adb shell dumpsys activity services 并查找 IHeadsetService 来获取 ComponentName。
    • BluetoothHeadset 文档说“使用 BluetoothAdapter#getProfileProxy 获取 BluetoothHeadset 代理对象。”。当我可以从 BluetoothAdapter 获取 .aidl 文件时,我还需要它吗? @MoAdel
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多