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

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());  
                }  
     
            }  
     
        }  
     
     

    (審核編輯: 智匯小新)

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

    主站蜘蛛池模板: 四川蜀易控科技有限公司-酒店客房控制系统-智慧酒店智能化客房控制系统生产厂家 | 纸带过滤机,磁性分离器,排屑器-烟台通赫机床辅机有限公司 | 上海升降机_导轨式升降货梯_移动铝合金升降机_上海力盏电动液压平台厂家 | 压缩强度测定仪-纸管平压强度测定仪-电脑拉力仪-杭州纸邦自动化技术有限公司 | 泰安兴润建材有限公司,泰安井盖定做,泰安警示桩定做,泰安雨水篦子定做,泰安操场篦子定做,泰安标志牌定做 | 郫都人才网_郫都招聘网_求职找工作平台 | 华为交换机及防火墙-H3C无线AP-鸿远腾达华为交换机总代理商 | 移动石料破碎机-颚式锤式反击式破碎机设备厂家_山东.青州富康机械 | 津南人才网_津南招聘网_求职找工作平台 | 智能搅拌锅_食品搅拌锅_多功能搅拌锅 - 青岛环速科技有限公司 | 砂金设备-淘金机械-金矿选矿设备厂家-青州冠诚重工机械有限公司 砂浆生产线_干混砂浆设备_干混砂浆生产线-苏州一工机械有限公司 | 上海浩斌信息科技有限公司RFID读写器,IC卡读卡器,手持机,数据采集终端,电力仓库管理软件开发,固定资产软件,纱管标签,试剂管理,RFID试剂柜,档案管理,档案柜,智能货架 | 上海乾乙智能科技有限公司官网 | 全球石油化工网 - 石油化工资讯,石油化工机械,石油化工设备,石油化工贸易,石油化工技术,尽在石油化工网 | 无锡大型数控龙门铣,喷涂加工,回火抛丸加工,精密不锈钢焊接机床身机床底座制造加工-无锡美高帝机械有限公司 | 九江市丰硕节能建材有限公司| 铝基板_铜基板_铝基板厂家诚之益电路—汽车灯铜基板行业制商 | 球形钢支座,粘滞阻尼器,抗震球型钢支座,盆式橡胶支座,调谐质量阻尼器,屈曲约束支撑-衡水路泽科技 | 种植槽系统,移动苗床,多层种植货架,潮汐苗床,物流苗床,潮汐面板,立体旋转育秧床,河北博超温室设备有限公司 | 山东临沂春鑫新能源科技有限公司|官网|生物质颗粒锅炉|燃气锅炉|水源热泵 | 长春衡宇机械 食品干燥机 微波灭菌机 连续真空干燥机-干燥行业先进企业 | 中山电子控制板|中山工业控制板|中山市云禾电子科技有限公司 | 铝合金压缩空气管道安装与设计_专业厂家_福斯特铝合金管道 | 塑料托盘 塑料周转箱零件盒生产销售-江苏卡尔富塑业科技有限公司 | 汽车标签|医疗标签|电子标签|手机电池标签|电脑电池标签|电源标签|耐高温标签|防静电标签|手机出厂膜|手机全裹膜|手机包裹膜|手机卖点膜|热转印标签|遮阳板标签|天势科技|-标签印制专家! | 友联智能|RFID应用服务供应商|专注RFID行业解决方案|RFID数据采集-助力行业数字化转型 | 四字成语大全6000个,经典成语大全及解释,1000个50000个成语及解释 - 同鑫成语网 | 砂浆生产线_干混砂浆设备_干混砂浆生产线-苏州一工机械有限公司 砂基透水砖滤水率,防滑性试验仪,砂基透水砖落球冲击,抗冲击试验机-献县中正试验仪器销售处 | 厦门,泉州自助餐上门|生日自助餐|婚礼自助餐|公司聚会自助餐|户外烧烤|冷餐|茶歇外卖配送-福建非选餐饮公司 | 宿州电机维修厂家,大型电机维修及二手电机修理到安徽鑫瑞特电机装备有限公司 | 输送带_山东输送带厂家_橡胶传送带-山东中输输送机械有限公司 | 麦秸映像网络技术有限公司,河南省政府采网入驻对接,新乡网站维护建设,小程序开发,APP定制开发,钉钉开发,新乡软件开发等相关网络业务 | 新中式家具,广东新中式家具,广州新中式家具,佛山新中式家具,顺德新中式家具,乐从新中式家具,新中式家具厂家直销--唐明雅居 | 中房网_中国房地产业协会官方网站| 自动烘干线,工业烘箱生产厂家-湖南耐美特智能装备有限公司官方网站 | 培训桌-培训椅-会议椅-洽谈桌-培训桌椅生产厂家-【鼎优家具】 | 明星代言,明星代言费,明星代言价格查询-良策明星经纪公司 | 佳龙食品集团|高端辣条领导品牌 加药装置-排油烟装置-工业滤水器-连云港灵动 | 通风方式信号控制箱_人防呼叫按钮_人防设备厂家–西安鼎兴自控工程有限公司 | 威海实木家具-威海定制家具-威海家具-威海至佳百隆家具有限公司 威海木箱,威海木托盘,威海免熏蒸包装箱-威海耀晟木制品有限公司 | 厦门公司注册-提供工商登记记账代理服务和营业执照代办地址与注册流程及费用 |