3 蓝牙耳机服务
在打开蓝牙过程中,会开启一些对应的服务,在此只将和通话相关的一个服务, HeadsetClientService。手机上只有开启了这个服务,才可以将该手机当作一个蓝牙耳机,通话时声音才可以传输过来。
3.1 准备
首先在启动apk时,会首先启动该apk的Application,然后才是其它组件,因此, Application可以进行一些初始化的操作。Bluetooth.apk 对应的Application是
AdapterApp(classAdapterApp extends Application),其中完成2见事情:
1,加载对应的jni库。
1. static {
2. if (DBG) Log.d(TAG,"Loading JNILibrary");
3. System.loadLibrary("bluetooth_jni");
4. }
2,调用Config 检查哪些服务可以启动。
5. @Override
6. public void onCreate() {
7. super.onCreate();
8. if (DBG) Log.d(TAG,"onCreate");
9. Config.init(this);
10. }
Config里面仅有3个static 方法,只做2见事情。
11. public class Config {
12. private static final String TAG ="AdapterServiceConfig";
13. //List of profile services.
14. @SuppressWarnings("rawtypes")
15. //Do not inclue OPP and PBAP, because theirservices
16. //are not managed by AdapterService
17. private static final Class[] PROFILE_SERVICES = {
18. HeadsetService.class,
19. A2dpService.class,
20. A2dpSinkService.class,
21. HidService.class,
22. HealthService.class,
23. PanService.class,
24. GattService.class,
25. BluetoothMapService.class,
26. HeadsetClientService.class,
27. AvrcpControllerService.class,
28. SapService.class,
29. HidDevService.class
30. };
31. //Resourceflag to indicate whether profile is supported or not.
32. private static final int[] PROFILE_SERVICES_FLAG = {
33. R.bool.profile_supported_hs_hfp,
34. R.bool.profile_supported_a2dp,
35. R.bool.profile_supported_a2dp_sink,
36. R.bool.profile_supported_hid,
37. R.bool.profile_supported_hdp,
38. R.bool.profile_supported_pan,
39. R.bool.profile_supported_gatt,
40. R.bool.profile_supported_map,
41. R.bool.profile_supported_hfpclient,
42. R.bool.profile_supported_avrcp_controller,
43. R.bool.profile_supported_sap,
44. R.bool.profile_supported_hidd
45. };
46.
47. private static Class[] SUPPORTED_PROFILES =new Class[0];
48.
49. static void init(Context ctx) {
50. if (ctx == null) {
51. return;
52. }
53. Resources resources =ctx.getResources();
54. if (resources == null) {
55. return;
56. }
57. ArrayList<Class> profiles = newArrayList<Class>(PROFILE_SERVICES.length);
58. for (int i=0; i <PROFILE_SERVICES_FLAG.length; i++) {
59. boolean supported =resources.getBoolean(PROFILE_SERVICES_FLAG[i]);
60. if (supported) {
61. if(!addAudioProfiles(PROFILE_SERVICES[i].getSimpleName()))
62. continue;
63. Log.d(TAG, "Adding "+ PROFILE_SERVICES[i].getSimpleName());
64. profiles.add(PROFILE_SERVICES[i]);
65. }
66. }
67. int totalProfiles = profiles.size();
68. SUPPORTED_PROFILES = newClass[totalProfiles];
69. profiles.toArray(SUPPORTED_PROFILES);
70. }
71.
72. @SuppressWarnings("rawtypes")
73. private static synchronized boolean addAudioProfiles(String serviceName) {
74. boolean isA2dpSinkEnabled =SystemProperties.getBoolean("persist.service.bt.a2dp.sink",false);
75. boolean isHfpClientEnabled =SystemProperties.getBoolean("persist.service.bt.hfp.client",false);
76. if((serviceName.equals("A2dpSinkService"))&&(!isA2dpSinkEnabled))
77. return false;
78. if((serviceName.equals("A2dpService"))&&(isA2dpSinkEnabled))
79. return false;
80.
81. if((serviceName.equals("HeadsetClientService"))&&(!isHfpClientEnabled))
82. return false;
83. if((serviceName.equals("HeadsetService"))&&(isHfpClientEnabled))
84. return false;
85.
86. return true;
87. }
88.
89. static Class[] getSupportedProfiles(){