IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 蓝牙通信开发 -> 正文阅读

[移动开发]Android 蓝牙通信开发

Receiver的设置

一、Receiver1(蓝牙状态的改变通过广播接收)

public class MyReceiver1 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        int status = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,-1);
        switch (status) {
            case BluetoothAdapter.STATE_OFF:
                Log.d(TAG, "蓝牙已关闭");
                break;
            case BluetoothAdapter.STATE_ON:
                Log.d(TAG, "蓝牙已打开");
                break;
            case BluetoothAdapter.STATE_TURNING_OFF:
                Log.d(TAG, "蓝牙关闭中...");
                break;
            case BluetoothAdapter.STATE_TURNING_ON:
                Log.d(TAG, "蓝牙打开中...");
                break;
            default:

                break;
            }
        }
    }
};

二、Receiver2(蓝牙搜索到设备、绑定设备(配对)通过广播接收)

        // 注册蓝牙device接收广播
        IntentFilter intentFilterDevice = new IntentFilter();
        // 开始查找
        intentFilterDevice.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        // 结束查找
        intentFilterDevice.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        // 查找设备(查找到设备)
        intentFilterDevice.addAction(BluetoothDevice.ACTION_FOUND);
        // 设备扫描模式改变 (自己状态的改变action,当设置可见或者不见时都会发送此广播)
        intentFilterDevice.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        // 绑定状态
        intentFilterDevice.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        registerReceiver(mReceiverDeceiver,intentFilterDevice);
@Override
        public void onReceive(Context context,Intent intent) {
            String action = intent.getAction();
            ArraySet<Object> mList = null;
            Policy mAdapter = null;
            if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                // 开始搜索        ——接收广播
                Log.d(TAG,"开始搜索");
                mList.clear();
                mAdapter.refresh(mList);

            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                // 查找到设备完成   —— 接收广播
                Log.d(TAG,"查找到设备完成");

            } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // 搜索到设备       —— 接收广播
                Log.d(TAG,"搜索到设备");
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                mList.add(device);
                mAdapter.refresh(mList);


            } else if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
                // 当自己设备设置蓝牙可见时或者不可见时 —— 接收广播
                int scanMode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,0);
                // 可见时
                if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                    Log.d(TAG,"设备可见监听");
                } else {
                    Log.d(TAG,"设备不可见监听");
                }

            } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                // 绑定状态改变回调
                BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (remoteDevice == null) {
                    Log.d(TAG,"没有绑定设备");
                    return;
                }

                int status = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,0);
                if (status == BluetoothDevice.BOND_BONDED) {
                    Log.d(TAG,"绑定设备完成: " + remoteDevice.getName());
                } else if (status == BluetoothDevice.BOND_BONDING) {
                    Log.d(TAG,"绑定设备中: " + remoteDevice.getName());
                } else if (status == BluetoothDevice.BOND_NONE) {
                    Log.d(TAG,"取消绑定: ");
                }
            }

服务端代码

/**
 * <p>Title: AccepThread</p >
 * <p>Description: 服务端Socket通过accept()一直监听客户端连接的线程</p >
 * <p>Company: ihaveu</p >
 *
 * @author kenan
 * @date 2021/12/12
 */
public class AccepThread extends Thread {
    /** 连接的名称*/
    private static final String NAME = "BluetoothClass";
    /** UUID*/
    private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
    /** 服务端蓝牙Sokcet*/
    private final BluetoothServerSocket mmServerSocket;
    private final BluetoothAdapter mBluetoothAdapter;
    /** 线程中通信的更新UI的Handler*/
    private final Handler mHandler;
    /** 监听到有客户端连接,新建一个线程单独处理,不然在此线程中会堵塞*/
    private ConnectedThread mConnectedThread;
    public AccepThread(BluetoothAdapter adapter, Handler handler) throws IOException {
        mBluetoothAdapter = adapter;
        this.mHandler = handler;
        // 获取服务端蓝牙socket
        mmServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
    }
    @Override
    public void run() {
        super.run();
        // 连接的客户端soacket
        BluetoothSocket socket = null;
        // 服务端是不退出的,要一直监听连接进来的客户端,所以是死循环
        while (true){
            // 通知主线程更新UI,客户端开始监听
            mHandler.sendEmptyMessage(Constant.MSG_START_LISTENING);
            try {
                // 获取连接的客户端socket
                socket =  mmServerSocket.accept();
            } catch (IOException e) {
                // 通知主线程更新UI, 获取异常
                mHandler.sendEmptyMessage(Constant.MSG_ERROR);
                e.printStackTrace();
                // 服务端退出一直监听线程
                break;
            }
            if(socket != null) {
                // 管理连接的客户端socket
                manageConnectSocket(socket);

            }
        }
    }
    /**
     * 管理连接的客户端socket
     * @param socket
     */
    private void manageConnectSocket(BluetoothSocket socket) {
        // 只支持同时处理一个连接
        // mConnectedThread不为空,踢掉之前的客户端
        if(mConnectedThread != null) {
            mConnectedThread.cancle();
        }
        // 主线程更新UI,连接到了一个客户端
        mHandler.sendEmptyMessage(Constant.MSG_GOT_A_CLINET);
        // 新建一个线程,处理客户端发来的数据
        mConnectedThread = new ConnectedThread(socket, mHandler);
        mConnectedThread.start();
    }
   /**
     * 断开服务端,结束监听
     */
    public void cancle() {
        try {
            mmServerSocket.close();
            mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 发送数据
     * @param data
     */
     public void sendData(byte[] data){
         if(mConnectedThread != null) {
             mConnectedThread.write(data);
         }
     }
}

客户端代码

/**
 * <p>Title: ConnectThread</p >
 * <p>Description: 客户端逻辑: 客户端的线程,处理客户端socket</p >
 * <p>Company: ihaveu</p >
 *
 * @author kenan
 * @date 2021/12/12
 */
public class ConnectThread extends Thread{
    private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
    /** 客户端socket*/
    private final BluetoothSocket mmSoket;
    /** 要连接的设备*/
    private final BluetoothDevice mmDevice;
    private BluetoothAdapter mBluetoothAdapter;
    /** 主线程通信的Handler*/
    private final Handler mHandler;
    /** 发送和接收数据的处理类*/
    private ConnectedThread mConnectedThread;
    public ConnectThread(BluetoothDevice device, BluetoothAdapter bluetoothAdapter, Handler mUIhandler) {
        mmDevice = device;
        mBluetoothAdapter = bluetoothAdapter;
        mHandler = mUIhandler;
        BluetoothSocket tmp = null;
        try {
            // 创建客户端Socket
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            e.printStackTrace();
        }
        mmSoket = tmp;
    }
    @Override
    public void run() {
        super.run();
        // 关闭正在发现设备.(如果此时又在查找设备,又在发送数据,会有冲突,影响传输效率)
        mBluetoothAdapter.cancelDiscovery();
        try {
            // 连接服务器
            mmSoket.connect();
        } catch (IOException e) {
            // 连接异常就关闭
            try {
                mmSoket.close();
            } catch (IOException e1) {
            }
            return;
        }
        manageConnectedSocket(mmSoket);
    }
    private void manageConnectedSocket(BluetoothSocket mmSoket) {
        // 通知主线程连接上了服务端socket,更新UI
        mHandler.sendEmptyMessage(Constant.MSG_CONNECTED_TO_SERVER);
        // 新建一个线程进行通讯,不然会发现线程堵塞
        mConnectedThread = new ConnectedThread(mmSoket,mHandler);
        mConnectedThread.start();
    }
    /**
     * 关闭当前客户端
     */
    public void cancle() {
        try {
            mmSoket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 发送数据
     * @param data
     */
    public void sendData(byte[] data) {
        if(mConnectedThread != null) {
            mConnectedThread.write(data);
        }
    }
}

共同通讯处理类

/**
 * <p>Title: ConnectedThread</p >
 * <p>Description: 客户端和服务端 处理 发送数据 和获取数据</p >
 * <p>Company: ihaveu</p >
 *
 * @author kenna
 * @date 2021/12/12
 */
public class ConnectedThread extends Thread{
    /** 当前连接的客户端BluetoothSocket*/
    private final BluetoothSocket mmSokcet;
    /** 读取数据流*/
    private final InputStream mmInputStream;
    /** 发送数据流*/
    private final OutputStream mmOutputStream;
    /** 与主线程通信Handler*/
    private Handler mHandler;
    private String TAG = "ConnectedThread";
    public ConnectedThread(BluetoothSocket socket,Handler handler) {
        mmSokcet = socket;
        mHandler = handler;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mmInputStream = tmpIn;
        mmOutputStream = tmpOut;
    }
    @Override
    public void run() {
        super.run();
        byte[] buffer = new byte[1024];
        while (true) {
            try {
                // 读取数据
                int bytes = mmInputStream.read(buffer);
                if(bytes > 0) {
                    String data = new String(buffer,0,bytes,"utf-8");
                    // 把数据发送到主线程, 此处还可以用广播
                    Message message = mHandler.obtainMessage(Constant.MSG_GOT_DATA,data);
                    mHandler.sendMessage(message);
                }
                Log.d(TAG, "messge size :" + bytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    // 踢掉当前客户端
    public void cancle() {
        try {
            mmSokcet.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 服务端发送数据
     * @param data
     */
    public void write(byte[] data) {
        try {
            mmOutputStream.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

蓝牙通信的步骤如下:

1,开启蓝牙

2,搜索可用设备

3,创建蓝牙socket,获取输入输出流

4,读取和写入数据

5,断开连接关闭蓝牙

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 16:03:59  更:2021-12-14 16:05:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:54:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码