zoukankan      html  css  js  c++  java
  • Android实现主动连接蓝牙耳机

    在Android程序中可以实现自动扫描蓝牙、配对蓝牙、建立数据通道。
    蓝牙分不同类型,可以参考(http://gqdy365.iteye.com/admin/blogs/2229304)
    可以入下面方法获取蓝牙设备支持的类型:

    Java代码  收藏代码
    1. BluetoothDevice device;  
    2. Arrays.toString(device.getUuids());  



    我的蓝牙音箱支持的类型有:

    Java代码  收藏代码
    1. 0000111e-0000-1000-8000-00805f9b34fb:Handsfree  
    2. 0000110b-0000-1000-8000-00805f9b34fb:AudioSink  
    3. 0000110e-0000-1000-8000-00805f9b34fb:AVRemoteControl  
    4. 00001203-0000-1000-8000-00805f9b34fb:GenericFileTransfer  



    这篇文字只讨论如何与蓝牙耳机(蓝牙音箱)连接。
    蓝牙耳机一般都支持A2DP(蓝牙立体声,用于音乐播放)、HFP协议(通话),参考:http://gqdy365.iteye.com/admin/blogs/2231553
    所以下面操作要同时操作A2DP和HFP,两个都连接成功,才算连接成功;

    一、A2DP的操作可以分三步:

    1、扫描蓝牙设备:
    注册并监听广播:

    Java代码  收藏代码
    1. BluetoothAdapter.ACTION_DISCOVERY_STARTED  
    2. BluetoothDevice.ACTION_FOUND  
    3. BluetoothAdapter.ACTION_DISCOVERY_FINISHED  


    启动扫描:

    Java代码  收藏代码
    1. BluetoothAdapter.getDefaultAdapter().startDiscovery();  



    对扫描的结果按类型进行筛选,只保留我们需要的蓝牙耳机:

    Java代码  收藏代码
    1.         if(device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET  
    2.                 || device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE){  
    3. //蓝牙耳机  
    4. }  



    2、配对指定的蓝牙设备:
    这个跟配对普通蓝牙一样,方法如下:

    Java代码  收藏代码
    1. public static  boolean createBond(BluetoothDevice btDevice){  
    2.     boolean result = false;  
    3.     try{  
    4.         Method m = btDevice.getClass().getDeclaredMethod("createBond",new Class[]{});  
    5.         m.setAccessible(true);  
    6.         Boolean originalResult = (Boolean) m.invoke(btDevice);  
    7.         result = originalResult.booleanValue();  
    8.     }catch(Exception ex){  
    9.     }  
    10.     return result;  
    11. }  



    等配对完成之后就是要建立数据连接;

    3、建立数据连接:

    if you SDK between 11 and 16.call a2dp.connectSink(btDevice) or a2dp.connect(btDevice)

    Java代码  收藏代码
    1. private static IBluetoothA2dp getIBluetoothA2dp() {  
    2.     IBluetoothA2dp ibta = null;  
    3.   
    4.     try {  
    5.         final Class serviceManager = Class.forName("android.os.ServiceManager");  
    6.         final Method getService = serviceManager.getDeclaredMethod("getService", String.class);  
    7.         final IBinder iBinder = (IBinder) getService.invoke(null, "bluetooth_a2dp");  
    8.         final Class iBluetoothA2dp = Class.forName("android.bluetooth.IBluetoothA2dp");  
    9.         final Class[] declaredClasses = iBluetoothA2dp.getDeclaredClasses();  
    10.         final Class c = declaredClasses[0];  
    11.         final Method asInterface = c.getDeclaredMethod("asInterface", IBinder.class);  
    12.   
    13.         asInterface.setAccessible(true);  
    14.         ibta = (IBluetoothA2dp) asInterface.invoke(null, iBinder);  
    15.     } catch (final Exception e) {  
    16.         Log.e("Error " + e.getMessage());  
    17.     }  
    18.     return ibta;  
    19. }  


    参考:http://stackoverflow.com/questions/8467178/working-around-a2dp-and-hfp-limitations-of-android-pre-honeycomb

    如果API大于16需要用如下的方法:

    Java代码  收藏代码
    1.     private void initA2dpService(){  
    2. //      Intent i = getExplicitIntent(mContext,new Intent(IBluetoothA2dp.class.getName()));//5.0以上系统需要显示intent  
    3. //详细参考http://blog.csdn.net/l2show/article/details/47421961  
    4.         Intent i = new Intent(IBluetoothA2dp.class.getName());  
    5.         boolean success = mContext.bindService(i, mConnection, Context.BIND_AUTO_CREATE);  
    6.         if (success) {  
    7.   
    8.         } else {  
    9.         }  
    10.     }  
    11.   
    12.     public ServiceConnection mConnection = new ServiceConnection() {  
    13.   
    14.         @Override  
    15.         public void onServiceConnected(ComponentName name, IBinder service) {  
    16.             try {  
    17.                 mA2dpService = IBluetoothA2dp.Stub.asInterface(service);  
    18.             } catch (Exception e) {  
    19.                 e.printStackTrace();  
    20.             }  
    21.         }  
    22.   
    23.         @Override  
    24.         public void onServiceDisconnected(ComponentName name) {  
    25.             // TODO Auto-generated method stub  
    26.   
    27.         }  
    28.   
    29.     };  
    30.       
    31.     public Intent getExplicitIntent(Context context, Intent implicitIntent) {  
    32.         // Retrieve all services that can match the given intent  
    33.         PackageManager pm = context.getPackageManager();  
    34.         List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);  
    35.         // Make sure only one match was found  
    36.         if (resolveInfo == null || resolveInfo.size() != 1) {  
    37.             return null;  
    38.         }  
    39.         // Get component info and create ComponentName  
    40.         ResolveInfo serviceInfo = resolveInfo.get(0);  
    41.         String packageName = serviceInfo.serviceInfo.packageName;  
    42.         String className = serviceInfo.serviceInfo.name;  
    43.         ComponentName component = new ComponentName(packageName, className);  
    44.         // Create a new intent. Use the old one for extras and such reuse  
    45.         Intent explicitIntent = new Intent(implicitIntent);  
    46.         // Set the component to be explicit  
    47.         explicitIntent.setComponent(component);  
    48.         return explicitIntent;  
    49.     }  


    建立连接:mA2dpService.connect(device);
    断开连接:mA2dpService.disconnect(device);

    参考:http://stackoverflow.com/questions/14705167/how-connect-paired-bluetooth-a2dp-device-on-android-4-2-using-reflection

    http://blog.csdn.net/qs_csu/article/details/45114251

    二、HFP操作:
    下面只针对4.0及以上版本;
    1、初始化:

    Java代码  收藏代码
    1. private void initOrCloseBtCheck(boolean init){  
    2.     if(init){  
    3.         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  
    4.         mBluetoothAdapter.getProfileProxy(mContext, new ServiceListener() {  
    5.             public void onServiceConnected(int profile, BluetoothProfile proxy) {  
    6.                 if (profile == BluetoothProfile.HEADSET) {  
    7.                     mBluetoothHeadset = (BluetoothHeadset) proxy;  
    8.                 }  
    9.             }  
    10.   
    11.             public void onServiceDisconnected(int profile) {  
    12.                 if (profile == BluetoothProfile.HEADSET) {  
    13.                     mBluetoothHeadset = null;  
    14.                 }  
    15.             }  
    16.         },BluetoothProfile.HEADSET);  
    17.     }else{  
    18.         mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET,mBluetoothHeadset);  
    19.     }  
    20. }  



    建立连接:

    Java代码  收藏代码
    1.          Method m = mBluetoothHeadset.getClass().getDeclaredMethod("connect",BluetoothDevice.class);    
    2. m.setAccessible(true);  
    3. //连接Headset  
    4. boolean successHeadset = (Boolean)m.invoke(mBluetoothHeadset, device);  



    断开连接:

    Java代码  收藏代码
    1.          Method m = mBluetoothHeadset.getClass().getDeclaredMethod("disconnect",BluetoothDevice.class);    
    2. m.setAccessible(true);  
    3. m.invoke(mBluetoothHeadset, device);  




    三、状态判断:

    蓝牙耳机连接成功:

    Java代码  收藏代码
    1. mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_DISCONNECTED && mBluetoothHeadset.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED  


    断开成功:

    Java代码  收藏代码
      1. (mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_CONNECTED || mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_PLAYING)  
      2.                                 && mBluetoothHeadset.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED 
  • 相关阅读:
    接口的理解
    Application.DoEvents()笔记
    c#的DateTime.Now函数详解---来源(笨鸟先飞)
    怎么判断字符串a的内容包含字符串b的内容
    c#下怎么判断一个字符串是否可以转换为double类型
    .net中TreeView使用方法小结(2)
    .net中TreeView使用方法小结(1)
    TT企业微信社群辅助,企业微信社群辅助工具,允许批量添加好友,自动同意添加请求,自动回复消息
    TokenMismatchException Laravel
    实现Nginx Upload 模块 功能上传文件。
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/6514529.html
Copyright © 2011-2022 走看看