Android藍牙通信:實現跨設備數據傳輸與控制

一、什麼是藍牙通信

藍牙(Bluetooth)是一種短距離無線通信技術,它的傳輸距離一般在10米以內,最高不超過100米。在現代生活中,藍牙被廣泛應用於手機、電腦、藍牙音箱等設備的數據傳輸和控制。

藍牙通信的特點是無需數據線連接兩台設備,同時支持多設備同時連接,傳輸速率相對較慢但功耗低,穩定性較好。

二、藍牙通信的實現技術

Android系統提供了Bluetooth API,使得開發者可以方便地實現藍牙通信功能。

在藍牙通信中,一般存在服務端和客戶端兩個角色。服務端負責創建藍牙連接,等待客戶端連接並接收客戶端發送的數據。而客戶端則負責搜索可用的服務端並向其發送數據。

在本文的藍牙通信示例中,我們將演示如何在Android設備上實現藍牙通信並通過藍牙控制LED燈的開關。其中,一台設備將扮演服務端的角色,而另一台設備則作為客戶端。

三、藍牙通信示例代碼

示例代碼中,我們將在兩個Activity中實現藍牙通信功能。第一個Activity作為服務端,第二個Activity作為客戶端。

服務端代碼


    private BluetoothAdapter mAdapter;
    private AcceptThread mAcceptThread;
    private ConnectThread mConnectThread;
    private ConnectedThread mConnectedThread;
    private int mState;
 
    private static final int STATE_NONE = 0;       // we're doing nothing
    private static final int STATE_LISTEN = 1;     // now listening for incoming connections
    private static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
    private static final int STATE_CONNECTED = 3;  // now connected to a remote device
 
    public BluetoothService() {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mState = STATE_NONE;
    }
 
    private synchronized void setState(int state) {
        mState = state;
    }
 
    public synchronized int getState() {
        return mState;
    }
 
    public synchronized void start() {
        cancelConnectThread();
        cancelConnectedThread();
 
        if (mAcceptThread == null) {
            mAcceptThread = new AcceptThread();
            mAcceptThread.start();
        }
        setState(STATE_LISTEN);
    }
 
    public synchronized void connect(BluetoothDevice device) {
        cancelConnectThread();
        cancelConnectedThread();
        mConnectThread = new ConnectThread(device);
        mConnectThread.start();
        setState(STATE_CONNECTING);
    }
 
    public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
        cancelConnectThread();
        cancelConnectedThread();
        mConnectedThread = new ConnectedThread(socket);
        mConnectedThread.start();
        setState(STATE_CONNECTED);
    }
 
    public synchronized void stop() {
        cancelConnectThread();
        cancelConnectedThread();
        cancelAcceptThread();
        setState(STATE_NONE);
    }
 
    public void write(byte[] out) {
        ConnectedThread r;
        synchronized (this) {
            if (mState != STATE_CONNECTED) return;
            r = mConnectedThread;
        }
        r.write(out);
    }
 
    private void connectionFailed() {
        setState(STATE_LISTEN);
    }
 
    private void connectionLost() {
        setState(STATE_LISTEN);
    }
 
    private void cancelConnectThread() {
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }
    }
 
    private void cancelConnectedThread() {
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
    }
 
    private void cancelAcceptThread() {
        if (mAcceptThread != null) {
            mAcceptThread.cancel();
            mAcceptThread = null;
        }
    }
 
    private class AcceptThread extends Thread {
        private final BluetoothServerSocket mmServerSocket;
 
        public AcceptThread() {
            BluetoothServerSocket tmp = null;
            try {
                tmp = mAdapter.listenUsingRfcommWithServiceRecord("BluetoothService", MY_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mmServerSocket = tmp;
        }
 
        public void run() {
 
            BluetoothSocket socket = null;
 
            while (mState != STATE_CONNECTED) {
                try {
                    socket = mmServerSocket.accept();
                } catch (IOException e) {
                    e.printStackTrace();
                    break;
                }
 
                if (socket != null) {
                    connected(socket, socket.getRemoteDevice());
                }
            }
        }
 
        public void cancel() {
            try {
                mmServerSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
 
        public ConnectThread(BluetoothDevice device) {
            BluetoothSocket tmp = null;
            mmDevice = device;
            try {
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mmSocket = tmp;
        }
 
        public void run() {
            mAdapter.cancelDiscovery();
            try {
                mmSocket.connect();
            } catch (IOException e) {
                connectionFailed();
                try {
                    mmSocket.close();
                } catch (IOException e2) {
                    e2.printStackTrace();
                }
                BluetoothService.this.start();
                return;
            }
            connected(mmSocket, mmDevice);
        }
 
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
 
        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }
 
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;
 
            while (true) {
                try {
                    bytes = mmInStream.read(buffer);
                    mHandler.obtainMessage(BluetoothState.MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();
                } catch (IOException e) {
                    connectionLost();
                    BluetoothService.this.start();
                    break;
                }
            }
        }
 
        public void write(byte[] buffer) {
            try {
                mmOutStream.write(buffer);
                mHandler.obtainMessage(BluetoothState.MESSAGE_WRITE, -1, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
 
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

客戶端代碼


    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothService mBluetoothService;
    private Button mBtnSwitch;
    private boolean mLedOn = false;
 
    private final Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BluetoothState.MESSAGE_READ:
                    break;
                case BluetoothState.MESSAGE_WRITE:
                    break;
                default:
                    break;
            }
        }
    };
 
    private void setupBluetooth() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        } else {
            setupService();
        }
    }
 
    private void setupService() {
        mBluetoothService = new BluetoothService(this, mHandler);
    }
 
    private void connectDevice(Intent data, boolean secure) {
        String address = data.getExtras()
                .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        mBluetoothService.connect(device);
    }
 
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQUEST_CONNECT_DEVICE_SECURE:
                if (resultCode == Activity.RESULT_OK) {
                    connectDevice(data, true);
                }
                break;
            case REQUEST_ENABLE_BT:
                if (resultCode == Activity.RESULT_OK) {
                    setupService();
                } else {
                    Toast.makeText(this, "Bluetooth is not enabled",
                            Toast.LENGTH_SHORT).show();
                    finish();
                }
        }
    }
 
    private void switchLED() {
        if (mLedOn) {
            mBtnSwitch.setText(R.string.btn_led_on);
            byte[] command = "0".getBytes();
            mBluetoothService.write(command);
        } else {
            mBtnSwitch.setText(R.string.btn_led_off);
            byte[] command = "1".getBytes();
            mBluetoothService.write(command);
        }
        mLedOn = !mLedOn;
    }

四、小結

本文介紹了藍牙通信的基本概念和實現技術,並提供了Android設備上藍牙通信的示例代碼。通過示例代碼,我們可以實現在兩台Android設備之間進行藍牙通信,並通過藍牙控制LED燈的開關。

原創文章,作者:TDIS,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/147602.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
TDIS的頭像TDIS
上一篇 2024-11-01 14:10
下一篇 2024-11-01 14:10

相關推薦

  • 如何解決egalaxtouch設備未找到的問題

    egalaxtouch設備未找到問題通常出現在Windows或Linux操作系統上。如果你遇到了這個問題,不要慌張,下面我們從多個方面進行詳細闡述解決方案。 一、檢查硬體連接 首先…

    編程 2025-04-29
  • 跨域通信浮標——實現客戶端之間的跨域通信

    本文將介紹跨域通信浮標的使用方法,該浮標可以實現客戶端之間的跨域通信,解決了瀏覽器同源策略的限制,讓開發者能夠更加方便地進行跨域通信。 一、浮標的原理 跨域通信浮標的原理是基於浮動…

    編程 2025-04-27
  • NB設備上傳數據方案

    NB(Narrow Band)是一種物聯網通信技術,可以實現低功耗、寬覆蓋、多連接等特點。本文旨在探討如何使用NB設備上傳數據。在這篇文章中,我們將介紹NB設備上傳數據的基本原理、…

    編程 2025-04-27
  • 通信專業Python和Java的開發技巧

    本文旨在介紹通信專業Python和Java的開發技巧,為讀者提供實用且可操作的思路和方法。 一、Python在通信領域中的應用 Python是一種優秀的程序設計語言,因其易學易用、…

    編程 2025-04-27
  • ROS通信

    一、概述 ROS是機器人操作系統,是一個開源的、靈活的、分散式的軟體平台,可以幫助我們快速開發機器人應用程序。ROS中的通信是機器人應用程序開發中最重要的部分之一,它是實現多模塊協…

    編程 2025-04-25
  • Python 進程通信

    當需要在不同進程之間進行通信時,Python 提供了幾種方法來實現進程間通信。這些方法包括隊列,管道,共享內存以及套接字。 1. 隊列 Python 隊列是進程安全的,並且可以很方…

    編程 2025-04-24
  • HC-05藍牙模塊控制

    一、簡介 HC-05是一款藍牙串口模塊,與典型的串口模塊相似,可通過UART通信發送和接收數據。它可以很方便地與其他設備進行藍牙通信,例如智能手機,平板電腦等,實現無線控制。HC-…

    編程 2025-04-24
  • TIPC:多節點通信的高效解決方案

    一、TIPC概述 TIPC是一個Linux內核中的通信協議,在多節點通信場景下擁有出色的表現,被許多公司使用。 TIPC協議支持傳輸層的連接管理、擁塞控制、流量調整等高級特性,對於…

    編程 2025-04-24
  • c#串口通信數據讀取

    一、基礎概念 串口通信是指通過串口進行數據交換的過程。串口是指COM口,COM口是計算機硬體設備之一,其可進行非同步數據傳輸,因此能方便地進行數據收發,被廣泛應用於各種領域中。 串口…

    編程 2025-04-24
  • ROS串口通信詳解

    一、ROS介紹 ROS(Robot Operating System)是一個開源的機器人操作系統,為機器人軟體開發提供了很多功能包,如導航、定位、感知等。 ROS主要基於發布/訂閱…

    編程 2025-04-24

發表回復

登錄後才能評論