当前位置:首页 > 行业动态 > 正文

如何在Android上实现蓝牙聊天功能?

Android实现蓝牙聊天功能需要使用Bluetooth API进行设备搜索、配对,建立连接后通过输入输出流传输消息。

Android实现蓝牙聊天功能

一、前言

如何在Android上实现蓝牙聊天功能?  第1张

随着移动设备的普及,蓝牙技术已经成为一种常见的无线通信方式,在Android平台上,通过蓝牙实现设备之间的数据传输和通讯是一种非常实用的功能,本文将详细讲解如何在Android应用中实现一个简单的蓝牙聊天功能,包括蓝牙的搜索、配对、连接以及数据的发送和接收。

二、准备工作

在开始编写代码之前,需要确保开发环境配置正确,以下是所需的工具和库:

1、Android Studio: 官方集成开发环境(IDE)。

2、BluetoothAdapter: Android提供的用于管理蓝牙功能的类。

3、BluetoothSocket: 用于蓝牙通信的套接字。

4、BluetoothDevice: 表示远程蓝牙设备。

5、Handler: 用于处理消息传递。

6、Message: 用于封装信息。

7、UUID: 通用唯一识别码,用于标识服务。

三、项目结构

为了便于管理和理解,建议按照以下目录结构组织项目:

src/main/java

com.example.bluetoothchat

BluetoothChatActivity.java: 主活动类。

BluetoothService.java: 蓝牙服务类。

Constants.java: 常量定义文件。

MessageHandler.java: 消息处理类。

四、常量定义 (Constants.java)

package com.example.bluetoothchat;
public class Constants {
    public static final String DEVICE_NAME = "MyBluetoothChat"; // 设备名称
    public static final UUID MY_UUID = java.util.UUID.randomUUID(); // 随机生成一个UUID
}

五、蓝牙服务类 (BluetoothService.java)

这个类负责蓝牙的初始化、搜索、配对和连接等操作。

package com.example.bluetoothchat;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
public class BluetoothService {
    private static final String TAG = "BluetoothService";
    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;    // there is an active connection
    private static final int STATE_CONNECTED = 3;    // now connected to a remote device
    private BluetoothAdapter mAdapter;
    private Context mContext;
    private Handler mHandler;
    private AcceptThread mAcceptThread;
    private ConnectThread mConnectThread;
    private ConnectedThread mConnectedThread;
    private int mState;
    private UUID mUUID;
    private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME, device).sendToTarget();
        }
    };
    public BluetoothService(Context context, Handler handler) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mState = STATE_NONE;
        mHandler = handler;
        mUUID = Constants.MY_UUID;
        mContext = context;
    }
    private synchronized void setState(int state) {
        mState = state;
        mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
    }
    private synchronized void start() {
        if (D) Log.d(TAG, "start");
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        if (mAcceptThread == null) {
            mAcceptThread = new AcceptThread();
            mAcceptThread.start();
            setState(STATE_LISTEN);
        }
        if (mScanning) {
            mAdapter.stopLeScan(mLeScanCallback);
            setState(STATE_NONE);
            return;
        }
    }
    private synchronized void connect(BluetoothDevice device) {
        if (D) Log.d(TAG, "connect to: " + device);
        if (mState == STATE_CONNECTING) {
            if (mConnectThread != null) {
                mConnectThread.cancel();
                mConnectThread = null;
            }
        }
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        mConnectThread = new ConnectThread(device);
        mConnectThread.start();
        setState(STATE_CONNECTING);
    }
    private synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
        if (D) Log.d(TAG, "connected");
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        if (mAcceptThread != null) {
            mAcceptThread.cancel();
            mAcceptThread = null;
        }
        mConnectedThread = new ConnectedThread(socket);
        mConnectedThread.start();
        setState(STATE_CONNECTED);
        Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);
        Bundle bundle = new Bundle();
        bundle.putString("toast", "Connected to " + device.getName());
        msg.setData(bundle);
        mHandler.sendMessage(msg);
    }
    private synchronized void stop() {
        if (D) Log.d(TAG, "stop");
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        if (mAcceptThread != null) {
            mAcceptThread.cancel();
            mAcceptThread = null;
        }
        setState(STATE_NONE);
    }
    public synchronized void write(byte[] out) {
        Log.d(TAG, "write: Write message: " + new String(out));
        if (mConnectedThread != null) {
            mConnectedThread.write(out);
        } else {
            Log.w(TAG, "write: Not connected");
        }
    }
    public void startDiscovery() {
        if (mAdapter.isDiscovering()) {
            mAdapter.cancelDiscovery();
        } else {
            mAdapter.startDiscovery();
        }
    }
    // Create a new server socket using the UUID from the profile name and listen for incoming connections.
    private class AcceptThread extends Thread {
        private final BluetoothServerSocket mmServerSocket;
        private String mSocketType;
        public AcceptThread() {
            BluetoothServerSocket tmp = null;
            mSocketType = "Secure";
            try {
                if (secure) {
                    tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
                } else {
                    tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID);
                    mSocketType = "Insecure";
                }
            } catch (IOException e) {
                Log.e(TAG, "Socket Type: " + mSocketType + "createListener() failed", e);
            }
            mmServerSocket = tmp;
            mAdapter.cancelDiscovery();
        }
        public void run() {
            if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
            setName("AcceptThread");
            BluetoothSocket socket = null;
            while (mState != STATE_CONNECTED) {
                try {
                    socket = mmServerSocket.accept();
                } catch (IOException e) {
                    Log.e(TAG, "accept() failed", e);
                    break;
                }
                if (socket != null) {
                    synchronized (BluetoothService.this) {
                        switch (mState) {
                            case STATE_LISTEN:
                            case STATE_CONNECTTHEM:
                                connected(socket, socket.getRemoteDevice());
                                break;
                            case STATE_NONE:
                            case STATE_CONNECTED:
                                try {
                                    mmServerSocket.close();
                                      } catch (IOException e) {
                                          Log.e(TAG, "Could not close unwanted socket", e);
                                      } break;
                        }
                    }
                }
            }
            if (D) Log.i(TAG, "END mAcceptThread", this);
            setState(STATE_NONE);
            mAcceptThread = null;
            if (mConnectedThread != null) {
                mConnectedThread.cancel();
                mConnectedThread = null;
            }
            if (mmServerSocket != null) {
                try {
                    mmServerSocket.close();
                } catch (IOException e) {
                    Log.e(TAG, "Could not close server socket", e);
                }
            }
        }
        void cancel() {
            mAcceptThread.interrupt();
        }
    }
    // This thread runs while attempting to make an outgoing connection with a device. It runs until it either: establishes a connection and returns or each connection attempt fails to connect then records a message and quits.
    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
        private String mSocketType;
        public ConnectThread(BluetoothDevice device) {
            mmDevice = device;
            BluetoothSocket tmp = null;
            mSocketType = "Secure";
            try {
                if (secure) {
                    tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
                } else {
                    tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
                    mSocketType = "Insecure";
                }
            } catch (IOException e) {
                Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
            }
            mmSocket = tmp;
        }
        public void run() {
            mAdapter.cancelDiscovery();
            setName("ConnectThread");
            setState(STATE_CONNECTING);
            try {
                mmSocket.connect();
            } catch (IOException e) {
                connectionFailed();
                try {
                    mmSocket.close();
                } catch (IOException e2) {
                    Log.e(TAG, "unable to close() " + mSocketType + " socket during connection failure", e2);
                }
                return;
            } finally { }
            connected(mmSocket, mmDevice);
        }
        void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { } because you cannot reliably close input stream here due to possible blocking by buffered I/O operations System.exit(0); } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } ) new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_READ: byte[] readBuf = (byte[]) msg.obj; String action = new String(readBuf, 0, msg.arg1, "utf-8"); if (true) { Log.d(TAG, "Read: " + action); } return true; case MESSAGE_WRITE: byte[] writeBuf = (byte[]) msg.obj; Integer wrote = msg.arg1; if (true) { Log.d(TAG, "Write: " + new String(writeBuf, 0, writeBuf.length, "utf-8")); } return true; case MESSAGE_DEVICE_NAME: msg.obj = msg.obj + "
Rename me"; break; case MESSAGE_TOAST: Toast msg = msg.obj; msg.show(); break; case MESSAGE_STATE_CHANGE: switch (msg.arg1) { case BluetoothService.STATE_NONE: break; case BluetoothService.STATE_LISTEN: break; case BluetoothService.STATE_CONNECTING: break; case BluetoothService.STATE_CONNECTED: break; case BluetoothService.STATE_MESSAGE_READ: break; default: break; } break; default: super.handleMessage(msg); } } ); 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) { Log.e(TAG, "temp sockets not created", e); } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { byte[] buffer = new byte[1024]; int numBytes; while (true) { try { numBytes = mmInStream.read(buffer); String readMessage = new String(buffer, 0, numBytes, "UTF-8"); mHandler.obtainMessage(BluetoothService.MESSAGE_READ, buffer, 0, numBytes).sendToTarget(); } catch (IOException e) { Log.d(TAG, "Input stream was disconnected", e); break; } } } void write(byte[] bytes) { try { mmOutStream.write(bytes); mHandler.obtainMessage(BluetoothService.MESSAGE_WRITE, bytes, bytes.length).sendToTarget(); } catch (IOException e) { Log.e(TAG, "Error occurred when sending data", e); break; } finally { try { mmInStream.close(); } catch (IOException e) { Log.e(TAG, "Error closing input stream", e); } catch (NullPointerException e2) { Log.e(TAG, "Null pointer exception on input stream close", e2); } finally { try { mmOutStream.close(); } catch (IOException e) { Log.e(TAG, "Error closing output stream", e); } catch (NullPointerException e2) { Log.e(TAG, "Null pointer exception on output stream close", e2); } finally { try { mmSocket.close(); } catch (IOException e) { Log.e(TAG, "Error closing socket", e); } finally { super.finalize(); } }}}}};```

各位小伙伴们,我刚刚为大家分享了有关“Android实现蓝牙聊天功能”的知识,希望对你们有所帮助。如果您还有其他相关问题需要解决,欢迎随时提出哦!

0