蓝牙相关

1,221 阅读2分钟

个人记录

  • 可见性
  • 自动配对
// 权限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />


// 使用
public class BluetoothManager {

    private static final String TAG = "BluetoothManager";
    private BluetoothAdapter bluetoothAdapter;
    private OnBluetoothListener onBluetoothListener;
    private boolean isInited;

    private static class Holder {
        private static BluetoothManager INSTANCE = new BluetoothManager();
    }

    public static BluetoothManager getInstance() {
        return Holder.INSTANCE;
    }

    private BluetoothManager() {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    public boolean isSupported() {
        return bluetoothAdapter != null;
    }

    public void init(Context context) {
        if (bluetoothAdapter == null) {
            Log.e(TAG, "startBluetooth: 设备不支持蓝牙");
            if (onBluetoothListener != null) {
                onBluetoothListener.onError("startBluetooth: 设备不支持蓝牙");
            }
            return;
        }

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intentFilter.addAction(BluetoothDevice.EXTRA_BOND_STATE);
        intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
        intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        context.registerReceiver(mReceiver, intentFilter);

        isInited = true;
    }

    public void unInit(final Context context) {
        if (isInited) {
            context.unregisterReceiver(mReceiver);
        }
    }

    public void setEnable() {
        bluetoothAdapter.enable();
    }

    /**
     * 设置蓝牙可被发现
     */
    private void setBluetoothDiscoverable() {
        try {
            Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
            setDiscoverableTimeout.setAccessible(true);
            Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class, int.class);
            setScanMode.setAccessible(true);

            setDiscoverableTimeout.invoke(bluetoothAdapter, 1);
            setScanMode.invoke(bluetoothAdapter, SCAN_MODE_CONNECTABLE_DISCOVERABLE, 1);
            Log.i(TAG, "setBluetoothDiscoverable: 可见.............");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setDisable() {
        if (bluetoothAdapter.isDiscovering()) {
            bluetoothAdapter.cancelDiscovery();
        }
        bluetoothAdapter.disable();
    }

    public boolean isEnable() {
        return bluetoothAdapter.isEnabled();
    }

    public void setOnBluetoothListener(OnBluetoothListener onBluetoothListener) {
        this.onBluetoothListener = onBluetoothListener;
    }

    public interface OnBluetoothListener {

        void onStartDiscovery();

        void onNewDeviceFound(BluetoothDevice device);

        void onNewBondedDeviceFound(BluetoothDevice device);

        void onParing(BluetoothDevice device);

        /**
         * 开启蓝牙成功
         */
        void onEnableComplete();

        /**
         * 请求配对
         *
         * @param device 配对设备
         * @param strPin 配对码
         */
        void onRequestPairing(BluetoothDevice device, String strPin);

        void onConnecting(BluetoothDevice device);

        /**
         * 已连接
         *
         * @param device 连接设备
         */
        void onConnected(BluetoothDevice device);

        /**
         * 断开连接
         *
         * @param device 设备
         */
        void onDisconnected(BluetoothDevice device);

        void onSearchCompleted();

        /**
         * 异常
         *
         * @param s 异常原因
         */
        void onError(String s);
    }

    public void startBluetooth() {
        if (bluetoothAdapter.isDiscovering()) {
            bluetoothAdapter.cancelDiscovery();
        }
        bluetoothAdapter.startDiscovery();
    }

    public void setName(String name) {
        checkNotNull(bluetoothAdapter);
        String lastName = bluetoothAdapter.getName();
        if (TextUtils.equals(name, lastName)) {
            Log.e(TAG, "setName: =.= equals");
            return;
        }
        boolean setNameSuccess = bluetoothAdapter.setName(name);
        Log.e(TAG, "setName: " + name + "... " + setNameSuccess);
    }

    private void checkNotNull(Object o) {
        if (o == null) {
            throw new NullPointerException();
        }
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (TextUtils.isEmpty(action)) {
                Log.e(TAG, "onReceive: action is null.");
                return;
            }
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            String deviceName;
            String deviceHardwareAddress;
            switch (action) {
                case BluetoothDevice.ACTION_FOUND:
                    //寻找蓝牙设备
                    deviceName = device.getName();
                    deviceHardwareAddress = device.getAddress(); // MAC address
                    Log.d(TAG, "onReceive: " + deviceName + ".." + deviceHardwareAddress
                            + "...: state = " + device.getBondState() + "....type = " + device.getType());
                    if (onBluetoothListener != null) {
                        if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                            onBluetoothListener.onNewBondedDeviceFound(device);
                        } else {
                            onBluetoothListener.onNewDeviceFound(device);
                        }
                    }
                    break;
                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                    //配对状态改变
                    if (device != null) {
                        deviceName = device.getName();
                        deviceHardwareAddress = device.getAddress(); // MAC address
                        Log.d(TAG, "onReceive:action state change. " + deviceName + ".." + deviceHardwareAddress
                                + "...: state = " + device.getBondState() + "....type = " + device.getType());
                        if (onBluetoothListener != null) {
                            onBluetoothListener.onParing(device);
                        }
                    }
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                     //开始搜索
                    if (onBluetoothListener != null) {
                        onBluetoothListener.onStartDiscovery();
                    }
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    //搜索结束
                    if (onBluetoothListener != null) {
                        onBluetoothListener.onSearchCompleted();
                    }
                    break;
                case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED:
                    // 连接状态改变
                    if (device != null) {
                        deviceName = device.getName();
                        deviceHardwareAddress = device.getAddress(); // MAC address
                        Log.d(TAG, "ACTION_STATE_CHANGED. " + deviceName + ".." + deviceHardwareAddress
                                + "...: state = " + device.getBondState() + "....type = " + device.getType()
                                + "...uuid = " + Arrays.toString(device.getUuids()));
                    }
                    //蓝牙连接状态
                    int state = intent.getIntExtra(EXTRA_CONNECTION_STATE, STATE_DISCONNECTED);
                    switch (state) {
                        case STATE_DISCONNECTING:
                            // unknown
                            break;
                        case STATE_DISCONNECTED:
                            // 0
                            if (onBluetoothListener != null) {
                                onBluetoothListener.onDisconnected(device);
                            }
                            break;
                        case STATE_CONNECTING:
                            // 1
                            Log.e(TAG, "onReceive:STATE_CONNECTING " + state);
                            if (onBluetoothListener != null) {
                                onBluetoothListener.onConnecting(device);
                            }
                            break;
                        case STATE_CONNECTED:
                            // 2
                            if (onBluetoothListener != null) {
                                onBluetoothListener.onConnected(device);
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                case BluetoothAdapter.ACTION_SCAN_MODE_CHANGED:
                    //蓝牙 SCAN_MODE
                    int scanMode = intent.getIntExtra(EXTRA_SCAN_MODE, SCAN_MODE_NONE);
                    Log.i(TAG, "onReceive:scanMode =  " + scanMode);

                    if (scanMode == SCAN_MODE_CONNECTABLE) {
                        setBluetoothDiscoverable();
                    } else if (scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                        Log.i(TAG, "onReceive: 蓝牙开启了...");
                        if (onBluetoothListener != null) {
                            onBluetoothListener.onEnableComplete();
                        }
                    }
                    break;
                case BluetoothDevice.ACTION_PAIRING_REQUEST:
                    // 请求配对
                    int intExtra = intent.getIntExtra(EXTRA_PAIRING_KEY, -1);
                    Log.i(TAG, "onReceive:========== " + intExtra);
                    abortBroadcast();
                    if (onBluetoothListener != null) {
                        onBluetoothListener.onRequestPairing(device, String.valueOf(intExtra));
                    }
                    break;
                default:
                    Log.i(TAG, "onReceive: action =  " + action);
                    break;
            }
        }
    };


    /**
     * 配对
     */
    public void createBond(BluetoothDevice device) {
        String address = device.getAddress();
        Log.i(TAG, "onItemClick: " + address);
        device.createBond();
    }

    /**
     * 解除配对
     */
    public void removeBond(BluetoothDevice device) {
        try {
            Method m = device.getClass().getMethod("removeBond", (Class[]) null);
            m.invoke(device, (Object[]) null);
        } catch (Exception e) {
            e.printStackTrace();
            if (onBluetoothListener != null) {
                onBluetoothListener.onError(e.toString());
            }
        }
    }

    /**
     * 自动配对不弹出配对窗口
     */
    public void autoParing(BluetoothDevice device, String str) {
        try {
            Method convertPinToBytes = device.getClass().getMethod(
                    "convertPinToBytes", new Class[]{String.class});
            byte[] result = (byte[]) convertPinToBytes.invoke(device, str);
            Method m = device.getClass().getMethod("setPin", new Class[]{byte[].class});
            Boolean aBoolean = (Boolean) m.invoke(device, result);
            Log.d(TAG, "autoParing: " + aBoolean);

            Method setPairingConfirmation = device.getClass().getMethod("setPairingConfirmation", boolean.class);
            Boolean confirm = (Boolean) setPairingConfirmation.invoke(device, true);
            Log.d(TAG, "autoParing: confirm " + confirm);

            if (!aBoolean || !confirm) {
                //配对失败
            }

//            Method createBondMethod = device.getClass().getMethod("cancelPairingUserInput");
//            Boolean returnValue = (Boolean) createBondMethod.invoke(device);
//            Log.d(TAG, "autoParing:cancel......... " + returnValue);
        } catch (Exception e) {
            e.printStackTrace();
            if (onBluetoothListener != null) {
                onBluetoothListener.onError(e.toString());
            }
        }
    }
}