Android Bluetooth BLE (1)

The function of interacting with the hardware bracelet has been used in recent projects. The bracelet is a BLE bracelet and requires Bluetooth technology.

1. Add permissions in AndroidManifest.xml:

	<uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

2. Dynamic permission acquisition: (this must be added, otherwise the callback of the search device will not be called)

//清单文件里面也需要配置
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
                checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.CAMERA,}, 0);
        }

    //系统方法,从requestPermissions()方法回调结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //确保是我们的请求
        if (requestCode == REQUEST_COARSE_LOCATION) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限被授予", Toast.LENGTH_SHORT).show();
            } else if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show();
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

3. Get the BluetoothManager manager:

BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

4. Get the BluetoothAdapter object:

mBluetoothAdapter = bluetoothManager.getAdapter();
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {

            Intent enableBluetooth = new Intent(

                    BluetoothAdapter.ACTION_REQUEST_ENABLE);

            startActivityForResult(enableBluetooth, 1);
        }

5. Start to search for the device to set the callback. When a device is found, this method will be called back:

mBluetoothAdapter.startLeScan(mLeScanCallback);

    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

        @Override

        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
            try {
                int startByte = 2;
                boolean patternFound = false;
                while (startByte <= 5) {

                    if (((int) scanRecord[startByte + 2] & 0xff) == 0x02 && // Identifies
                            ((int) scanRecord[startByte + 3] & 0xff) == 0x15) { // Identifies
                        patternFound = true;

                        break;

                    }

                    startByte++;

                }

                // 如果找到了的话

                if (patternFound) {

                    // 转换为16进制

                    byte[] uuidBytes = new byte[16];

                    System.arraycopy(scanRecord, startByte + 4, uuidBytes, 0, 16);

                    String hexString = bytesToHex(uuidBytes);


                    // ibeacon的UUID值

                    String uuid = hexString.substring(0, 8) + "-"

                            + hexString.substring(8, 12) + "-"

                            + hexString.substring(12, 16) + "-"

                            + hexString.substring(16, 20) + "-"

                            + hexString.substring(20, 32);


                    // ibeacon的Major值

                    int major = (scanRecord[startByte + 20] & 0xff) * 0x100

                            + (scanRecord[startByte + 21] & 0xff);


                    // ibeacon的Minor值

                    int minor = (scanRecord[startByte + 22] & 0xff) * 0x100

                            + (scanRecord[startByte + 23] & 0xff);


                    String ibeaconName = device.getName();

                    String mac = device.getAddress();

                    int txPower = (scanRecord[startByte + 24]);
                        Log.i("lee", "   Name:" + ibeaconName + "   Mac:" + mac + "   UUID:" + uuid + "   Major:" + major + "   Minor:" + minor + "   TxPower:" + txPower + "   rssi:" + rssi);
               
                }
            } catch (Exception e) {
            }
        }
    };

This method will be called back when a device is found. The first parameter is the device, the second parameter is rssi, which represents the signal strength, and the third parameter scanRecord is the broadcast packet data. Here is a filter, when it is an ibeacon device, it will enter the if statement to print out the information of the ibeacon device.

All codes:

package com.demo.ibeacondemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import java.util.Date;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;
    private static final int REQUEST_COARSE_LOCATION = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        isLocationOpen();
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {

            Intent enableBluetooth = new Intent(

                    BluetoothAdapter.ACTION_REQUEST_ENABLE);

            startActivityForResult(enableBluetooth, 1);
        }
        mBluetoothAdapter.startLeScan(mLeScanCallback);
    }

    static final char[] hexArray = "0123456789ABCDEF".toCharArray();

    private void isLocationOpen() {
        //清单文件里面也需要配置
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
                checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.CAMERA,}, 0);
        }
    }

    //系统方法,从requestPermissions()方法回调结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //确保是我们的请求
        if (requestCode == REQUEST_COARSE_LOCATION) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限被授予", Toast.LENGTH_SHORT).show();
            } else if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show();
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    private static String bytesToHex(byte[] bytes) {

        char[] hexChars = new char[bytes.length * 2];

        for (int j = 0; j < bytes.length; j++) {

            int v = bytes[j] & 0xFF;

            hexChars[j * 2] = hexArray[v >>> 4];

            hexChars[j * 2 + 1] = hexArray[v & 0x0F];

        }

        return new String(hexChars);

    }

    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

        @Override

        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
            try {
                int startByte = 2;
                boolean patternFound = false;
                while (startByte <= 5) {

                    if (((int) scanRecord[startByte + 2] & 0xff) == 0x02 && // Identifies
                            ((int) scanRecord[startByte + 3] & 0xff) == 0x15) { // Identifies

                        patternFound = true;

                        break;

                    }

                    startByte++;

                }

                // 如果找到了的话

                if (patternFound) {

                    // 转换为16进制

                    byte[] uuidBytes = new byte[16];

                    System.arraycopy(scanRecord, startByte + 4, uuidBytes, 0, 16);

                    String hexString = bytesToHex(uuidBytes);


                    // ibeacon的UUID值

                    String uuid = hexString.substring(0, 8) + "-"

                            + hexString.substring(8, 12) + "-"

                            + hexString.substring(12, 16) + "-"

                            + hexString.substring(16, 20) + "-"

                            + hexString.substring(20, 32);


                    // ibeacon的Major值

                    int major = (scanRecord[startByte + 20] & 0xff) * 0x100

                            + (scanRecord[startByte + 21] & 0xff);


                    // ibeacon的Minor值

                    int minor = (scanRecord[startByte + 22] & 0xff) * 0x100

                            + (scanRecord[startByte + 23] & 0xff);


                    String ibeaconName = device.getName();

                    String mac = device.getAddress();

                    int txPower = (scanRecord[startByte + 24]);
                    Log.i("lee", "   Name:" + ibeaconName + "   Mac:" + mac + "   UUID:" + uuid + "   Major:" + major + "   Minor:" + minor + "   TxPower:" + txPower + "   rssi:" + rssi);
                }

            } catch (Exception e) {

            }
        }
    };
}

The above can complete the function of searching equipment.

Guess you like

Origin blog.csdn.net/qq77485042/article/details/109286036