2016年9月10日星期六

Android Implementation Connect Bluetooth Headset Automaticaly




In Android applications can realize automatic scanning bluetooth, pairing bluetooth, data channel is established. 
Bluetooth is divided  into different types, you can refer to (http://gqdy365.iteye.com/admin/blogs/2229304)
May enter the type of the following methods for bluetooth devices support:


Java Code
1.  BluetoothDevice device;  
2.  Arrays.toString(device.getUuids());  

My bluetooth speakers support types are:
Java Code
1.  0000111e-0000-1000-8000-00805f9b34fbHandsfree  
2.  0000110b-0000-1000-8000-00805f9b34fbAudioSink  
3.  0000110e-0000-1000-8000-00805f9b34fbAVRemoteControl  
4.  00001203-0000-1000-8000-00805f9b34fbGenericFileTransfer  

Only this article will discuss how to connect to bluetooth headset( bluetooth speakers ). 

Bluetooth headsets are generally support A2DP (bluetooth stereo, for music playback), HFP protocol (call), refer to: http://gqdy365.iteye.com/admin/blogs/2231553

So the following operation to operating A2DP and HFP at the same time, both the connection is successful, are successful connection;
First, The operation of the A2DP can divide three steps:
1, Scanning bluetooth devices:
    Register and listening radio:
Java Code
1.  BluetoothAdapter.ACTION_DISCOVERY_STARTED  
2.  BluetoothDevice.ACTION_FOUND  
3.  BluetoothAdapter.ACTION_DISCOVERY_FINISHED  

Start scanning:
Java Code
1.  BluetoothAdapter.getDefaultAdapter().startDiscovery();  

Filtered according to the results of scanning type, only keep the bluetooth headset we need:
Java Code
1.          if(device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET  
2.                  || device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE){  
3.  //bluetooth headset  
4.  }  

2, Pairing the specified Bluetooth device:
 As like pairing the ordinary bletooth,methods as following:
Jave Code
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. }  

It will be connect after finishing pairing;
3, Establishing Connect data

if you SDK between 11 and 16.call a2dp.connectSink(btDevice) or a2dp.connect(btDevice)
 
Java Code
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. }  

Refer to http://stackoverflow.com/questions/8467178/working-around-a2dp-and-hfp-limitations-of-android-pre-honeycomb 
If API is more than 16 need yo use as following methods:
Jave Code
1.      private void initA2dpService(){  
2.  //      Intent i = getExplicitIntent(mContext,new Intent(IBluetoothA2dp.class.getName()));//5.0 above system need to show intent  
3.  //detail reference : 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.     }  

Connect:mA2dpService.connect(device); 
Disconnect:mA2dpService.disconnect(device); 
Refer to 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
 

Second,  HFP operation:
As following is for Version 4.0 or above;
1. Originally
Jave Code
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. }  

 Connected:
1.           Method m = mBluetoothHeadset.getClass().getDeclaredMethod("connect",BluetoothDevice.class);    
2.  m.setAccessible(true);  
3.  //connect Headset  
4.  boolean successHeadset = (Boolean)m.invoke(mBluetoothHeadset, device);  

Disconnect:
Java Code
1.           Method m = mBluetoothHeadset.getClass().getDeclaredMethod("disconnect",BluetoothDevice.class);    
2.  m.setAccessible(true);  
3.  m.invoke(mBluetoothHeadset, device);  



Third, State judgment:
Bluetooth earphone connect successfully:
Java Code
1.  mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_DISCONNECTED && mBluetoothHeadset.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED  

Disconnect succefully:
 Java Code
1.  (mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_CONNECTED || mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_PLAYING)  
2.                                  && mBluetoothHeadset.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED  


没有评论:

发表评论