最近又搞到了藍牙通信功能,重搞,走起(看成果,上代碼)。

一、先看成果

Android Bluetooth藍牙開發:Bluetooth藍牙設備之間的連接建立(3) - Zhang Phil -_#Bluetooth通信

二、上代碼

1、藍牙item:bluetooth_item

<?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="wrap_content"
    android:orientation="vertical"
    android:padding="12dp">

    <TextView
        android:id="@+id/tv_device_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black"
        android:textSize="16sp"
        android:textStyle="bold" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_device_address"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/black"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/tv_pair_state"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="12sp" />
    </LinearLayout>

</LinearLayout>

2、demo主Activityxml:activity_bluetooth_demo

<?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:background="@mipmap/sdbei"
    android:orientation="vertical">

    <!-- 標題欄 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        android:gravity="center_vertical"
        android:paddingHorizontal="16dp">

        <Button
            android:id="@+id/isOut"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@null"
            android:text="退出"
            android:textColor="@android:color/white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:text="藍牙通信"
            android:textColor="@android:color/white"
            android:textSize="18sp" />
    </LinearLayout>

    <!-- 設備列表區域 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp">

        <ListView
            android:id="@+id/device_list"
            android:layout_width="match_parent"
            android:layout_height="150dp"
            android:background="@android:color/white"
            android:divider="@color/color_EEEEEE"
            android:dividerHeight="1dp" />

        <!-- 接收消息提示 -->
        <TextView
            android:id="@+id/tv_received"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="接收消息區"
            android:textColor="@android:color/black" />
    </LinearLayout>

    <!-- 聊天消息列表 -->
    <ListView
        android:id="@+id/chatListView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:divider="@null"
        android:padding="8dp" />

    <!-- 輸入區域 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/et_message"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="輸入消息..."
            android:inputType="text"
            android:maxLines="3" />

        <Button
            android:id="@+id/btn_send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="發送" />
    </LinearLayout>

    <!-- 功能按鈕區 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="16dp">

        <Button
            android:id="@+id/btn_scan"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="16dp"
            android:text="搜索藍牙設備" />

        <Button
            android:id="@+id/btn_start_server"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="啓動服務端" />
    </LinearLayout>

</LinearLayout>

3、BluetoothCallback 

public interface BluetoothCallback {
    // 設備發現回調
    void onDeviceFound(BluetoothDevice device);
    // 連接狀態變化
    void onConnectionStateChanged(boolean isConnected, BluetoothDevice device);
    // 消息接收回調
    void onMessageReceived(String message);
    // 操作結果回調
    void onOperationResult(boolean success, String message);
}

4、BluetoothManager

public class BluetoothManager {
    private static final String TAG = "BluetoothManager";
        private static final String SERVICE_NAME = "GlobalBluetoothService";
        private static final UUID UUID_DEVICE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

        // 單例實例
        private static volatile BluetoothManager instance;

        private Context mContext;
        private BluetoothAdapter mBluetoothAdapter;
        private BluetoothSocket mClientSocket;
        private BluetoothServerSocket mServerSocket;
        private ConnectedThread mConnectedThread;
        private BluetoothCallback mCallback;
        private List<BluetoothDevice> mFoundDevices = new ArrayList<>();
        private boolean isConnected = false;
        private BluetoothDevice mConnectedDevice;

        // 權限請求碼
        public static final int PERMISSION_REQUEST_BLE_S = 100;
        public static final int PERMISSION_REQUEST_BLE_LEGACY = 101;
        public static final int REQUEST_OPEN_BLUETOOTH = 0;

        // 廣播接收器
        private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (action == null) return;

                switch (action) {
                    case BluetoothDevice.ACTION_FOUND:
                        handleDeviceFound(intent);
                        break;
                    case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                        if (mCallback != null) {
                            mCallback.onOperationResult(true, "掃描完成,共發現" + mFoundDevices.size() + "台設備");
                        }
                        break;
                    case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                        handleBondStateChanged(intent);
                        break;
                    case BluetoothAdapter.ACTION_STATE_CHANGED:
                        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                        if (state == BluetoothAdapter.STATE_OFF) {
                            disconnect();
                            if (mCallback != null) {
                                mCallback.onConnectionStateChanged(false, null);
                            }
                        }
                        break;
                }
            }
        };

        // 主線程Handler
        private Handler mHandler = new Handler(Looper.getMainLooper());

        // 私有構造函數
    private BluetoothManager(Context context) {
            this.mContext = context.getApplicationContext();
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            registerReceiver();
        }

        // 單例獲取方法
        public static BluetoothManager getInstance(Context context) {
            if (instance == null) {
                synchronized (BluetoothManager.class) {
                    if (instance == null) {
                        instance = new BluetoothManager(context);
                    }
                }
            }
            return instance;
        }

        // 註冊廣播接收器
        private void registerReceiver() {
            IntentFilter filter = new IntentFilter();
            filter.addAction(BluetoothDevice.ACTION_FOUND);
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
            filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
            mContext.registerReceiver(mBluetoothReceiver, filter);
        }

        // 設置回調
        public void setCallback(BluetoothCallback callback) {
            this.mCallback = callback;
        }

        // 檢查設備是否支持藍牙
        public boolean isBluetoothSupported() {
            return mBluetoothAdapter != null;
        }

        // 檢查藍牙是否開啓
        public boolean isBluetoothEnabled() {
            return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
        }

        // 開啓藍牙
        @SuppressLint("MissingPermission")
        public boolean enableBluetooth() {
            if (mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled()) {
                return mBluetoothAdapter.enable();
            }
            return true;
        }

        // 檢查所有藍牙權限
        public boolean checkAllPermissions() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                return ActivityCompat.checkSelfPermission(mContext, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED
                        && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED;
            } else {
                boolean hasBluetooth = ActivityCompat.checkSelfPermission(mContext, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED;
                boolean hasBluetoothAdmin = ActivityCompat.checkSelfPermission(mContext, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED;
                boolean hasLocation = ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    hasLocation &= ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
                }
                return hasBluetooth && hasBluetoothAdmin && hasLocation;
            }
        }

        // 獲取需要請求的權限列表
        public String[] getRequiredPermissions() {
            List<String> permissions = new ArrayList<>();

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                permissions.add(Manifest.permission.BLUETOOTH_SCAN);
                permissions.add(Manifest.permission.BLUETOOTH_CONNECT);
            } else {
                permissions.add(Manifest.permission.BLUETOOTH);
                permissions.add(Manifest.permission.BLUETOOTH_ADMIN);
                permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
                }
            }
            return permissions.toArray(new String[0]);
        }

        // 開始掃描設備
        @SuppressLint("MissingPermission")
        public void startScan() {
            if (!isBluetoothSupported()) {
                notifyOperationResult(false, "設備不支持藍牙");
                return;
            }

            if (!isBluetoothEnabled()) {
                notifyOperationResult(false, "藍牙未開啓");
                return;
            }

            if (!checkAllPermissions()) {
                notifyOperationResult(false, "缺少藍牙權限");
                return;
            }

            // 檢查位置服務(Android 10及以下)
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q && !isLocationEnabled()) {
                notifyOperationResult(false, "請開啓位置服務以搜索藍牙設備");
                return;
            }

            // 清除之前的設備列表
            mFoundDevices.clear();

            // 如果正在掃描,先停止
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }

            // 開始掃描
            boolean started = mBluetoothAdapter.startDiscovery();
            if (started) {
                notifyOperationResult(true, "開始掃描設備...");
                // 30秒後自動停止掃描
                mHandler.postDelayed(() -> {
                    if (mBluetoothAdapter.isDiscovering()) {
                        stopScan();
                    }
                }, 30000);
            } else {
                notifyOperationResult(false, "掃描啓動失敗");
            }
        }

        // 停止掃描
        @SuppressLint("MissingPermission")
        public void stopScan() {
            if (mBluetoothAdapter != null && mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
                notifyOperationResult(true, "掃描已停止");
            }
        }

        // 處理髮現的設備
        @SuppressLint("MissingPermission")
        private void handleDeviceFound(Intent intent) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if (device != null && !TextUtils.isEmpty(device.getAddress())) {
                // 避免重複添加
                boolean isExist = false;
                for (BluetoothDevice d : mFoundDevices) {
                    if (TextUtils.equals(d.getAddress(), device.getAddress())) {
                        isExist = true;
                        break;
                    }
                }

                if (!isExist) {
                    mFoundDevices.add(device);
                    if (mCallback != null) {
                        mCallback.onDeviceFound(device);
                    }
                }
            }
        }

        // 處理配對狀態變化
        @SuppressLint("MissingPermission")
        private void handleBondStateChanged(Intent intent) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);

            if (bondState == BluetoothDevice.BOND_BONDED) {
                notifyOperationResult(true, "配對成功,正在連接...");
                connect(device); // 配對成功後自動連接
            } else if (bondState == BluetoothDevice.BOND_NONE) {
                notifyOperationResult(false, "配對已取消");
            }
        }

        // 連接設備
        @SuppressLint("MissingPermission")
        public void connect(BluetoothDevice device) {
            if (device == null) {
                notifyOperationResult(false, "設備不能為空");
                return;
            }

            // 停止掃描
            stopScan();

            // 如果已連接,先斷開
            if (isConnected) {
                disconnect();
            }

            // 檢查配對狀態
            if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                notifyOperationResult(true, "正在與" + device.getName() + "配對...");
                pairDevice(device);
            } else {
                // 已配對,直接連接
                startClientConnect(device);
            }
        }

        // 配對設備
        private void pairDevice(BluetoothDevice device) {
            try {
                Method method = BluetoothDevice.class.getMethod("createBond");
                method.invoke(device);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                Log.e(TAG, "配對失敗: ", e);
                notifyOperationResult(false, "配對失敗: " + e.getMessage());
            }
        }

        // 客户端連接
        @SuppressLint("MissingPermission")
        private void startClientConnect(BluetoothDevice device) {
            new Thread(() -> {
                try {
                    closeSocket(mClientSocket);

                    // 創建客户端Socket
                    mClientSocket = device.createRfcommSocketToServiceRecord(UUID_DEVICE);
                    Log.d(TAG, "開始連接設備: " + device.getName());
                    mClientSocket.connect();

                    // 連接成功
                    if (mClientSocket.isConnected()) {
                        mConnectedDevice = device;
                        isConnected = true;
                        mHandler.post(() -> {
                            if (mCallback != null) {
                                mCallback.onConnectionStateChanged(true, device);
                                mCallback.onOperationResult(true, "已連接到: " + device.getName());
                            }
                        });

                        // 啓動通信線程
                        mConnectedThread = new ConnectedThread(mClientSocket);
                        mConnectedThread.start();
                    } else {
                        notifyOperationResult(false, "連接失敗");
                    }
                } catch (IOException e) {
                    Log.e(TAG, "連接失敗: ", e);
                    notifyOperationResult(false, "連接失敗: " + e.getMessage());
                    closeSocket(mClientSocket);
                }
            }).start();
        }

        // 啓動服務端監聽
        @SuppressLint("MissingPermission")
        public void startServer() {
            new Thread(() -> {
                try {
                    closeServerSocket();

                    // 創建服務端Socket
                    mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(SERVICE_NAME, UUID_DEVICE);
                    notifyOperationResult(true, "服務端啓動,等待連接...");

                    // 阻塞等待連接
                    BluetoothSocket socket = mServerSocket.accept();
                    if (socket != null && socket.isConnected()) {
                        closeServerSocket();
                        mClientSocket = socket;
                        mConnectedDevice = socket.getRemoteDevice();
                        isConnected = true;

                        mHandler.post(() -> {
                            if (mCallback != null) {
                                mCallback.onConnectionStateChanged(true, mConnectedDevice);
                                mCallback.onOperationResult(true, "已接受連接: " + mConnectedDevice.getName());
                            }
                        });

                        // 啓動通信線程
                        mConnectedThread = new ConnectedThread(socket);
                        mConnectedThread.start();
                    }
                } catch (IOException e) {
                    Log.e(TAG, "服務端啓動失敗: ", e);
                    notifyOperationResult(false, "服務端啓動失敗: " + e.getMessage());
                    closeServerSocket();
                }
            }).start();
        }

        // 發送消息
        public void sendMessage(String message) {
            if (!isConnected || mConnectedThread == null) {
                notifyOperationResult(false, "未連接到設備");
                return;
            }

            if (TextUtils.isEmpty(message)) {
                notifyOperationResult(false, "消息不能為空");
                return;
            }

            mConnectedThread.write(message);
        }

        // 斷開連接
        public void disconnect() {
            if (!isConnected) return;

            isConnected = false;
            if (mConnectedThread != null) {
                mConnectedThread.cancel();
                mConnectedThread = null;
            }

            closeSocket(mClientSocket);
            closeServerSocket();

            mHandler.post(() -> {
                if (mCallback != null) {
                    mCallback.onConnectionStateChanged(false, mConnectedDevice);
                    mCallback.onOperationResult(true, "已斷開連接");
                }
                mConnectedDevice = null;
            });
        }

        // 關閉Socket
        private void closeSocket(BluetoothSocket socket) {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    Log.e(TAG, "關閉Socket失敗: ", e);
                }
            }
        }

        // 關閉服務端Socket
        private void closeServerSocket() {
            if (mServerSocket != null) {
                try {
                    mServerSocket.close();
                } catch (IOException e) {
                    Log.e(TAG, "關閉服務端Socket失敗: ", e);
                }
                mServerSocket = null;
            }
        }

        // 檢查位置服務是否開啓
        private boolean isLocationEnabled() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            android.location.LocationManager lm = (android.location.LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
            return lm.isLocationEnabled();
        } else {
            int mode = Settings.Secure.getInt(
                    mContext.getContentResolver(),
                    Settings.Secure.LOCATION_MODE,
                    Settings.Secure.LOCATION_MODE_OFF
            );
            return mode != Settings.Secure.LOCATION_MODE_OFF;
        }
    }

    // 通知操作結果
    private void notifyOperationResult(boolean success, String message) {
        mHandler.post(() -> {
            if (mCallback != null) {
                mCallback.onOperationResult(success, message);
            }
        });
    }

    // 獲取連接狀態
    public boolean isConnected() {
        return isConnected;
    }

    // 獲取已連接的設備
    public BluetoothDevice getConnectedDevice() {
        return mConnectedDevice;
    }

    // 數據通信線程
    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private final byte[] mmBuffer;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG, "獲取流失敗: ", e);
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
            mmBuffer = new byte[1024];
        }

        public void run() {
            int bytes; // 讀取的字節數

            // 持續讀取數據
            while (true) {
                try {
                    if (mmInStream == null) break;

                    bytes = mmInStream.read(mmBuffer);
                    final String message = new String(mmBuffer, 0, bytes);

                    // 發送到主線程
                    mHandler.post(() -> {
                        if (mCallback != null) {
                            mCallback.onMessageReceived(message);
                        }
                    });
                } catch (IOException e) {
                    Log.e(TAG, "讀取數據失敗: ", e);
                    // 連接斷開
                    mHandler.post(() -> {
                        disconnect();
                    });
                    break;
                }
            }
        }

        // 發送數據
        public void write(String message) {
            try {
                byte[] bytes = message.getBytes();
                mmOutStream.write(bytes);
                notifyOperationResult(true, "消息發送成功");
            } catch (IOException e) {
                Log.e(TAG, "發送數據失敗: ", e);
                notifyOperationResult(false, "消息發送失敗");
            }
        }

        // 取消連接
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "關閉連接失敗: ", e);
            }
        }
    }

    // 釋放資源
    public void destroy() {
        disconnect();
        try {
            mContext.unregisterReceiver(mBluetoothReceiver);
        } catch (IllegalArgumentException e) {
            Log.w(TAG, "廣播接收器未註冊");
        }
        mCallback = null;
        instance = null;
    }
}

5、在Activity中使用

public class BluetoothDemoActivity extends AppCompatActivity implements BluetoothCallback {
    private BluetoothManager bluetoothManager;
    private ListView deviceListView;
    private DeviceAdapter deviceAdapter;
    private List<BluetoothDeviceMessage> deviceList = new ArrayList<>();

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

        // 初始化藍牙管理器
        bluetoothManager = BluetoothManager.getInstance(this);
        bluetoothManager.setCallback(this);

        // 初始化UI
        initView();

        // 檢查藍牙狀態
        checkBluetoothStatus();
    }

    private void initView() {
        deviceListView = findViewById(R.id.device_list);
        deviceAdapter = new DeviceAdapter(this, deviceList);
        deviceListView.setAdapter(deviceAdapter);

        deviceListView.setOnItemClickListener((parent, view, position, id) -> {
//            BluetoothDevice device = deviceList.get(position);
            BluetoothDevice device = ((BluetoothDeviceMessage) deviceList.get(position)).getDevice();
            bluetoothManager.connect(device);
        });

        // 掃描按鈕
        findViewById(R.id.btn_scan).setOnClickListener(v -> {
            deviceList.clear();
            deviceAdapter.notifyDataSetChanged();
            bluetoothManager.startScan();
        });

        // 發送消息按鈕
        findViewById(R.id.btn_send).setOnClickListener(v -> {
            String message = ((EditText) findViewById(R.id.et_message)).getText().toString();
            bluetoothManager.sendMessage(message);
        });

        // 開啓服務端按鈕
        findViewById(R.id.btn_start_server).setOnClickListener(v -> {
            bluetoothManager.startServer();
        });
    }

    @SuppressLint("MissingPermission")
    private void checkBluetoothStatus() {
        if (!bluetoothManager.isBluetoothSupported()) {
            Toast.makeText(this, "設備不支持藍牙", Toast.LENGTH_SHORT).show();
            return;
        }

        if (!bluetoothManager.isBluetoothEnabled()) {
            // 請求開啓藍牙
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, BluetoothManager.REQUEST_OPEN_BLUETOOTH);
        } else {
            // 檢查權限
            checkPermissions();
        }
    }

    private void checkPermissions() {
        if (!bluetoothManager.checkAllPermissions()) {
            ActivityCompat.requestPermissions(
                    this,
                    bluetoothManager.getRequiredPermissions(),
                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ?
                            BluetoothManager.PERMISSION_REQUEST_BLE_S :
                            BluetoothManager.PERMISSION_REQUEST_BLE_LEGACY
            );
        }
    }

    @SuppressLint("MissingPermission")
    @Override
    public void onDeviceFound(BluetoothDevice device) {
        BluetoothDeviceMessage deviceMsg = new BluetoothDeviceMessage(
                TextUtils.isEmpty(device.getName()) ? "未知設備" : device.getName(),
                device.getAddress()
        );
        deviceMsg.setDevice(device);
        deviceMsg.setPaired(device.getBondState() == BluetoothDevice.BOND_BONDED);
        deviceList.add(deviceMsg);

//        deviceList.add(device);
        deviceAdapter.notifyDataSetChanged();
    }

    @Override
    public void onConnectionStateChanged(boolean isConnected, BluetoothDevice device) {
        @SuppressLint("MissingPermission") String status = isConnected ? "已連接到: " + (device != null ? device.getName() : "未知設備") : "連接已斷開";
        Toast.makeText(this, status, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onMessageReceived(String message) {
        // 處理接收到的消息
        runOnUiThread(() -> {
            TextView tvReceived = findViewById(R.id.tv_received);
            tvReceived.append("收到: " + message + "\n");
        });
    }

    @Override
    public void onOperationResult(boolean success, String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean allGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
                break;
            }
        }

        if (!allGranted) {
            Toast.makeText(this, "缺少必要權限,無法使用藍牙功能", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == BluetoothManager.REQUEST_OPEN_BLUETOOTH) {
            if (resultCode == RESULT_OK) {
                Toast.makeText(this, "藍牙已開啓", Toast.LENGTH_SHORT).show();
                checkPermissions();
            } else {
                Toast.makeText(this, "請開啓藍牙以使用功能", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        bluetoothManager.disconnect();
        // 如果是全局使用,可以不調用destroy(),保持單例存在
        // bluetoothManager.destroy();
    }
}

6、打完收工,代碼已全,撤退。。