蓝牙绕过系统Pin弹窗自动匹配,亲测4.0以上没问题

来源:互联网 发布:飞狐软件 编辑:程序博客网 时间:2024/05/20 05:09

今天做一个功能,APP连接蓝牙打印机,但是每次连接都要弹一个系统弹窗输入Pin,很不爽,一般Pin都是0000或者1234,所以想能不能让程序去自动输入匹配呢?随后Google了一大堆出来,基本都是以前的代码,我就从网上一个通用的工具类,做了一些修改经过边测边改一整天,基本上实现了这个功能,大部分情况下Pin窗会一闪而过,但是也偶尔会弹出来,或者连接上之后等一段时间会弹出来,这样子,希望能和大家讨论交流,下面上代码:

首先是修改过后的蓝牙自动配对工具类:

/** * Created by caolicheng on 14/12/1. * 蓝牙自动配对工具类 */import android.bluetooth.BluetoothDevice;import android.util.Log;import java.lang.reflect.Field;import java.lang.reflect.Method;import me.ele.omniknight.common.tools.AppLogger;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);        AppLogger.e("绑定:"+returnValue);        return returnValue;    }    /**     * 与设备解除配对 参考源码: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);        AppLogger.e("解除绑定:"+returnValue);        return returnValue;    }    static public boolean setPin(Class btClass, BluetoothDevice btDevice,                                 byte[] str) throws Exception {        try {            Method removeBondMethod = btClass.getDeclaredMethod("setPin",                    new Class[]                            {byte[].class});            Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,str);            AppLogger.e("设置Pin:" + returnValue);        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return true;    }    //自动配对设置Pin值    static public boolean autoBond(Class btClass, BluetoothDevice device, String strPin) throws Exception {        Method autoBondMethod = btClass.getMethod("setPin", new Class[]{byte[].class});        Boolean result = (Boolean) autoBondMethod.invoke(device, new Object[]{strPin.getBytes()});        AppLogger.e("自动配对:"+result);        return result;    }    static public byte[] convertPinToBytes(Class btClass,BluetoothDevice device,String strPin) throws Exception {        Method convertPinToBytes = btClass.getMethod("convertPinToBytes",new Class[]{String.class});        byte[] result = (byte[]) convertPinToBytes.invoke(device,strPin);        AppLogger.e("Pin转Bytes结束");        return result;    }    // 取消用户输入    static public boolean cancelPairingUserInput(Class btClass,                                                 BluetoothDevice device)            throws Exception {        Method createBondMethod = btClass.getMethod("cancelPairingUserInput");        Boolean returnValue = (Boolean) createBondMethod.invoke(device);        AppLogger.e("取消用户输入:" + returnValue);//        cancelBondProcess(btClass, device);        return returnValue;    }    // 取消配对    static public boolean cancelBondProcess(Class btClass,                                            BluetoothDevice device)            throws Exception {        Method createBondMethod = btClass.getMethod("cancelBondProcess");        Boolean returnValue = (Boolean) createBondMethod.invoke(device);        AppLogger.e("取消配对进程:"+returnValue);        return returnValue;    }    /**     * 打印所有方法和常量     * @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() + ";and the i is:"                        + i);            }            // 取得所有常量            Field[] allFields = clsShow.getFields();            for (i = 0; i < allFields.length; i++) {                Log.e("Field name", allFields[i].getName());            }        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
原理想必大家都是知道的,没错,就是反射,拿到隐藏API进行操作,那么在什么时候调用这个函数呢?我们需要监听一个隐藏的广播"android.bluetooth.device.action.PAIRING_REQUEST",这个是在蓝牙请求配对的时候会发出的广播,那么下一步怎么做呢?在监听到这个广播之后:

BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);                if (device.getBondState() != BluetoothDevice.BOND_NONE) {                    try {                        ClsUtils.autoBond(device.getClass(), device, "1234");//                        ClsUtils.createBond(device.getClass(),device);//                        ClsUtils.cancelPairingUserInput(device.getClass(), device);                    } catch (Exception e) {                        e.printStackTrace();                    }                }
那么经过我的多次测试,基本上是没问题的,在4.0,4.1,4.2,4.4的手机上都有测试,中兴、联想、酷派和魅族(公司的几台测试机)。当然偶尔是有问题的。

希望能和大家一起探讨,谢谢!


0 0
原创粉丝点击