Android提高第十三篇之探秘藍芽隱藏API

來源:互聯網
上載者:User

本文來自http://blog.csdn.net/hellogv/ ,引用必須註明出處!

       上次講解Android的藍芽基本用法,這次講得深入些,探討下藍芽方面的隱藏API。用過Android系統設定(Setting)的人都知道藍芽搜尋之後可以建立配對解除配對,但是這兩項功能的函數沒有在SDK中給出,那麼如何去使用這兩項功能呢?本文利用JAVA的反射機制去調用這兩項功能對應的函數:createBond和removeBond,具體的發掘和實現步驟如下:

1.使用Git工具下載platform/packages/apps/Settings.git,在Setting源碼中尋找關於建立配對解除配對的API,知道這兩個API的宿主(BluetoothDevice);

2.使用反射機制對BluetoothDevice枚舉其所有方法和常量,看看是否存在:

 

static public void printAllInform(Class clsShow) {<br />try {<br />// 取得所有方法<br />Method[] hideMethod = clsShow.getMethods();<br />int i = 0;<br />for (; i < hideMethod.length; i++) {<br />Log.e("method name", hideMethod[i].getName());<br />}<br />// 取得所有常量<br />Field[] allFields = clsShow.getFields();<br />for (i = 0; i < allFields.length; i++) {<br />Log.e("Field name", allFields[i].getName());<br />}<br />} catch (SecurityException e) {<br />// throw new RuntimeException(e.getMessage());<br />e.printStackTrace();<br />} catch (IllegalArgumentException e) {<br />// throw new RuntimeException(e.getMessage());<br />e.printStackTrace();<br />} catch (Exception e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />}<br />}  

結果如下:

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卻隱藏),則自己實現調用方法:

/**<br /> * 與裝置配對 參考源碼:platform/packages/apps/Settings.git<br /> * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java<br /> */<br />static public boolean createBond(Class btClass,BluetoothDevice btDevice) throws Exception {<br />Method createBondMethod = btClass.getMethod("createBond");<br />Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);<br />return returnValue.booleanValue();<br />}</p><p>/**<br /> * 與裝置解除配對 參考源碼:platform/packages/apps/Settings.git<br /> * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java<br /> */<br />static public boolean removeBond(Class btClass,BluetoothDevice btDevice) throws Exception {<br />Method removeBondMethod = btClass.getMethod("removeBond");<br />Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);<br />return returnValue.booleanValue();<br />}

PS:SDK之所以不給出隱藏的API肯定有其原因,也許是出於安全性或者是後續版本相容性的考慮,因此不能保證隱藏API能在所有Android平台上很好地運行。。。

本文程式運行效果如下:

main.xml源碼如下:

<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br />android:orientation="vertical" android:layout_width="fill_parent"<br />android:layout_height="fill_parent"><br /><LinearLayout android:id="@+id/LinearLayout01"<br />android:layout_height="wrap_content" android:layout_width="fill_parent"><br /><Button android:layout_height="wrap_content" android:id="@+id/btnSearch"<br />android:text="Search" android:layout_width="160dip"></Button><br /><Button android:layout_height="wrap_content"<br />android:layout_width="160dip" android:text="Show" android:id="@+id/btnShow"></Button><br /></LinearLayout><br /><LinearLayout android:id="@+id/LinearLayout02"<br />android:layout_width="wrap_content" android:layout_height="wrap_content"></LinearLayout><br /><ListView android:id="@+id/ListView01" android:layout_width="fill_parent"<br />android:layout_height="fill_parent"><br /></ListView><br /></LinearLayout><br />

工具類ClsUtils.java源碼如下:

package com.testReflect;</p><p>import java.lang.reflect.Field;<br />import java.lang.reflect.Method;</p><p>import android.bluetooth.BluetoothDevice;<br />import android.util.Log;</p><p>public class ClsUtils {</p><p>/**<br /> * 與裝置配對 參考源碼:platform/packages/apps/Settings.git<br /> * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java<br /> */<br />static public boolean createBond(Class btClass,BluetoothDevice btDevice) throws Exception {<br />Method createBondMethod = btClass.getMethod("createBond");<br />Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);<br />return returnValue.booleanValue();<br />}</p><p>/**<br /> * 與裝置解除配對 參考源碼:platform/packages/apps/Settings.git<br /> * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java<br /> */<br />static public boolean removeBond(Class btClass,BluetoothDevice btDevice) throws Exception {<br />Method removeBondMethod = btClass.getMethod("removeBond");<br />Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);<br />return returnValue.booleanValue();<br />}</p><p>/**<br /> *<br /> * @param clsShow<br /> */<br />static public void printAllInform(Class clsShow) {<br />try {<br />// 取得所有方法<br />Method[] hideMethod = clsShow.getMethods();<br />int i = 0;<br />for (; i < hideMethod.length; i++) {<br />Log.e("method name", hideMethod[i].getName());<br />}<br />// 取得所有常量<br />Field[] allFields = clsShow.getFields();<br />for (i = 0; i < allFields.length; i++) {<br />Log.e("Field name", allFields[i].getName());<br />}<br />} catch (SecurityException e) {<br />// throw new RuntimeException(e.getMessage());<br />e.printStackTrace();<br />} catch (IllegalArgumentException e) {<br />// throw new RuntimeException(e.getMessage());<br />e.printStackTrace();<br />} catch (Exception e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />}<br />}<br />}<br />

主程式testReflect.java的源碼如下:

package com.testReflect;</p><p>import java.util.ArrayList;<br />import java.util.List;<br />import android.app.Activity;<br />import android.bluetooth.BluetoothAdapter;<br />import android.bluetooth.BluetoothDevice;<br />import android.content.BroadcastReceiver;<br />import android.content.Context;<br />import android.content.Intent;<br />import android.content.IntentFilter;<br />import android.os.Bundle;<br />import android.util.Log;<br />import android.view.View;<br />import android.widget.AdapterView;<br />import android.widget.ArrayAdapter;<br />import android.widget.Button;<br />import android.widget.ListView;<br />import android.widget.Toast;</p><p>public class testReflect extends Activity {<br />Button btnSearch, btnShow;<br />ListView lvBTDevices;<br />ArrayAdapter<String> adtDevices;<br />List<String> lstDevices = new ArrayList<String>();<br />BluetoothDevice btDevice;<br />BluetoothAdapter btAdapt;</p><p>@Override<br />public void onCreate(Bundle savedInstanceState) {<br />super.onCreate(savedInstanceState);<br />setContentView(R.layout.main);</p><p>btnSearch = (Button) this.findViewById(R.id.btnSearch);<br />btnSearch.setOnClickListener(new ClickEvent());<br />btnShow = (Button) this.findViewById(R.id.btnShow);<br />btnShow.setOnClickListener(new ClickEvent());</p><p>lvBTDevices = (ListView) this.findViewById(R.id.ListView01);<br />adtDevices = new ArrayAdapter<String>(testReflect.this,<br />android.R.layout.simple_list_item_1, lstDevices);<br />lvBTDevices.setAdapter(adtDevices);<br />lvBTDevices.setOnItemClickListener(new ItemClickEvent());</p><p>btAdapt = BluetoothAdapter.getDefaultAdapter();// 初始化本機藍芽功能<br />if (btAdapt.getState() == BluetoothAdapter.STATE_OFF)// 開藍芽<br />btAdapt.enable();</p><p>// 註冊Receiver來擷取藍牙裝置相關的結果<br />IntentFilter intent = new IntentFilter();<br />intent.addAction(BluetoothDevice.ACTION_FOUND);<br />intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);<br />registerReceiver(searchDevices, intent);</p><p>}</p><p>private BroadcastReceiver searchDevices = new BroadcastReceiver() {<br />public void onReceive(Context context, Intent intent) {<br />String action = intent.getAction();<br />Bundle b = intent.getExtras();<br />Object[] lstName = b.keySet().toArray();</p><p>// 顯示所有收到的訊息及其細節<br />for (int i = 0; i < lstName.length; i++) {<br />String keyName = lstName[i].toString();<br />Log.e(keyName, String.valueOf(b.get(keyName)));<br />}<br />// 搜尋裝置時,取得裝置的MAC地址<br />if (BluetoothDevice.ACTION_FOUND.equals(action)) {<br />BluetoothDevice device = intent<br />.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);</p><p>if (device.getBondState() == BluetoothDevice.BOND_NONE) {<br />String str = "未配對|" + device.getName() + "|" + device.getAddress();<br />lstDevices.add(str); // 擷取裝置名稱和mac地址<br />adtDevices.notifyDataSetChanged();<br />}<br />}<br />}<br />};</p><p>class ItemClickEvent implements AdapterView.OnItemClickListener {</p><p>@Override<br />public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,<br />long arg3) {<br />btAdapt.cancelDiscovery();<br />String str = lstDevices.get(arg2);<br />String[] values = str.split("//|");<br />String address=values[2];</p><p>btDevice = btAdapt.getRemoteDevice(address);<br />try {<br />if(values[0].equals("未配對"))<br />{<br />Toast.makeText(testReflect.this, "由未配對轉為已配對", 500).show();<br />ClsUtils.createBond(btDevice.getClass(), btDevice);<br />}<br />else if(values[0].equals("已配對"))<br />{<br />Toast.makeText(testReflect.this, "由已配對轉為未配對", 500).show();<br />ClsUtils.removeBond(btDevice.getClass(), btDevice);<br />}<br />} catch (Exception e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />}<br />}</p><p>}</p><p>/**<br /> * 按鍵處理<br /> * @author GV<br /> *<br /> */<br />class ClickEvent implements View.OnClickListener {</p><p>@Override<br />public void onClick(View v) {<br />if (v == btnSearch) {//搜尋附近的藍牙裝置<br />lstDevices.clear();</p><p>Object[] lstDevice = btAdapt.getBondedDevices().toArray();<br />for (int i = 0; i < lstDevice.length; i++) {<br />BluetoothDevice device=(BluetoothDevice)lstDevice[i];<br />String str = "已配對|" + device.getName() + "|" + device.getAddress();<br />lstDevices.add(str); // 擷取裝置名稱和mac地址<br />adtDevices.notifyDataSetChanged();<br />}<br />// 開始搜尋<br />setTitle("本機藍芽地址:" + btAdapt.getAddress());<br />btAdapt.startDiscovery();<br />}<br />else if(v==btnShow){//顯示BluetoothDevice的所有方法和常量,包括隱藏API<br />ClsUtils.printAllInform(btDevice.getClass());<br />}</p><p>}</p><p>}</p><p>}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.