智汇工业-智慧工业、智能制造及工业智能、工业互联门户网站,专业的工业“互联网+”传媒

Android提高之探秘藍牙隱藏API

來源:網絡

點擊:2109

A+ A-

所屬頻道:新聞中心

關鍵詞: Android,藍牙,API

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

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

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

    view plaincopy to clipboardprint?
    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();  
        }  

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

    view plaincopy to clipboardprint?
    /** 
     * 與設備配對 參考源碼: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();  

     /**
      * 與設備配對 參考源碼: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();
     }

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

    本文程序運行效果如下:

    main.xml源碼如下:

    view plaincopy to clipboardprint?
    <?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> 
    <?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源碼如下:

    view plaincopy to clipboardprint?
    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();  
            }  
        }  

    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的源碼如下:

    view plaincopy to clipboardprint?
    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());  
                }  
     
            }  
     
        }  
     
     

    (審核編輯: 智匯小新)

    聲明:除特別說明之外,新聞內容及圖片均來自網絡及各大主流媒體。版權歸原作者所有。如認為內容侵權,請聯系我們刪除。

    主站蜘蛛池模板: 山东优科机械设备有限公司,养鸡设备,湿帘设备,通风降温加湿设备,山东养鸡设备,山东湿帘设备 | 浙江创洁卫生消杀有限公司-浙江杀虫公司,温州消杀公司,温州灭鼠公司,灭蟑螂,灭蚊蝇,灭跳蚤,灭书虱,灭臭虫,灭螨虫,白蚁防治,房间消毒除味等专业服务 | 英格索兰隔膜泵_ARO气动隔膜泵_英格索兰隔膜泵配件【原厂正品】连续五年无投诉_英格索兰隔膜泵代理-苏州瑞晟茂环保设备有限公司 印刷公司,北京印刷厂,宣传画册手册印刷厂-和智印彩页设计 | 橡胶粉碎机_轮胎粉碎机_橡胶切条机_橡胶粉碎机价格_河南鑫世昌机械制造有限公司 | 样品前处理仪器_光谱仪器_色谱/分析仪器_测量/计量仪器_青岛聚创世纪环保科技有限公司 | 生物可降解膜_全降解薄膜_可降解包装膜材料厂家-凯峰降解膜 | 重庆木门_重庆木门十大品牌_重庆套装门_重庆烤漆门_重庆套装门十大品牌_重庆木门一线品牌_重庆川田木门 | 模具架,模具货架,抽屉式模具架-模具架厂家 | 深山工作室提供网络投票系统|微信公众号投票|微信公众号小程序|抖音小程序|百度小程序|微信公众号开发|企业网站建设 | 凿岩机|操车设备|爬车机|三环链|伞钻|伞型钻机|中心回转抓岩机|往复式给煤机|滚轮罐耳|吊桶|钩头-济宁卓力工矿设备有限公司 | 新余婚庆公司_新余最好的婚庆公司_新余高端婚礼-爱尚婚礼策划 | 呼吸家官网|肺功能检测仪生产厂家|国产肺功能仪知名品牌|肺功能检测仪|肺功能测试仪|婴幼儿肺功能仪|弥散残气肺功能仪|肺功能测试系统|广州红象医疗科技有限公司|便携式肺功能仪|大肺功能仪|呼吸康复一体机|儿童肺功能仪|肺活量计|医用简易肺功能仪|呼吸康复系统|肺功能仪|弥散肺功能仪(大肺)|便携式肺功能检测仪|肺康复|呼吸肌力测定肺功能仪|肺功能测定仪|呼吸神经肌肉刺激仪|便携式肺功能 | 青州市昌达机械设备有限公司_洗石机-洗砂机-筛沙机-砂石分离机-洗轮机-制砂机 | 兰州职业学校-新华互联网学校咨询平台中心 | 领先的一站式_专利申请代理知识产权服务平台_乐知网 | 泡酒配方大全-泡药酒专业的网站-泡酒之家 | 厦门电脑维修_上门维修电脑_笔记本电脑维修_办公设备维修 - 耐诚 | 汽油发电机,柴油发电机,小型汽油发电机,小型柴油发电机,家用发电机生产厂家——上海东明动力设备有限公司 | 合肥年会策划-合肥开业庆典公司-合肥会务活动礼仪公司-合肥展台搭建/音响租赁公司 [七色海] | 排水PVC管-PVC排污管-给水PVC管-电线PVC管-米阳建材pvc管厂 | 美缝剂_美缝剂加盟_瓷砖美缝剂_美缝剂厂家_填缝剂_领翔美缝剂-【官网】 | 互动投影_全息投影_提供一站式互动投影解决方案_水滴石科技 | 亚克力游泳池_透明/空中/无边泳池_别墅亚克力泳池设计生产厂家_瑞地格乐-深圳他拍档 | 潍坊网络推广,临沂360推广,东营360推广,枣庄360推广,潍坊网站建设,潍坊网络公司,潍坊360搜索,潍坊APP开发,潍坊360推广,潍坊360代理,潍坊点睛网络科技有限公司 | 济宁山银煤矿机械有限公司,钻采工具,防爆电器,凿岩机械,风动工具,矿山机械,建筑机械,支护设备,通风防尘,铁路设备,仪器仪表,大型设备,矿用泵,钎具类,消防类,矿车类,配件区类 | 无机纤维抗菌板-A级不燃纤维板-石英纤维板厂家-医疗抗菌板-浙江德耐姆 | 欧氏运动木地板,体育木地板厂家,篮球木地板价格_欧氏体育木地板 欧派板材官网 | 全屋定制板材 专业供应商 | 玉米加工机械_玉米加工设备_玉米深加工机械_玉米糁加工设备--滑县鑫丰粮油机械有限公司 | 蒸汽发生器厂家-电加热蒸汽发生器-免办证/免报批/免报检电锅炉-上海电热水锅炉-上海艾亚锅炉有限公司 | 语音芯片_蓝牙芯片_ble数传芯片_蓝牙数传模块厂家_拓达半导体-蓝牙数传芯片模块原厂 | 激光切割机_激光切割机价格-山东大威激光科技有限公司 | 气相色谱仪生产厂家批发价格找上海惠分科学分析仪器有限公司 | 天津止回阀-止回阀报价/哪家好-天津蝶阀/进口阀门/通风蝶阀批发-闸阀阀门/球阀生产厂家-天津凯维斯阀门制造 | 河南反渗透设备,河南纯净水设备,河南软化水设备,郑州EDI超纯水设备,郑州水处理设备厂家_河南江宇环保科技有限公司 | 陕西|青海|兰州|新疆|西宁|净化工程|西安甘肃|PCR实验室|无尘车间|净化车间-西安环亚净化工程 | 内蒙古燕雕机械设备有限公司 | 江苏维赛科技生物发展有限公司| 江西蔬菜配送,南昌蔬菜配送,南昌食堂承包,江西饭堂承包-江西菜篮子农产品发展有限公司 | 环球医网 | 带来健康生活... | 威学一百-专注国际学校择校备考-DSE-A-level-雅思-托福-OSSD-港澳台联考-AP-IGCSE-IB-AMC-多邻国-PTE-SAT-SSAT-小语种(如日语,韩语,德语,法语,西班牙语,意大利语,俄语,泰语)等考试培训,为出国留学学生提供个性化定制性学习方案,线下实体面授+线上网络课程, 提供一对一,小班课等多种班型 | 长沙升阳化工材料有限公司|