android bt低功耗

我来帮您实现一个完整的Android BLE(低功耗蓝牙)通讯示例。

1. 权限配置 (AndroidManifest.xml)

<xml>

<uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><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" /><uses-feature    android:name="android.hardware.bluetooth_le"    android:required="true" />

2. BLE管理类

<java>

import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothGatt;import android.bluetooth.BluetoothGattCallback;import android.bluetooth.BluetoothGattCharacteristic;import android.bluetooth.BluetoothGattDescriptor;import android.bluetooth.BluetoothGattService;import android.bluetooth.BluetoothManager;import android.bluetooth.BluetoothProfile;import android.bluetooth.le.BluetoothLeScanner;import android.bluetooth.le.ScanCallback;import android.bluetooth.le.ScanResult;import android.content.Context;import android.os.Handler;import android.util.Log;import java.util.ArrayList;import java.util.List;import java.util.UUID;public class BLEManager {    private static final String TAG = "BLEManager";        // 通用的UUID    public static final String SERVICE_UUID = "0000fff0-0000-1000-8000-00805f9b34fb";    public static final String CHARACTERISTIC_UUID_TX = "0000fff1-0000-1000-8000-00805f9b34fb";    public static final String CHARACTERISTIC_UUID_RX = "0000fff2-0000-1000-8000-00805f9b34fb";    public static final String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";        private Context context;    private BluetoothManager bluetoothManager;    private BluetoothAdapter bluetoothAdapter;    private BluetoothLeScanner bluetoothLeScanner;    private BluetoothGatt bluetoothGatt;        private boolean isScanning = false;    private boolean isConnected = false;        private Handler handler = new Handler();    private static final long SCAN_PERIOD = 10000; // 扫描10秒        private BLECallback bleCallback;        // 回调接口    public interface BLECallback {        void onDeviceFound(BluetoothDevice device);        void onConnected();        void onDisconnected();        void onDataReceived(byte[] data);        void onError(String error);    }        public BLEManager(Context context) {        this.context = context;        initialize();    }        public void setBLECallback(BLECallback callback) {        this.bleCallback = callback;    }        // 初始化蓝牙    private boolean initialize() {        if (bluetoothManager == null) {            bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);            if (bluetoothManager == null) {                Log.e(TAG, "Unable to initialize BluetoothManager.");                return false;            }        }                bluetoothAdapter = bluetoothManager.getAdapter();        if (bluetoothAdapter == null) {            Log.e(TAG, "Unable to obtain a BluetoothAdapter.");            return false;        }                bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();        return true;    }        // 检查蓝牙是否开启    public boolean isBluetoothEnabled() {        return bluetoothAdapter != null && bluetoothAdapter.isEnabled();    }        // 开始扫描    public void startScan() {        if (!isBluetoothEnabled()) {            if (bleCallback != null) {                bleCallback.onError("蓝牙未开启");            }            return;        }                if (isScanning) {            return;        }                handler.postDelayed(new Runnable() {            @Override            public void run() {                stopScan();            }        }, SCAN_PERIOD);                isScanning = true;        bluetoothLeScanner.startScan(scanCallback);        Log.d(TAG, "开始扫描BLE设备");    }        // 停止扫描    public void stopScan() {        if (isScanning && bluetoothLeScanner != null) {            isScanning = false;            bluetoothLeScanner.stopScan(scanCallback);            Log.d(TAG, "停止扫描BLE设备");        }    }        // 扫描回调    private ScanCallback scanCallback = new ScanCallback() {        @Override        public void onScanResult(int callbackType, ScanResult result) {            super.onScanResult(callbackType, result);            BluetoothDevice device = result.getDevice();            if (bleCallback != null && device.getName() != null) {                bleCallback.onDeviceFound(device);            }        }                @Override        public void onScanFailed(int errorCode) {            super.onScanFailed(errorCode);            if (bleCallback != null) {                bleCallback.onError("扫描失败: " + errorCode);            }        }    };        // 连接设备    public void connect(String address) {        if (bluetoothAdapter == null || address == null) {            Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");            return;        }                final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);        if (device == null) {            Log.w(TAG, "Device not found. Unable to connect.");            return;        }                // 如果已经连接,先断开        if (bluetoothGatt != null) {            bluetoothGatt.close();            bluetoothGatt = null;        }                bluetoothGatt = device.connectGatt(context, false, gattCallback);        Log.d(TAG, "Trying to create a new connection.");    }        // GATT回调    private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {        @Override        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {            if (newState == BluetoothProfile.STATE_CONNECTED) {                isConnected = true;                Log.i(TAG, "Connected to GATT server.");                bluetoothGatt.discoverServices();                                if (bleCallback != null) {                    handler.post(new Runnable() {                        @Override                        public void run() {                            bleCallback.onConnected();                        }                    });                }            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {                isConnected = false;                Log.i(TAG, "Disconnected from GATT server.");                                if (bleCallback != null) {                    handler.post(new Runnable() {                        @Override                        public void run() {                            bleCallback.onDisconnected();                        }                    });                }            }        }                @Override        public void onServicesDiscovered(BluetoothGatt gatt, int status) {            if (status == BluetoothGatt.GATT_SUCCESS) {                Log.w(TAG, "onServicesDiscovered received: " + status);                // 启用通知                enableNotification();            } else {                Log.w(TAG, "onServicesDiscovered received: " + status);            }        }                @Override        public void onCharacteristicRead(BluetoothGatt gatt,                                        BluetoothGattCharacteristic characteristic,                                        int status) {            if (status == BluetoothGatt.GATT_SUCCESS) {                final byte[] data = characteristic.getValue();                if (bleCallback != null && data != null) {                    handler.post(new Runnable() {                        @Override                        public void run() {                            bleCallback.onDataReceived(data);                        }                    });                }            }        }                @Override        public void onCharacteristicChanged(BluetoothGatt gatt,                                            BluetoothGattCharacteristic characteristic) {            final byte[] data = characteristic.getValue();            if (bleCallback != null && data != null) {                handler.post(new Runnable() {                    @Override                    public void run() {                        bleCallback.onDataReceived(data);                    }                });            }        }                @Override        public void onCharacteristicWrite(BluetoothGatt gatt,                                          BluetoothGattCharacteristic characteristic,                                          int status) {            if (status == BluetoothGatt.GATT_SUCCESS) {                Log.d(TAG, "Characteristic written successfully");            } else {                Log.e(TAG, "Characteristic write failed");            }        }    };        // 启用通知    private void enableNotification() {        if (bluetoothGatt == null) {            return;        }                BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(SERVICE_UUID));        if (service == null) {            Log.e(TAG, "Service not found");            return;        }                BluetoothGattCharacteristic characteristic = service.getCharacteristic(                UUID.fromString(CHARACTERISTIC_UUID_RX));        if (characteristic == null) {            Log.e(TAG, "Characteristic not found");            return;        }                bluetoothGatt.setCharacteristicNotification(characteristic, true);                BluetoothGattDescriptor descriptor = characteristic.getDescriptor(                UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));        if (descriptor != null) {            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);            bluetoothGatt.writeDescriptor(descriptor);        }    }        // 发送数据    public boolean sendData(byte[] data) {        if (bluetoothGatt == null || !isConnected) {            Log.e(TAG, "BluetoothGatt not initialized or not connected");            return false;        }                BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(SERVICE_UUID));        if (service == null) {            Log.e(TAG, "Service not found");            return false;        }                BluetoothGattCharacteristic characteristic = service.getCharacteristic(                UUID.fromString(CHARACTERISTIC_UUID_TX));        if (characteristic == null) {            Log.e(TAG, "Characteristic not found");            return false;        }                characteristic.setValue(data);        return bluetoothGatt.writeCharacteristic(characteristic);    }        // 发送字符串    public boolean sendData(String data) {        return sendData(data.getBytes());    }        // 断开连接    public void disconnect() {        if (bluetoothGatt == null) {            return;        }        bluetoothGatt.disconnect();    }        // 关闭资源    public void close() {        if (bluetoothGatt == null) {            return;        }        bluetoothGatt.close();        bluetoothGatt = null;    }        // 获取连接状态    public boolean isConnected() {        return isConnected;    }}

3. 使用示例 (MainActivity.java)

<java>

import android.Manifest;import android.bluetooth.BluetoothDevice;import android.content.pm.PackageManager;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity implements BLEManager.BLECallback {    private static final String TAG = "MainActivity";    private static final int PERMISSION_REQUEST_CODE = 1;        private BLEManager bleManager;    private ArrayAdapter<String> deviceAdapter;    private List<BluetoothDevice> deviceList = new ArrayList<>();        private Button btnScan, btnConnect, btnDisconnect, btnSend;    private ListView listDevices;    private EditText editMessage;    private TextView textStatus, textReceived;        private BluetoothDevice selectedDevice;        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                initViews();        checkPermissions();                bleManager = new BLEManager(this);        bleManager.setBLECallback(this);                deviceAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);        listDevices.setAdapter(deviceAdapter);                setupListeners();    }        private void initViews() {        btnScan = findViewById(R.id.btn_scan);        btnConnect = findViewById(R.id.btn_connect);        btnDisconnect = findViewById(R.id.btn_disconnect);        btnSend = findViewById(R.id.btn_send);        listDevices = findViewById(R.id.list_devices);        editMessage = findViewById(R.id.edit_message);        textStatus = findViewById(R.id.text_status);        textReceived = findViewById(R.id.text_received);    }        private void setupListeners() {        btnScan.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                startScan();            }        });                btnConnect.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                connectDevice();            }        });                btnDisconnect.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                bleManager.disconnect();            }        });                btnSend.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                sendMessage();            }        });                listDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                selectedDevice = deviceList.get(position);                Toast.makeText(MainActivity.this,                    "选择了: " + selectedDevice.getName(),                    Toast.LENGTH_SHORT).show();            }        });    }        private void checkPermissions() {        String[] permissions = {            Manifest.permission.BLUETOOTH,            Manifest.permission.BLUETOOTH_ADMIN,            Manifest.permission.ACCESS_FINE_LOCATION,            Manifest.permission.ACCESS_COARSE_LOCATION        };                List<String> permissionsNeeded = new ArrayList<>();                for (String permission : permissions) {            if (ContextCompat.checkSelfPermission(this, permission)                    != PackageManager.PERMISSION_GRANTED) {                permissionsNeeded.add(permission);            }        }                if (!permissionsNeeded.isEmpty()) {            ActivityCompat.requestPermissions(this,                permissionsNeeded.toArray(new String[0]),                PERMISSION_REQUEST_CODE);        }    }        private void startScan() {        if (!bleManager.isBluetoothEnabled()) {            Toast.makeText(this, "请先开启蓝牙", Toast.LENGTH_SHORT).show();            return;        }                deviceList.clear();        deviceAdapter.clear();        bleManager.startScan();        textStatus.setText("正在扫描...");    }        private void connectDevice() {        if (selectedDevice == null) {            Toast.makeText(this, "请先选择设备", Toast.LENGTH_SHORT).show();            return;        }                bleManager.stopScan();        bleManager.connect(selectedDevice.getAddress());        textStatus.setText("正在连接...");    }        private void sendMessage() {        String message = editMessage.getText().toString();        if (message.isEmpty()) {            Toast.makeText(this, "请输入消息", Toast.LENGTH_SHORT).show();            return;        }                if (bleManager.sendData(message)) {            editMessage.setText("");            Toast.makeText(this, "发送成功", Toast.LENGTH_SHORT).show();        } else {            Toast.makeText(this, "发送失败", Toast.LENGTH_SHORT).show();        }    }        @Override    public void onDeviceFound(BluetoothDevice device) {        if (!deviceList.contains(device)) {            deviceList.add(device);            deviceAdapter.add(device.getName() + "\n" + device.getAddress());        }    }        @Override    public void onConnected() {        textStatus.setText("已连接");        btnConnect.setEnabled(false);        btnDisconnect.setEnabled(true);        btnSend.setEnabled(true);    }        @Override    public void onDisconnected() {        textStatus.setText("已断开");        btnConnect.setEnabled(true);        btnDisconnect.setEnabled(false);        btnSend.setEnabled(false);    }        @Override    public void onDataReceived(byte[] data) {        String message = new String(data);        textReceived.setText("收到: " + message);        Log.d(TAG, "Received: " + message);    }        @Override    public void onError(String error) {        Toast.makeText(this, "错误: " + error, Toast.LENGTH_SHORT).show();        Log.e(TAG, "Error: " + error);    }        @Override    protected void onDestroy() {        super.onDestroy();        bleManager.close();    }}

4. 布局文件 (activity_main.xml)

<xml>

<?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"    android:padding="16dp">        <TextView        android:id="@+id/text_status"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="未连接"        android:textSize="18sp"        android:textStyle="bold"        android:padding="8dp"/>        <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">                <Button            android:id="@+id/btn_scan"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="扫描"/>                <Button            android:id="@+id/btn_connect"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="连接"/>                <Button            android:id="@+id/btn_disconnect"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="断开"            android:enabled="false"/>    </LinearLayout>        <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="设备列表:"        android:textStyle="bold"        android:padding="8dp"/>        <ListView        android:id="@+id/list_devices"        android:layout_width="match_parent"        android:layout_height="200dp"        android:layout_marginBottom="16dp"/>        <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">                <EditText            android:id="@+id/edit_message"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:hint="输入消息"/>                <Button            android:id="@+id/btn_send"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="发送"            android:enabled="false"/>    </LinearLayout>        <TextView        android:id="@+id/text_received"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="接收数据:"        android:padding="8dp"        android:layout_marginTop="16dp"/>    </LinearLayout>

使用说明

权限处理:应用会在启动时请求必要的权限扫描设备:点击"扫描"按钮开始搜索附近的BLE设备选择设备:从列表中点击选择要连接的设备连接设备:选择设备后点击"连接"按钮发送数据:连接成功后,在输入框输入消息并点击"发送"接收数据:接收到的数据会显示在界面底部

注意事项

需要根据实际的BLE设备修改UUIDAndroid 12及以上需要额外的蓝牙权限某些操作需要在UI线程执行记得在不使用时关闭连接以节省电量

这个实现提供了完整的BLE通讯功能,包括扫描、连接、数据收发等基本操作。您可以根据具体需求进行修改和扩展。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容