Android蓝牙通信——与蓝牙模块进行通信传输数据

android蓝牙开发—与蓝牙模块进行通信数据传输(蓝牙串口)

需要与蓝牙模块进行通信。
首先,需要获得一个BluetoothAdapter,可以通过BluetoothAdapter.getDefaultAdapter()获得系统默认的蓝牙适配器,也可以自己指定(没有试过)。然后检查手机的蓝牙是否打开,如果没有,通过enable()方法打开。
完成这些必要的设置后,就可以正式开始与蓝牙模块进行通信了:


BluetoothChatService类做所有蓝牙相关的工作,建立和管理蓝牙连接其他装置。它有一个线程,监听传入连接,连接装置,和一个执行数据传输。

package com.firemonitoringsystem;

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 android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

public class BluetoothChatService {
// 调试
private static final String TAG = “BluetoothChatService”;
private static final boolean D = true;

// 当创建服务器时记录套接字
private static final String NAME = "RetimeFragment";

// UUID
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public static StringBuffer hexString = new StringBuffer();
// 适配器
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
//常数,指示当前的连接状态
public static final int STATE_NONE = 0;       // 当前没有可用的连接
public static final int STATE_LISTEN = 1;     // 现在侦听传入的连接
public static final int STATE_CONNECTING = 2; // 现在开始传出联系
public static final int STATE_CONNECTED = 3;  // 现在连接到远程设备
public static boolean bRun = true;
/**
 * 构造函数。准备一个新的RetimeFragment会话。
 * @param context  用户界面活动的背景
 * @param handler 一个处理程序发送信息到界面
 */
public BluetoothChatService(Context context, Handler handler) {
    mAdapter = BluetoothAdapter.getDefaultAdapter();
    mState = STATE_NONE;
    mHandler = handler;
}

/**
 * 设置当前状态的连接
 * @param state  整数定义当前连接状态
 */
private synchronized void setState(int state) {
    if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
    mState = state;

    // 给新状态的处理程序,界面可以更新
 mHandler.obtainMessage(RetimeFragment.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}

/*** 返回当前的连接状态。 */
public synchronized int getState() {
    return mState;
}

/**
 * 开始聊天服务。特别acceptthread开始会话听力(服务器)模式。所谓的活动onresume() */
public synchronized void start() {
    if (D) Log.d(TAG, "start");

    //取消任何线程试图建立连接
    if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}

    // 取消任何线程正在运行的连接
    if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

    // 启动线程来听一个bluetoothserversocket
    if (mAcceptThread == null) {
        mAcceptThread = new AcceptThread();
        mAcceptThread.start();
    }
    setState(STATE_LISTEN);
}

//连接按键响应函数
/**
 * 开始connectthread启动连接到远程设备。
 * 装置连接的蓝牙设备
 */
public 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);
}

/**
 * 开始connectedthread开始管理一个蓝牙连接
 * bluetoothsocket插座上连接了
 * 设备已连接的蓝牙设备
 */
@SuppressWarnings("unused")
public 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();


    //把名字的连接设备到Activity

    Message msg = mHandler.obtainMessage(RetimeFragment.MESSAGE_DEVICE_NAME);
    Bundle bundle = new Bundle();
    bundle.putString(RetimeFragment.DEVICE_NAME, device.getName());
    msg.setData(bundle);
    mHandler.sendMessage(msg);
    setState(STATE_CONNECTED);
}

/**
 * 停止所有的线程
 */
public 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);
}

/**
 * Write to the ConnectedThread in an unsynchronized manner
 * @param out The bytes to write
 * @see ConnectedThread#write(byte[])
 */
public void write(byte[] out) {
    //创建临时对象
    ConnectedThread r;
    // 同步副本的connectedthread
    synchronized (this) {
        if (mState != STATE_CONNECTED) return;
        r = mConnectedThread;
    }
    // 执行写同步
    r.write(out);
}

/**
 * Indicate that the connection attempt failed and notify the UI Activity.
 */
private void connectionFailed() {
    setState(STATE_LISTEN);

    // 发送失败的信息带回活动
    Message msg = mHandler.obtainMessage(RetimeFragment.MESSAGE_TOAST);
    Bundle bundle = new Bundle();
    bundle.putString(RetimeFragment.TOAST, "无法连接装置");
    msg.setData(bundle);
    mHandler.sendMessage(msg);
}

/**
 * Indicate that the connection was lost and notify the UI Activity.
 */
private void connectionLost() {
    setState(STATE_LISTEN);

    // 发送失败的信息带回Activity
    Message msg = mHandler.obtainMessage(RetimeFragment.MESSAGE_TOAST);
    Bundle bundle = new Bundle();
    bundle.putString(RetimeFragment.TOAST, "装置连接丢失");
    msg.setData(bundle);
    mHandler.sendMessage(msg);
}

/**
 *本线同时侦听传入的连接。它的行为
 *喜欢一个服务器端的客户端。它运行直到连接被接受
 *(或取消)。
 */
private class AcceptThread extends Thread {
    // 本地服务器套接字
    private final BluetoothServerSocket mmServerSocket;

    public AcceptThread() {

        BluetoothServerSocket tmp = null;

        // 创建一个新的侦听服务器套接字
        try {
            tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) {
            Log.e(TAG, "listen() failed", e);
        }
        mmServerSocket = tmp;
    }

    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 (BluetoothChatService.this) {
                    switch (mState) {
                        case STATE_LISTEN:
                        case STATE_CONNECTING:
                            // 正常情况。启动连接螺纹。
                            connected(socket, socket.getRemoteDevice());
                            break;
                        case STATE_NONE:
                        case STATE_CONNECTED:
                            // 没有准备或已连接。新插座终止。
                            try {
                                socket.close();
                            } catch (IOException e) {
                                Log.e(TAG, "Could not close unwanted socket", e);
                            }
                            break;
                    }
                }
            }
        }
        if (D) Log.i(TAG, "END mAcceptThread");
    }

    public void cancel() {
        if (D) Log.d(TAG, "cancel " + this);
        try {
            mmServerSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of server failed", e);
        }
    }
}


/**
 * 本线在试图使传出联系
 *与设备。它径直穿过连接;或者
 *成功或失败。
 */
private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) {
        mmDevice = device;
        BluetoothSocket tmp = null;

        // 得到一个bluetoothsocket为与连接
        // 由于蓝牙设备
        try {
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            Log.e(TAG, "create() failed", e);
        }
        mmSocket = tmp;
    }

    public void run() {
        Log.i(TAG, "BEGIN mConnectThread");
        setName("ConnectThread");

        //总是取消的发现,因为它会减缓连接
        mAdapter.cancelDiscovery();

        // 使一个连接到bluetoothsocket
        try {
            // 这是一个阻塞调用和将只返回一个
            // 成功的连接或例外
            mmSocket.connect();
        } catch (IOException e) {
            connectionFailed();
            //关闭这个socket
            try {
                mmSocket.close();
            } catch (IOException e2) {
                Log.e(TAG, "unable to close() socket during connection failure", e2);
            }
            // 启动服务在重新启动聆听模式
            BluetoothChatService.this.start();
            return;
        }

        // 因为我们所做的connectthread复位
        synchronized (BluetoothChatService.this) {
            mConnectThread = null;
        }

        // 启动连接线程
        connected(mmSocket, mmDevice);
    }

    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed", e);
        }
    }
}

/**
 * 本线在连接与远程设备。
 * 它处理所有传入和传出的传输。
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        Log.d(TAG, "create ConnectedThread");
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // 获得bluetoothsocket输入输出流
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, "没有创建临时sockets", e);
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;

    }

    /**
     * 2017.3.6
     */
    //*****************使用obtainMessage()*************************/

// public void run() {
// Log.i(TAG, “BEGIN mConnectedThread”);
// byte[] buffer = new byte[1024];
// int bytes;
//
// // 继续听InputStream同时连接
// while (true) {
// try {
// // 读取输入流
// bytes = mmInStream.read(buffer);
//
// // 发送获得的字节的用户界面
// mHandler.obtainMessage(RetimeFragment.MESSAGE_READ, bytes, -1, buffer)
// .sendToTarget();
// } catch (IOException e) {
// Log.e(TAG, “disconnected”, e);
// connectionLost();
// break;
// }
// }
// }

    //*****************使用sendMessage()*************************/
    public void run() {

        byte[] buffer = new byte[1024];
        int bytes;
        String readMessage;
        // Keep listening to the InputStream while connected
        while (true) {
            try {
                int availableBytes = mmInStream.available();
                if (availableBytes > 0) {
                    bytes = mmInStream.read(buffer);
                    Message msg = new Message();
                    Bundle data = new Bundle();
                    readMessage = new String(buffer,0,bytes);
                    data.putString("BTdata",readMessage);
                    msg.what = RetimeFragment.MESSAGE_READ;
                    msg.setData(data);
                    mHandler.sendMessage(msg);
                }

            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                break;
            }
        }
    }

// int num = 0;
// byte[] buffer = new byte[1024];
// byte[] buffer_new = new byte[1024];
// int i = 0;
// int n = 0;
// bRun = true;
// //接收线程
// while(true){
// try{
// while(mmInStream.available()==0){
// while(bRun == false){}
// }
// while(true){
// num = mmInStream.read(buffer); //读入数据
// n=0;
//
// String s0 = new String(buffer,0,num);
// fmsg+=s0; //保存收到数据
// for(i=0;i

你可能感兴趣的:(android)