Android 蓝牙 自动配对连接

最近在开发一个手机连接蓝牙设备的APP,其中有个需求是自动连接,用户不用确认。我在网上找到了一个工具类,但是网上很

多文章对这个工具类的使用方法都不能实现我的需求,要么弹出框不能隐藏,要么是隐藏输入框却不能配对成功。经过我多次尝

试,发现他们的配对方法用错了。

工具类:ClsUtils.java


/**************** 蓝牙配对函数 ***************/

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();
    }
    static public boolean setPin(Class<? extends BluetoothDevice> btClass, BluetoothDevice btDevice, String str) throws Exception {
        try {
            Method removeBondMethod = btClass.getDeclaredMethod("setPin", new Class[]{byte[].class});
            Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice, new Object[]{str.getBytes()});
            Log.e("returnValue", "" + returnValue);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
    // 取消用户输入
    static public boolean cancelPairingUserInput(Class<?> btClass, BluetoothDevice device) throws Exception {
        Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
        Boolean returnValue = (Boolean) createBondMethod.invoke(device);
        return returnValue.booleanValue();
    }
    // 取消配对
    static public boolean cancelBondProcess(Class<?> btClass, BluetoothDevice device) throws Exception {
        Method createBondMethod = btClass.getMethod("cancelBondProcess");
        Boolean returnValue = (Boolean) createBondMethod.invoke(device);
        return returnValue.booleanValue();
    }
    //确认配对
    static public void setPairingConfirmation(Class<?> btClass, BluetoothDevice device, boolean isConfirm) throws Exception {
        Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation", boolean.class);
        setPairingConfirmation.invoke(device, isConfirm);
    }
    /**
     *
     * @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 (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 实现的界面,没有采用在Manifest文件里配置receiver的方法,因为发现那样配置结果还是会闪出配对密码输入框,附配对代码

本方法是根据蓝牙名称进行配对的,如需求不同可以自己该代码,不适用配对手机蓝牙设备,只适用于硬件开发中蓝牙模块中需

要输入密码的配对,(layout文件里只有一个按钮,这里就不给代码了):


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.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothDevice bluetoothDevice;
    private Button search;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //开始配对按钮
        search = findViewById(R.id.search_bluetooth);
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //检查蓝牙
        if(bluetoothAdapter != null){
            if(!bluetoothAdapter.isEnabled()){
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                //设置蓝牙可见性
                intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,3000);
                this.startActivity(intent);
                //打开蓝牙
                bluetoothAdapter.enable();
            }
        }else {
            Toast.makeText(this,"本地设备驱动异常",Toast.LENGTH_LONG).show();
        }
        search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //扫描设备
                bluetoothAdapter.startDiscovery();
                //注册广播
                RegisterBluetoothReceiver();
            }
        });
    }
    //注册广播
    public void RegisterBluetoothReceiver(){
        // 设置广播信息过滤
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
        // 注册广播接收器,接收并处理搜索结果
        registerReceiver(BTReceive, intentFilter);
    }
    //处理蓝夜绑定的广播
    private BroadcastReceiver BTReceive = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String bluetoothName;
                if((bluetoothName = bluetoothDevice.getName()) != null){
                    // 如果查找到的设备符合要连接的设备,处理
                    if (bluetoothName.equalsIgnoreCase("HC-05")) {
                        //搜索蓝牙占用资源,搜索到后要及时关闭
                        bluetoothAdapter.cancelDiscovery();
                        //获取蓝牙的连接状态
                        int connectState = bluetoothDevice.getBondState();
                        switch (connectState){
                            //未配对
                            case BluetoothDevice.BOND_NONE:
                                //开始配对
                                try{
                                    ClsUtils.createBond(bluetoothDevice.getClass(),bluetoothDevice);
                                }catch (Exception e){
                                    e.printStackTrace();
                                }
                                break;
                        }
                    }
                }
            }else if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)){
                try {
                    //如果不结束广播接收,配对界面会闪出
                    abortBroadcast();
                    //顺序一定要这样,否则会出问题
                    ClsUtils.setPin(bluetoothDevice.getClass(), bluetoothDevice, "1234");
                    //这行代码会在控制台报错
                    //ClsUtils.setPairingConfirmation(bluetoothDevice.getClass(), bluetoothDevice,true);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //注销广播
        unregisterReceiver(BTReceive);
    }

}

参考文章:https://blog.csdn.net/qq_30297763/article/details/79621137

猜你喜欢

转载自blog.csdn.net/Zx0307/article/details/81434066