andriod12 (sdk33) and above integrate Bluetooth app

Bluetooth module

Declare Bluetooth permissions

If you want your app to initiate device discovery or manipulate Bluetooth settings, BLUETOOTHyou must declare BLUETOOTH_ADMINpermissions in addition to permissions. Most applications only need this permission to discover local Bluetooth devices.

Add the following permissions in the AndroidManifest.xml file

  	<!-- 安卓12之前的蓝牙权限需求-->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- 安卓12新增的蓝牙权限-->
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <!-- 定位权限, 蓝牙搜索需要-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Set up Bluetooth

1. Get BluetoothAdapter

Required by all Bluetooth Activities BluetoothAdapter. To get it BluetoothAdapter, call the static getDefaultAdapter()method. This method returns an BluetoothAdapterobject representing the device's own Bluetooth adapter (Bluetooth wireless device). There is only one Bluetooth adapter for the entire system, and your app can interact with it using this object. If getDefaultAdapter()returned null, the device does not support Bluetooth.

 	/**
     * 获取BluetoothAdapter对象,并判断蓝牙是否获取到
     */
    public boolean isBlueToothAvailable() {
    
    
        //获取BluetoothAdapter对象
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        // 判断蓝牙是否可用
        return bluetoothAdapter != null;
    }
2. Enable Bluetooth

Next, you need to make sure Bluetooth is enabled. Called isEnabled()to check if Bluetooth is currently enabled. If this method returns false, it means Bluetooth is disabled. To request that Bluetooth be enabled, call startActivityForResult(), passing in an ACTION_REQUEST_ENABLEIntent operation. This call makes a request to enable Bluetooth via system settings (without stopping the app)

 	/**
     * 启用蓝牙
     *
     * @param activity 启动该方法的Activity
     */
    public void openBlueTooth(Activity activity) {
    
    
        if (!bluetoothAdapter.isEnabled()) {
    
    
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            activity.startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        } else {
    
    
            Toast.makeText(activity, "蓝牙已打开", Toast.LENGTH_SHORT).show();
        }
    }

Find device

1. Query paired devices

Before performing device discovery, you must query the set of paired devices to see if the desired device is in the Detected state. To do this, please call getBondedDevices(). This method returns an array of BluetoothDeviceobjects representing paired devices. For example, you can query all paired devices and get the name and MAC address of each device

 	/**
     * 打印已配对设备
     */
    public void printDevice() {
    
    
        //打印出已配对的设备
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        if (pairedDevices.size() > 0) {
    
    
            for (BluetoothDevice device : pairedDevices) {
    
    
                listAdapter.add(device.getName() + "\n" + device.getAddress());
            }
        } else {
    
    
            listAdapter.add("没有已配对设备");
        }
    }
2. Discover the device
 	/**
     * 广播接收者
     * 接收发现蓝牙设备和蓝牙设备扫描结束的广播
     */
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
    
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
    
            String action = intent.getAction();//获取蓝牙设备
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
    
      //发现设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                assert device != null;
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
    
      //如果设备未绑定
                    listAdapter.add(device.getName() + "\n" + device.getAddress());
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
    
      //扫描设备结束
                if (listAdapter.getCount() == 0) {
    
      //没有设备
                    Toast.makeText(BluetoothDeviceListActivity.this, "没有设备",
                            Toast.LENGTH_SHORT).show();
                }
            }
        }
    };

    @Override
    public void setRequestedOrientation(int requestedOrientation) {
    
    
        super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);
        //注册广播
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(bluetoothReceiver, filter);

        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(bluetoothReceiver, filter);

        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        listAdapter = new ArrayAdapter<>(this, R.layout.device_name);
        ListView lv_device = findViewById(R.id.listView);
        Button bt_find = findViewById(R.id.bt_find);
        lv_device.setAdapter(listAdapter);

        printDevice();

        bt_find.setOnClickListener(new OnClickListener() {
    
    
            @Override
            public void onClick(View arg0) {
    
    
                bluetoothAdapter.startDiscovery();   //开始扫描
            }
        });

        //选择连接设备
        lv_device.setOnItemClickListener(new OnItemClickListener() {
    
    
            @Override
            public void onItemClick(AdapterView<?> arg0, View v, int arg2,
                                    long arg3) {
    
    
                String info = ((TextView) v).getText().toString();
                if (info.equals("没有已配对设备")) {
    
    
                    Toast.makeText(getApplicationContext(), "没有已配对设备", Toast.LENGTH_LONG)
                            .show();
                } else {
    
    
                    String address = info.substring(info.length() - 17);   //获取蓝牙设备地址

                    Intent intent = new Intent();
                    intent.putExtra(EXTRA_DEVICE_ADDRESS, address);   //将地址装入EXTRA_DEVICE_ADDRESS
                    setResult(Activity.RESULT_OK, intent); //将地址传送回MainActivity
                    finish();
                }
            }
        });

    }

connect

1. Connect the device
    /**
     * 连接设备
     * @param device 蓝牙设备
     * @return 连接状态
     */
    public boolean connectThread(BluetoothDevice device) {
    
    
        try {
    
    
            bluetoothSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
            bluetoothAdapter.cancelDiscovery();
            bluetoothSocket.connect();
            connectStatus = true;  //连接成功
            // 接收数据进程
            new Thread(new Runnable() {
    
      //读线程
                @Override
                public void run() {
    
    
                    int bytes;
                    byte[] buffer = new byte[256];
                    while (true) {
    
    
                        if (bluetoothSocket != null && bluetoothSocket.isConnected()) {
    
    
                            try {
    
     // 接收数据
                                bytes = bluetoothSocket.getInputStream().read(buffer);
                                final String readStr = new String(buffer, 0, bytes); //读出的数据
                            } catch (IOException e) {
    
    
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }).start();
        } catch (IOException e) {
    
    
            connectStatus = false;  //连接失败
            try {
    
    
                bluetoothSocket.close();
            } catch (IOException e2) {
    
    
                e.printStackTrace();
            }
        }
        return connectStatus;
    }
2. Cancel the connection
 /**
     * 取消连接
     */
    public void cancelConnect() {
    
    
        try {
    
    
            bluetoothSocket.close();
            connectStatus = false;
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

data transmission

1. Blue sends data
 /**
     * 蓝牙发送数据
     *
     * @param str 待发送的字符串
     */
    public void write(String str) {
    
    
        if (connectStatus) {
    
    
            byte[] buffer = str.getBytes();
            try {
    
    
                bluetoothSocket.getOutputStream().write(buffer);
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
    }

Bluetooth transmission test results

Pay attention to the pitfalls of sdk version 33

  • Android 12 and above require dynamic permission application, otherwise an error will be reported and crashed when retrieving the connected Bluetooth device.
  • The code will be reported red. You only need to configure the dynamic permission application before calling Bluetooth, and you can use it. There should be a better solution to be solved...
1. First look at the file directory

Please add image description

  • BluetoothUtils Some methods of Bluetooth initial configuration
  • BluetoothDeviceListActivity Bluetooth connection list display
  • MainActivity Home Page
  • Under layout is the UI interface.
2. Test method
1. Use your mobile phone to connect to the laptop Bluetooth and open an incoming com port as follows

Please add image description

2. Open the serial port debugging tool, select the port number, for example, mine is COM6 port, and then open the serial port

Please add image description

3. Compile and install the Android program on your phone, click Connect Bluetooth on the left, and select the Bluetooth device of your computer on the right.

Please add image description

4. Click the Send button to see the effect on the debugging tool.

Please add image description

expand

When we successfully implement Bluetooth data transmission on the andriod side, we can integrate the hardware to implement some functions

  • The Bluetooth car controls the car's movement by sending instructions.
  • Smart homes, such as controlling lights on and off, air conditioners, curtains, etc., of course can only be played on microcontrollers, and are still far away from actual use.

For detailed introduction, please refer to the official documentation: Bluetooth Overview | Android Developers | Android Developers (google.cn)

Complete code repository: https://gitee.com/chafaner

Guess you like

Origin blog.csdn.net/weixin_45833112/article/details/129799278