gpt4 book ai didi

Android提高之蓝牙隐藏API探秘

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 26 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Android提高之蓝牙隐藏API探秘由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

前面文章讲解了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程序开发有一定的借鉴帮助作用.

最后此篇关于Android提高之蓝牙隐藏API探秘的文章就讲到这里了,如果你想了解更多关于Android提高之蓝牙隐藏API探秘的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com