Android通过蓝牙获取手机短信技术调研

      对“直接通过蓝牙来获取连接手机的短信信息”这个需求做了一些技术调研,如下是调研过程中的一些记录(持续更新中)。

1、无法得到BluetoothMasClient类

     在文章https://blog.csdn.net/u012439416/article/details/54349812(蓝牙map协议源码解析)这篇文章中有提到通过MAP方式来实现蓝牙读取短信,具体的实现方式为:

 1  //注册广播
 2  IntentFilter filter = new IntentFilter();  
 3  filter.addAction("android.bluetooth.device.action.SDP_RECORD");
 4  registerReceiver(mReceiver, filter);
 5  //监听广播
 6  private final BroadcastReceiver mReceivers = new BroadcastReceiver() {
 7      @Override
 8      public void onReceive(Context context, Intent intent) {
 9          String action = intent.getAction();
10         if (action.equals(BluetoothDevice.ACTION_SDP_RECORD)) {
11             BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
12             ParcelUuid uuid = intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID);
13             if (uuid.equals(BluetoothUuid.MAS)) {
14                 SdpMasRecord masrec =
15                         intent.getParcelableExtra(BluetoothDevice.EXTRA_SDP_RECORD);
16                  BluetoothMasClient mapclient = new BluetoothMasClient(mDevice, masrec,
17                         mMapHandler);
18             }
19         }
20     }
21 };

    这里面有些类和属性,在API-27及以上已经被加了@hide标签,当然这一点供应商提供的提供可以解决。在调试过程中,上述广播也能监听到。但第16行的红色字体部分有个比较关键的类BluetoothMasClient,获取短信信息的方法都需要通过该类实例来完成,在API-27(Android8.1)及以上系统都无法获取到。

(1)API-27上无法直接引用BluetoothMasClient类

          在系统源码frameworks\opt\bluetooth\src\android\bluetooth\client\map下可以找到该类,引用路径为"android.bluetooth.client.map.BluetoothMasClient",使用时发现无法引用这个类。

Android通过蓝牙获取手机短信技术调研_第1张图片

 

在源码中可以找到

            Android通过蓝牙获取手机短信技术调研_第2张图片

在使用时无法调用

(2)在API-27(Android8.1)无法通过反射获取到BluetoothMasClient类

        通过反射的方式,也无法获取到该类。测试代码:

 1 public void getBluetoothMasClient() {
 2     Log.d(TAG, "testGetHide");
 3     try {
 4         Class c = Class.forName("android.bluetooth.client.map.BluetoothMasClient");
 5         Log.d(TAG, "name=" + c.getName());
 6     } catch (ClassNotFoundException e) {
 7         Log.d(TAG, "e=" + e.getMessage());
 8         e.printStackTrace();
 9     }
10 }

运行结果:

 1  W/System.err: java.lang.ClassNotFoundException: android.bluetooth.client.map.BluetoothMasClient
 2  W/System.err:     at java.lang.Class.classForName(Native Method)
 3  W/System.err:     at java.lang.Class.forName(Class.java:453)
 4  W/System.err:     at java.lang.Class.forName(Class.java:378)
 5  W/System.err:     at com.example.demo.sms.BTActivity.testGetHide(BTActivity.java:489)
 6  W/System.err:     at com.example.demo.sms.BTActivity.onCreate(BTActivity.java:73)
 7  W/System.err:     at android.app.Activity.performCreate(Activity.java:7050)
 8  W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
 9  W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2809)
10  W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2931)
11  W/System.err:     at android.app.ActivityThread.-wrap11(Unknown Source:0)
12  W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1620)
13  W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:105)
14  W/System.err:     at android.os.Looper.loop(Looper.java:176)
15  W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6701)
16  W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
17  W/System.err:     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:249)
18  W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)

(3)API-28(Android9.0)上该类已经不存在了

      在AS中搜索该类,以及在系统源码中按照之前的路径,都无法再找到该类。

      

Android通过蓝牙获取手机短信技术调研_第3张图片

 2、没有找到核心类调用短信信息

      在文章https://www.jianshu.com/p/3696923aa4f7(Android蓝牙应用开发全面总结)中以Headset Profile为例,介绍了一种连接协议的代码实现:

 1 BluetoothHeadset mBluetoothHeadset;
 2 // 获取默认的Bluetooth适配器
 3 BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 4 // 连接Headset profile
 5 mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
 6 private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener(){
 7     public void onServiceConnected(int profile, BluetoothProfile proxy) {
 8         if (profile == BluetoothProfile.HEADSET) {
 9             mBluetoothHeadset = (BluetoothHeadset) proxy;
10         }
11     }
12     public void onServiceDisconnected(int profile) {
13         if (profile == BluetoothProfile.HEADSET) {
14             mBluetoothHeadset = null;
15         }
16     }
17 };
18 
19 // ... 使用 mBluetoothHeadset
20 
21 // 使用之后,关闭Proxy
22 mBluetoothAdapter.closeProfileProxy(mBluetoothHeadset)

 这里面提供了一个实现模式,我们似乎只要将Headset相关的东西依葫芦画瓢换成MAP相关的就可以了。这里面有两个问题(1)API-27及以上系统中,BluetoothProfile类中MAP常量是带有@hide标签的,这一点可以通过供应商修改框架代码来解决。(2)没有找到核心类调用短信信息。正如第一点中提到的BluetoothMasClient类,该类可以调用一些方法来获取短信信息,而目前就正是没有找到这样一个类来完成相同的功能。所以该方案也没法实现。

你可能感兴趣的:(Android通过蓝牙获取手机短信技术调研)