Android 蓝牙模块4.2通讯

一、配置权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

    <!-- 似乎android M需要位置权限才能扫描 -->
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

二、添加依赖

implementation 'com.clj.fastble:FastBleLib:2.3.4'

三、蓝牙工具类

/**
 * @anthor GrainRain
 * @funcation 蓝牙4.0工具类
 * @date 2020/11/10
 */
public class BluetoothUtil {

    private BluetoothGatt bluetoothGatt;
    private static BleDevice bleDevice = null;

    private static Context context;
    private static String serviceUUID;
    private static String readUUID;
    private static String writeUUID;
    private static String mac;  //要连接的设备MAC地址
    private static boolean isShowDeviceDialog;

    private static List<BleDevice> bleDeviceList;
    private static ArrayAdapter adapter;
    private static List<String> data;

    private static OnBluetoothMessageListener onBluetoothMessageListener;

    public BluetoothUtil() {
        applyPermission();
        initBluetooth();

        if (isShowDeviceDialog) {
            showBluetoothDeviceListDialog();
        }
    }

    private void initBluetooth() {
        BleManager.getInstance().init(((Activity) context).getApplication());
        BleManager.getInstance()
                .enableLog(true)
                .setReConnectCount(1, 5000)
                .setSplitWriteNum(200)
                .setConnectOverTime(10000)
                .setOperateTimeout(5000);

        //打开蓝牙
        if (!BleManager.getInstance().isBlueEnable()) {
            BleManager.getInstance().enableBluetooth();
        }

        //配置扫描规则
        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
                //.setDeviceMac(mac)                  // 只扫描指定mac的设备,可选
                .setScanTimeOut(10000)              // 扫描超时时间
                .build();

        BleManager.getInstance().initScanRule(scanRuleConfig);

        //扫描蓝牙
        BleManager.getInstance().scan(new BleScanCallback() {
            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {
//                Toast.makeText(context, "扫描结束", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onScanStarted(boolean success) {
                Toast.makeText(context, "开始寻找蓝牙", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onScanning(BleDevice bleDevice) {

                L.e(bleDevice.getName() + " " + bleDevice.getMac());

                bleDeviceList.add(bleDevice);
                listAddItem(bleDevice.getName() + " - " + bleDevice.getMac());

                try {
                    //连接指定设备
                    if (!isShowDeviceDialog && mac != null && !mac.equals("")) {
                        if (bleDevice.getMac().equals(mac)) {
                            connect(bleDevice);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    //连接
    private void connect(final BleDevice bleDevice) {

        BleManager.getInstance().connect(bleDevice, new BleGattCallback() {
            @Override
            public void onStartConnect() {
                //  开始连接
                L.e("开始连接");
            }

            @Override
            public void onConnectFail(BleDevice bleDevice, BleException exception) {
                //  扫描失败
            }

            @Override
            public void onConnectSuccess(final BleDevice mBleDevice, BluetoothGatt gatt, int status) {

                // 连接成功
                L.e("连接成功");
                Toast.makeText(context, "蓝牙已连接", Toast.LENGTH_SHORT).show();

                bluetoothGatt = gatt;
                BluetoothUtil.bleDevice = mBleDevice;
                openNotification(mBleDevice);

                //获取所有的Service和Characteristic的UUID
//                List<BluetoothGattService> serviceList = bluetoothGatt.getServices();
//                for (BluetoothGattService service : serviceList) {
//                    uuidService = service.getUuid();
//                    L.e("dataAnalysis: " + uuid_service.toString());

//                    List<BluetoothGattCharacteristic> characteristicList = service.getCharacteristics();
//                    for (BluetoothGattCharacteristic characteristic : characteristicList) {
//                        uuidChara = characteristic.getUuid();
//                        L.e("c: " + uuid_chara.toString());
//                    }
            }

            @Override
            public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
                Toast.makeText(context, "蓝牙连接中断", Toast.LENGTH_LONG).show();
            }
        });
    }

    //连接成功后打开通知,也就是用来接收来自蓝牙传输过来的内容
    private static void openNotification(BleDevice bleDevice) {

        BleManager.getInstance().notify(
                bleDevice,
                serviceUUID,
                readUUID,
                new BleNotifyCallback() {

                    @Override
                    public void onNotifySuccess() {
                        L.e("onNotifySuccess");
                    }

                    @Override
                    public void onNotifyFailure(final BleException exception) {
                        L.e("onNotifyFailure");
                    }

                    @Override
                    public void onCharacteristicChanged(byte[] data) {
                        //接收
                        L.e(ByteUtils.byteArrayToHexString(data, true));

                        if (onBluetoothMessageListener != null) {
                            onBluetoothMessageListener.onMessage(data);
                        }
                    }
                });
    }

    //发送
    public static void send(byte[] input) {
        if (bleDevice != null) {
            BleManager.getInstance().write(
                    bleDevice,
                    serviceUUID,
                    writeUUID,
                    input, null);
        }
    }

    //显示蓝牙设备列表的dialog
    private void showBluetoothDeviceListDialog() {
        View view = ((Activity) context).getLayoutInflater().inflate(R.layout.list, null);
        data = new ArrayList<>();

        final AlertDialog alertDialog = new AlertDialog.Builder(context)
                .setView(view)
                .create();

        ListView listView = view.findViewById(R.id.list_view);
        adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, data);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                L.e(data.get(position));

                for (int i = 0; i < bleDeviceList.size(); i++) {
                    BleDevice bleDevice = bleDeviceList.get(i);
                    if (data.get(position).equals(bleDevice.getName() + " - " + bleDevice.getMac())) {
                        connect(bleDevice);

                        alertDialog.dismiss();
                        Toast.makeText(context, bleDevice.getName() + " - " + bleDevice.getMac(), Toast.LENGTH_SHORT).show();
                    }
                }

            }
        });
        alertDialog.show();
    }

    private static void listAddItem(String s) {
        if (data == null) data = new ArrayList<>();

        data.add(s);
        if (adapter != null) adapter.notifyDataSetChanged();
    }

    //动态获取权限
    private static void applyPermission() {
        ActivityCompat.requestPermissions((Activity) context, new String[]{
                Manifest.permission.BLUETOOTH,
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.WRITE_SETTINGS,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
        }, 1);
    }

    public static final class Builder {
        private String serviceUUID;
        private String readUUID;
        private String writeUUID;
        private String mac;
        private boolean showDeviceDialog;
        private Context context;
        private OnBluetoothMessageListener onBluetoothMessageListener;

        public Builder() {

            //数据初始化
            isShowDeviceDialog = false;
            mac = null;
            bleDeviceList = new ArrayList<>();
        }

        public Builder setServiceUUID(String val) {
            serviceUUID = val;
            return this;
        }

        public Builder setReadUUID(String val) {
            readUUID = val;
            return this;
        }

        public Builder setWriteUUID(String val) {
            writeUUID = val;
            return this;
        }

        public Builder setContext(Context val) {
            context = val;
            return this;
        }

        public Builder setMAC(String val) {
            mac = val;
            return this;
        }

        public Builder isShowDeviceDialog(boolean val) {
            showDeviceDialog = val;
            return this;
        }

        public Builder setMessageListener(OnBluetoothMessageListener listener) {
            onBluetoothMessageListener = listener;
            return this;
        }

        public BluetoothUtil build() {
            BluetoothUtil.context = context;
            BluetoothUtil.mac = mac;
            BluetoothUtil.serviceUUID = serviceUUID;
            BluetoothUtil.readUUID = readUUID;
            BluetoothUtil.writeUUID = writeUUID;
            BluetoothUtil.isShowDeviceDialog = showDeviceDialog;
            BluetoothUtil.onBluetoothMessageListener = onBluetoothMessageListener;

            return new BluetoothUtil();
        }
    }

    public interface OnBluetoothMessageListener {
        void onMessage(byte[] bytes);
    }
}

四、布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

五、使用

 new BluetoothUtil.Builder()
                .setContext(this)
                .isShowDeviceDialog(false)
                .setMAC("BA:95:A3:20:C8:12")
                .setServiceUUID("d973f2e0-b19e-11e2-9e96-080020f29a66")
                .setReadUUID("d973f2e1-b19e-11e2-9e96-9e08000c9a66")
                .setWriteUUID("d973f2e2-b19e-11e2-9e96-0800200c9a66")
                .setMessageListener(new BluetoothUtil.OnBluetoothMessageListener() {
                    @Override
                    public void onMessage(byte[] bytes) {
                        
                    }
                })
                .build();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值