服务器之家

服务器之家 > 正文

Android提高之蓝牙隐藏API探秘

时间:2021-03-07 14:43     来源/作者:Android开发网

前面文章讲解了android的蓝牙基本用法,本文讲得深入些,探讨下蓝牙方面的隐藏api。用过android系统设置(setting)的人都知道蓝牙搜索之后可以建立配对和解除配对,但是这两项功能的函数没有在sdk中给出,那么如何去使用这两项功能呢?本文利用java的反射机制去调用这两项功能对应的函数:createbond和removebond,具体的发掘和实现步骤如下:

1.使用git工具下载platform/packages/apps/settings.git,在setting源码中查找关于建立配对和解除配对的api,知道这两个api的宿主(bluetoothdevice);

2.使用反射机制对bluetoothdevice枚举其所有方法和常量,看看是否存在:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static public void printallinform(class clsshow) {
 try {
 // 取得所有方法
 method[] hidemethod = clsshow.getmethods();
 int i = 0;
 for (; i < hidemethod.length; i++) {
  log.e("method name", hidemethod[i].getname());
 }
 // 取得所有常量
 field[] allfields = clsshow.getfields();
 for (i = 0; i < allfields.length; i++) {
  log.e("field name", allfields[i].getname());
 }
 } catch (securityexception e) {
 // throw new runtimeexception(e.getmessage());
 e.printstacktrace();
 } catch (illegalargumentexception e) {
 // throw new runtimeexception(e.getmessage());
 e.printstacktrace();
 } catch (exception e) {
 // todo auto-generated catch block
 e.printstacktrace();
 }
}

结果如下:

11-29 09:19:12.012: method name(452): cancelbondprocess
11-29 09:19:12.020: method name(452): cancelpairinguserinput
11-29 09:19:12.020: method name(452): createbond
11-29 09:19:12.020: method name(452): createinsecurerfcommsocket
11-29 09:19:12.027: method name(452): createrfcommsocket
11-29 09:19:12.027: method name(452): createrfcommsockettoservicerecord
11-29 09:19:12.027: method name(452): createscosocket
11-29 09:19:12.027: method name(452): describecontents
11-29 09:19:12.035: method name(452): equals
11-29 09:19:12.035: method name(452): fetchuuidswithsdp
11-29 09:19:12.035: method name(452): getaddress
11-29 09:19:12.035: method name(452): getbluetoothclass
11-29 09:19:12.043: method name(452): getbondstate
11-29 09:19:12.043: method name(452): getname
11-29 09:19:12.043: method name(452): getservicechannel
11-29 09:19:12.043: method name(452): gettruststate
11-29 09:19:12.043: method name(452): getuuids
11-29 09:19:12.043: method name(452): hashcode
11-29 09:19:12.043: method name(452): isbluetoothdock
11-29 09:19:12.043: method name(452): removebond
11-29 09:19:12.043: method name(452): setpairingconfirmation
11-29 09:19:12.043: method name(452): setpasskey
11-29 09:19:12.043: method name(452): setpin
11-29 09:19:12.043: method name(452): settrust
11-29 09:19:12.043: method name(452): tostring
11-29 09:19:12.043: method name(452): writetoparcel
11-29 09:19:12.043: method name(452): convertpintobytes
11-29 09:19:12.043: method name(452): getclass
11-29 09:19:12.043: method name(452): notify
11-29 09:19:12.043: method name(452): notifyall
11-29 09:19:12.043: method name(452): wait
11-29 09:19:12.051: method name(452): wait
11-29 09:19:12.051: method name(452): wait

3.如果枚举发现api存在(sdk却隐藏),则自己实现调用方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * 与设备配对 参考源码:platform/packages/apps/settings.git
 * /settings/src/com/android/settings/bluetooth/cachedbluetoothdevice.java
 */
static public boolean createbond(class btclass,bluetoothdevice btdevice) throws exception {
 method createbondmethod = btclass.getmethod("createbond");
 boolean returnvalue = (boolean) createbondmethod.invoke(btdevice);
 return returnvalue.booleanvalue();
}
/**
 * 与设备解除配对 参考源码:platform/packages/apps/settings.git
 * /settings/src/com/android/settings/bluetooth/cachedbluetoothdevice.java
 */
static public boolean removebond(class btclass,bluetoothdevice btdevice) throws exception {
 method removebondmethod = btclass.getmethod("removebond");
 boolean returnvalue = (boolean) removebondmethod.invoke(btdevice);
 return returnvalue.booleanvalue();
}

此处注意:sdk之所以不给出隐藏的api肯定有其原因,也许是出于安全性或者是后续版本兼容性的考虑,因此不能保证隐藏api能在所有android平台上很好地运行。

本文程序运行效果如下图所示:

Android提高之蓝牙隐藏API探秘

main.xml源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <linearlayout android:id="@+id/linearlayout01"
 android:layout_height="wrap_content" android:layout_width="fill_parent">
 <button android:layout_height="wrap_content" android:id="@+id/btnsearch"
  android:text="search" android:layout_width="160dip"></button>
 <button android:layout_height="wrap_content"
  android:layout_width="160dip" android:text="show" android:id="@+id/btnshow"></button>
 </linearlayout>
 <linearlayout android:id="@+id/linearlayout02"
 android:layout_width="wrap_content" android:layout_height="wrap_content"></linearlayout>
 <listview android:id="@+id/listview01" android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 </listview>
</linearlayout>

工具类clsutils.java源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.testreflect;
import java.lang.reflect.field;
import java.lang.reflect.method;
import android.bluetooth.bluetoothdevice;
import android.util.log;
public class clsutils {
 /**
 * 与设备配对 参考源码:platform/packages/apps/settings.git
 * /settings/src/com/android/settings/bluetooth/cachedbluetoothdevice.java
 */
 static public boolean createbond(class btclass,bluetoothdevice btdevice) throws exception {
 method createbondmethod = btclass.getmethod("createbond");
 boolean returnvalue = (boolean) createbondmethod.invoke(btdevice);
 return returnvalue.booleanvalue();
 }
 /**
 * 与设备解除配对 参考源码:platform/packages/apps/settings.git
 * /settings/src/com/android/settings/bluetooth/cachedbluetoothdevice.java
 */
 static public boolean removebond(class btclass,bluetoothdevice btdevice) throws exception {
 method removebondmethod = btclass.getmethod("removebond");
 boolean returnvalue = (boolean) removebondmethod.invoke(btdevice);
 return returnvalue.booleanvalue();
 }
 /**
 *
 * @param clsshow
 */
 static public void printallinform(class clsshow) {
 try {
  // 取得所有方法
  method[] hidemethod = clsshow.getmethods();
  int i = 0;
  for (; i < hidemethod.length; i++) {
  log.e("method name", hidemethod[i].getname());
  }
  // 取得所有常量
  field[] allfields = clsshow.getfields();
  for (i = 0; i < allfields.length; i++) {
  log.e("field name", allfields[i].getname());
  }
 } catch (securityexception e) {
  // throw new runtimeexception(e.getmessage());
  e.printstacktrace();
 } catch (illegalargumentexception e) {
  // throw new runtimeexception(e.getmessage());
  e.printstacktrace();
 } catch (exception e) {
  // todo auto-generated catch block
  e.printstacktrace();
 }
 }
}

主程序testreflect.java的源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package com.testreflect;
import java.util.arraylist;
import java.util.list;
import android.app.activity;
import android.bluetooth.bluetoothadapter;
import android.bluetooth.bluetoothdevice;
import android.content.broadcastreceiver;
import android.content.context;
import android.content.intent;
import android.content.intentfilter;
import android.os.bundle;
import android.util.log;
import android.view.view;
import android.widget.adapterview;
import android.widget.arrayadapter;
import android.widget.button;
import android.widget.listview;
import android.widget.toast;
public class testreflect extends activity {
 button btnsearch, btnshow;
 listview lvbtdevices;
 arrayadapter<string> adtdevices;
 list<string> lstdevices = new arraylist<string>();
 bluetoothdevice btdevice;
 bluetoothadapter btadapt;
 @override
 public void oncreate(bundle savedinstancestate) {
 super.oncreate(savedinstancestate);
 setcontentview(r.layout.main);
 btnsearch = (button) this.findviewbyid(r.id.btnsearch);
 btnsearch.setonclicklistener(new clickevent());
 btnshow = (button) this.findviewbyid(r.id.btnshow);
 btnshow.setonclicklistener(new clickevent());
 lvbtdevices = (listview) this.findviewbyid(r.id.listview01);
 adtdevices = new arrayadapter<string>(testreflect.this,
  android.r.layout.simple_list_item_1, lstdevices);
 lvbtdevices.setadapter(adtdevices);
 lvbtdevices.setonitemclicklistener(new itemclickevent());
 
 btadapt = bluetoothadapter.getdefaultadapter();// 初始化本机蓝牙功能
 if (btadapt.getstate() == bluetoothadapter.state_off)// 开蓝牙
  btadapt.enable();
 // 注册receiver来获取蓝牙设备相关的结果
 intentfilter intent = new intentfilter();
 intent.addaction(bluetoothdevice.action_found);
 intent.addaction(bluetoothdevice.action_bond_state_changed);
 registerreceiver(searchdevices, intent);
 
 }
 private broadcastreceiver searchdevices = new broadcastreceiver() {
 public void onreceive(context context, intent intent) {
  string action = intent.getaction();
  bundle b = intent.getextras();
  object[] lstname = b.keyset().toarray();
  // 显示所有收到的消息及其细节
  for (int i = 0; i < lstname.length; i++) {
  string keyname = lstname[i].tostring();
  log.e(keyname, string.valueof(b.get(keyname)));
  }
  // 搜索设备时,取得设备的mac地址
  if (bluetoothdevice.action_found.equals(action)) {
  bluetoothdevice device = intent
   .getparcelableextra(bluetoothdevice.extra_device);
  if (device.getbondstate() == bluetoothdevice.bond_none) {
   string str = "未配对|" + device.getname() + "|" + device.getaddress();
   lstdevices.add(str); // 获取设备名称和mac地址
   adtdevices.notifydatasetchanged();
  }
  }
 }
 };
 class itemclickevent implements adapterview.onitemclicklistener {
 
 @override
 public void onitemclick(adapterview<?> arg0, view arg1, int arg2,
  long arg3) {
  btadapt.canceldiscovery();
  string str = lstdevices.get(arg2);
  string[] values = str.split("//|");
  string address=values[2];
  btdevice = btadapt.getremotedevice(address);
  try {
  if(values[0].equals("未配对"))
  {
   toast.maketext(testreflect.this, "由未配对转为已配对", 500).show();
   clsutils.createbond(btdevice.getclass(), btdevice);
  }
  else if(values[0].equals("已配对"))
  {
   toast.maketext(testreflect.this, "由已配对转为未配对", 500).show();
   clsutils.removebond(btdevice.getclass(), btdevice);
  }
  } catch (exception e) {
  // todo auto-generated catch block
  e.printstacktrace();
  }
 }
 }
 /**
 * 按键处理
 * @author gv
 *
 */
 class clickevent implements view.onclicklistener {
 @override
 public void onclick(view v) {
  if (v == btnsearch) {//搜索附近的蓝牙设备
  lstdevices.clear();
  object[] lstdevice = btadapt.getbondeddevices().toarray();
  for (int i = 0; i < lstdevice.length; i++) {
   bluetoothdevice device=(bluetoothdevice)lstdevice[i];
   string str = "已配对|" + device.getname() + "|" + device.getaddress();
   lstdevices.add(str); // 获取设备名称和mac地址
   adtdevices.notifydatasetchanged();
  }
  // 开始搜索
  settitle("本机蓝牙地址:" + btadapt.getaddress());
  btadapt.startdiscovery();
  }
  else if(v==btnshow){//显示bluetoothdevice的所有方法和常量,包括隐藏api
  clsutils.printallinform(btdevice.getclass());
  }
 }
 }
}

希望本文实例能够对大家进行android程序开发有一定的借鉴帮助作用。

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部

946
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40