封装一个Android蓝牙串口工具类

原文地址:https://www.shanya.world/archives/2fd981ea.html

把串口通信相关代码封装一下,省的每次都要重新写那些啰嗦的代码。

如何上传 jitpack 参考: https://www.shanya.world/archives/c0a1d02b.html

源码地址: https://github.com/Shanyaliux/SerialPortUtil

使用方法

  • 根目录的 build.gradle 添加 maven { url 'https://jitpack.io' } , 位置如下
allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }
  • 添加依赖
implementation 'com.github.Shanyaliux:SerialPortUtil:1.0.0'
  • 调用方法
/**
* 获取串口工具实例
*@param cntext
*@param new OnSerialPortListener() 收到消息监听
*/
SerialPortUtil serialPortUtil = SerialPortUtil.getInstance(this, new SerialPortUtil.OnSerialPortListener() {
            @Override
            public void onReceivedData(String data) {
                // 这里建议使用handler处理
            }
        });


/**
* 扫描可用设备
*/
serialPortUtil.doDiscovery();

/**
* 发送数据
*/
serialPortUtil.sendData("Hello World\n");

/**
* 获取已配对设备列表给ListView显示
*/
serialPortUtil.getPairedDevicesArrayAdapter()

/**
* 获取未配对设备列表给ListView显示
*/
serialPortUtil.getUnPairedDevicesArrayAdapter()

/**
* ListView 点击连接设置监听
*/
listView.setOnItemClickListener(serialPortUtil.getDevicesClickListener());

具体源码

package com.shanya.serialportutil;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.Toast;

import androidx.core.content.ContextCompat;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import java.util.UUID;

public class SerialPortUtil {

    private final static String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";   //SPP服务UUID号
    private Context context;
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothSocket bluetoothSocket;
    private ArrayAdapter<String> pairedDevicesArrayAdapter;
    private ArrayAdapter<String> unPairedDevicesArrayAdapter;
    private InputStream inputStream;
    private OnSerialPortListener onSerialPortListener;

    private static SerialPortUtil serialPortUtil;
    public static SerialPortUtil getInstance(Context context,OnSerialPortListener onSerialPortListener){
        if (serialPortUtil == null) {
            serialPortUtil = new SerialPortUtil(context,onSerialPortListener);
        }
        return serialPortUtil;
    }

    private SerialPortUtil(Context context, OnSerialPortListener onSerialPortListener) {
        this.context = context.getApplicationContext();
        this.onSerialPortListener = onSerialPortListener;
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        pairedDevicesArrayAdapter = new ArrayAdapter<>(context, R.layout.device_name);
        unPairedDevicesArrayAdapter = new ArrayAdapter<>(context,R.layout.device_name);
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    if (device != null) {
                        if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                            pairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                        } else {
                            unPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                        }
                    }
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    //搜索完成
                    System.out.println("ok");
                    if (unPairedDevicesArrayAdapter.getCount() == 0) {
                        System.out.println("未找到新设备");
                    }
                }
            }
        };
        context.registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
        context.registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
        context.registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        if (!pairedDevices.isEmpty()){
            for (BluetoothDevice device : pairedDevices) {
                pairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
            }
        }else {
            String noDevices = "未找到已配对设备";
            pairedDevicesArrayAdapter.add(noDevices);
        }
    }

    public void doDiscovery(){
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) !=
                PackageManager.PERMISSION_GRANTED){
            Toast.makeText(context,"没有权限",Toast.LENGTH_SHORT).show();
        }else{
            if (bluetoothAdapter.isDiscovering()){
                bluetoothAdapter.cancelDiscovery();
            }
            bluetoothAdapter.startDiscovery();
        }
    }

    public void sendData(String data){
        if(!bluetoothAdapter.isEnabled()){
            Toast.makeText(context,"请先打开蓝牙",Toast.LENGTH_SHORT).show();
            return;
        }
        if (bluetoothSocket == null){
            Toast.makeText(context,"请先连接设备",Toast.LENGTH_SHORT).show();
            return;
        }
        try{
            int n = 0;
            OutputStream outputStream = bluetoothSocket.getOutputStream();
            byte[] bos = data.getBytes();
            for (byte bo : bos) {
                if (bo == 0x0a) n++;
            }
            byte[] bos_new = new byte[bos.length + n];
            n = 0;
            for (byte bo : bos) { //手机中换行为0a,将其改为0d 0a后再发送
                if (bo == 0x0a) {
                    bos_new[n] = 0x0d;
                    n++;
                    bos_new[n] = 0x0a;
                } else {
                    bos_new[n] = bo;
                }
                n++;
            }

            outputStream.write(bos_new);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    private AdapterView.OnItemClickListener devicesClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            bluetoothAdapter.cancelDiscovery();
            String info = ((TextView) view).getText().toString();
            String address = info.substring(info.length() - 17);

            //返回地址供于连接
            BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);
            try{
                bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
                bluetoothSocket.connect();
                Toast.makeText(context,"连接" + bluetoothDevice.getName() + "成功",Toast.LENGTH_SHORT).show();
                inputStream = bluetoothSocket.getInputStream();
                readThread.start();
            }catch (IOException e){
                Toast.makeText(context,"连接失败",Toast.LENGTH_SHORT).show();
                try {
                    bluetoothSocket.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

            }
        }
    };

    private Thread readThread = new Thread(){

        public void run(){
            super.run();
            byte[] buffer = new byte[0];
            int len;
            String s;
            boolean flag = false;
            //noinspection InfiniteLoopStatement
            while(true){
                try {
                    sleep(100);
                    len = inputStream.available();
                    while(len != 0) {
                        flag = true;
                        buffer = new byte[len];
                        //noinspection ResultOfMethodCallIgnored
                        inputStream.read(buffer);
                        sleep(10);//读入数据
                        len = inputStream.available();
                    }
                    if (flag){
                        s = new String(buffer, StandardCharsets.UTF_8);
                        onSerialPortListener.onReceivedData(s);
                        flag = false;
                    }
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    public ArrayAdapter<String> getPairedDevicesArrayAdapter() {
        return pairedDevicesArrayAdapter;
    }

    public ArrayAdapter<String> getUnPairedDevicesArrayAdapter() {
        return unPairedDevicesArrayAdapter;
    }

    public AdapterView.OnItemClickListener getDevicesClickListener() {
        return devicesClickListener;
    }

    public interface OnSerialPortListener{
        void onReceivedData(String data);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章