android安卓 低功耗 蓝牙代码例

package com.example.myapplication;

import android.Manifest;
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.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
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 java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import android.widget.AdapterView;


public class BluetoothSendMsgActivity extends AppCompatActivity {

    private static final int REQUEST_LOCATION_PERMISSION = 1;
    private static final long SCAN_PERIOD = 10000;
    private static final String TAG = "BLECommunication";
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothLeScanner mBluetoothLeScanner;
    private Handler mHandler;
    private boolean mScanning;
    private ArrayAdapter<String> mDeviceListAdapter;
    private List<BluetoothDevice> mDeviceList;
    private BluetoothGatt mBluetoothGatt;

    private BluetoothGattCharacteristic mWriteCharacteristic;
    private BluetoothGattCharacteristic mReadCharacteristic;

    private EditText inputEditText;
    private TextView responseTextView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth_send_msg);

        inputEditText = findViewById(R.id.inputEditText);
        responseTextView = findViewById(R.id.responseTextView);
        Button sendButton = findViewById(R.id.sendButton);

        mHandler = new Handler();
        mDeviceList = new ArrayList<>();
        mDeviceListAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);

        ListView listDevices = findViewById(R.id.list_devices);
        listDevices.setAdapter(mDeviceListAdapter);
        // 为 ListView 添加点击事件监听器
        listDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                BluetoothDevice device = mDeviceList.get(position);
                scanLeDevice(false); // 停止扫描
                connectToDevice(device);
                Log.i(TAG, "---------------------------------------1009" );
            }
        });

        inputEditText = findViewById(R.id.inputEditText);
        responseTextView = findViewById(R.id.responseTextView);

        Button btnStartScan = findViewById(R.id.btn_start_scan);
        btnStartScan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (checkLocationPermission()) {
                    scanLeDevice(true);
                }
            }
        });
        // 获取蓝牙管理器
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        //-------------------------- start
        // 假设已经获取到目标设备的地址
//        String deviceAddress = "A2:E0:5A:6D:21:67";
//        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(deviceAddress);
//        Log.i(TAG, "----Bluetooth name is " + mBluetoothAdapter.getName());
//        // 连接设备
//        mBluetoothGatt = device.connectGatt(this, false, gattCallback);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                responseTextView.setText("Feedback: ---------");
                String message = inputEditText.getText().toString();
                sendMessage(message);
            }
        });
        //-------------------------- end

        mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
    }

    private void sendMessage(String message) {
        Log.i(TAG, "---------------------------------------2009" );
        if (mWriteCharacteristic != null) {
            Log.i(TAG, "---------------------------------------3009" );
            mWriteCharacteristic.setValue(message.getBytes());
            mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
        }
    }

    private boolean checkLocationPermission() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
            Log.i(TAG, "--------------checkLocationPermission-------------------------false" );
            return false;
        }
        Log.i(TAG, "--------------checkLocationPermission-------------------------true" );
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_LOCATION_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                scanLeDevice(true);
            } else {
                Toast.makeText(this, "Location permission is required for BLE scanning", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothLeScanner.stopScan(mLeScanCallback);
                }
            }, SCAN_PERIOD);

            mScanning = true;
            mBluetoothLeScanner.startScan(mLeScanCallback);
        } else {
            mScanning = false;
            mBluetoothLeScanner.stopScan(mLeScanCallback);
        }
    }

    private final ScanCallback mLeScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            BluetoothDevice device = result.getDevice();
            if (!mDeviceList.contains(device)) {
                mDeviceList.add(device);
                mDeviceListAdapter.add(device.getName() + " - " + device.getAddress());
                mDeviceListAdapter.notifyDataSetChanged();
                // Connect to the first device found for simplicity
                if (mDeviceList.size() == 1) {
                    scanLeDevice(false);
                    connectToDevice(device);
                }
            }
        }
    };

    private void connectToDevice(BluetoothDevice device) {
        Log.i(TAG, "---------------------------------------4009------------------" );
//        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
//            return;
//        }
        Log.i(TAG, "---------------------------------------5009------------------" );
        mBluetoothGatt = device.connectGatt(this, false, gattCallback);
    }
//    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
//        @Override
//        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
//            super.onConnectionStateChange(gatt, status, newState);
//            if (newState == BluetoothProfile.STATE_CONNECTED) {
//                // Discover services after connection
//                gatt.discoverServices();
//            }
//        }
//
//        @Override
//        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
//            Log.d("TAG", "---------------------------3001" );
//            super.onServicesDiscovered(gatt, status);
//            if (status == BluetoothGatt.GATT_SUCCESS) {
//                List<BluetoothGattService> services = gatt.getServices();
//                for (BluetoothGattService service : services) {
//                    List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
//                    for (BluetoothGattCharacteristic characteristic : characteristics) {
//                        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0) {
//                            Log.d("TAG", "---------------------------2001" );
//                            mWriteCharacteristic = characteristic;
//                        }
//                        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
//                            mReadCharacteristic = characteristic;
//                            gatt.setCharacteristicNotification(characteristic, true);
//                        }
//                    }
//                }
//            }
//        }
//
//        @Override
//        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
//            super.onCharacteristicChanged(gatt, characteristic);
//            if (characteristic == mReadCharacteristic) {
//                final String receivedMessage = new String(characteristic.getValue());
//                runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        responseTextView.setText("Received Message: " + receivedMessage);
//                    }
//                });
//            }
//        }
//    };

    // 用于标记是否刚刚进行了写入操作
    private boolean isJustWritten = false;
    private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                Log.i(TAG, "Connected to GATT server.");
                // 连接成功后,发现服务
                gatt.discoverServices();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                Log.i(TAG, "Disconnected from GATT server.");
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // 查找可写和可读特征
                List<BluetoothGattService> services = gatt.getServices();
                for (BluetoothGattService service : services) {
                    List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                    for (BluetoothGattCharacteristic characteristic : characteristics) {
                        Log.w(TAG, "--------------------------------9000002-------");
                        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0) {
                            Log.w(TAG, "--------------------------------9000001-------");
                            mWriteCharacteristic = characteristic;
                        }
                        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
                            mReadCharacteristic = characteristic;
                            gatt.setCharacteristicNotification(mReadCharacteristic, true);
                            // 获取描述符并启用通知
                            BluetoothGattDescriptor descriptor = mReadCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
                            if (descriptor != null) {
                                Log.w(TAG, "--------onServicesDiscovered descriptor ");
                                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                                gatt.writeDescriptor(descriptor);
                            }
                        }
                    }
                }
            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            if (characteristic == mReadCharacteristic) {
                byte[] data = characteristic.getValue();
                final String response = new String(data, StandardCharsets.UTF_8);
                if (isJustWritten) {
                    // 如果是刚刚写入操作后的反馈
                    Log.d(TAG, "Received feedback after write: " + response);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            responseTextView.setText("Feedback: " + response);
                        }
                    });
                    // 重置标记
                    isJustWritten = false;
                }
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG, "Write characteristic success");
                // 标记刚刚进行了写入操作
                isJustWritten = true;
            }
        }
    };
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBluetoothGatt != null) {
            mBluetoothGatt.close();
        }
    }
}

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <!-- 第一个 ImageView,靠右上角 -->

    <!-- 第二个 ImageView,靠左上角 -->
    <ImageView
        android:id="@+id/imageView5"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_marginTop="4dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/seting_3" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_marginTop="4dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/back_2" />

    <!-- Start Scan 按钮 -->

    <!-- ListView -->
    <Button
        android:id="@+id/btn_start_scan"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp"
        android:text="Start Scan"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView5" />

    <!-- 输入框 -->
    <ListView
        android:id="@+id/list_devices"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_start_scan" />

    <!-- 发送按钮 -->

    <!-- 响应文本视图 -->

    <EditText
        android:id="@+id/inputEditText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:hint="Enter message"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/list_devices" />

    <Button
        android:id="@+id/sendButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Send"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/responseTextView" />

    <TextView
        android:id="@+id/responseTextView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:paddingTop="16dp"
        android:text="Response will be shown here"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/inputEditText" />

</androidx.constraintlayout.widget.ConstraintLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值