Android 藍牙搜索、連接、數據讀取發送類


AndroidManifest.xml文件加入藍牙權限聲明,6.0??以上需要動態申請權限,這里不做說明

QQ截圖20200822230225.png

 

類:

package com.xxxx.yyyy.bluetooth;

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

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BlueToothSolve {

private static final String TAG = "BlueToothSolve";

private Context mContext;
private volatile static BlueToothSolve mInstance;

private BlueToothListener listener;

private final static String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB"; //SPP服務UUID號
private BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter(); //獲取本地藍牙適配器,即藍牙設備
private BluetoothListenerReceiver bTreceiver;
private BluetoothAdapter mBtAdapter;
private BluetoothDevice _device = null; //藍牙設備
private BluetoothSocket _socket = null; //藍牙通信socket
private InputStream btIs; //藍牙輸入流
private OutputStream btOs; //藍牙輸出流
private boolean conState = false; //是否連接

private List<String> bTdeviceList;
private ArrayAdapter<String> bTdeviceAdapter;

//藍牙數據讀取以及連接線程池
ExecutorService btThreadPool = Executors.newFixedThreadPool(2);

public boolean getconState(){return conState;}
public ArrayAdapter<String> getbTdeviceAdapter(){return bTdeviceAdapter;}
public BluetoothListenerReceiver getbTreceiver(){return bTreceiver;}

private BlueToothSolve(Context context){
Log.e(TAG, "BlueToothSolve創建");
this.mContext = context;

//注冊藍牙監聽
bTreceiver = new BluetoothListenerReceiver();
//初始化適配器
mBtAdapter = BluetoothAdapter.getDefaultAdapter();

bTdeviceList = new ArrayList<>();
bTdeviceAdapter = new ArrayAdapter<String>(mContext, android.R.layout.simple_list_item_1, bTdeviceList);

//發送及接收線程
Runnable runnable = new Runnable() {
@Override
public void run() {
while (true){
try{
if(conState){ //連接成功
if(revData())
listener.request();
else{
Log.w(TAG, "wait...");
Thread.sleep(10); //串口無數據
// listener.request(); //測試
}
}
}catch (IOException e){
//
}catch (InterruptedException e){
//
}
}
}
};
btThreadPool.execute(runnable);

}

public static BlueToothSolve getInstance(Context context){
if(mInstance == null){
mInstance = new BlueToothSolve(context);
}

return mInstance;
}

public class BluetoothListenerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
switch (Objects.requireNonNull(intent.getAction())) {
case BluetoothAdapter.ACTION_STATE_CHANGED:
int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
switch (blueState) {
case BluetoothAdapter.STATE_TURNING_ON:
Log.w(TAG, "onReceive---------藍牙正在打開中");
break;
case BluetoothAdapter.STATE_ON:
Log.w(TAG, "onReceive---------藍牙已經打開");
//藍牙開啟,開始查找設備
searchBlueTooth();
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.w(TAG, "onReceive---------藍牙正在關閉中");
break;
case BluetoothAdapter.STATE_OFF:
Log.w(TAG, "onReceive---------藍牙已經關閉");
closeDevice();
break;
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
Log.w(TAG, "onReceive---------搜索結束!");
listener.overDiscovery();
break;
case BluetoothDevice.ACTION_ACL_DISCONNECTED:
Log.w(TAG, "onReceive---------連接丟失!");
closeDevice();
listener.disConn();
break;
case BluetoothDevice.ACTION_FOUND:
// Log.w(TAG, "onReceive---------發現設備!");
// 得到藍牙設備
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//與本地存儲地址匹配
//local device
//更新設備信息
// BlueToothDeviceInfo info = new BlueToothDeviceInfo();
// assert device != null;
// info.setName(device.getName());
// info.setAddr(device.getAddress());
// listener.updateDevice(info);

// assert device != null;
String info = device.getName() + "\n" + device.getAddress();

if(!bTdeviceList.contains(info)){
bTdeviceList.add(info);
bTdeviceAdapter.notifyDataSetChanged();
}

break;
}

}
}

//方法
public boolean enableBlueTooth(){
if(_bluetooth != null && !_bluetooth.isEnabled()) {
return _bluetooth.enable();
}
return true;
}

public boolean disableBlueTooth(){
if(_bluetooth != null){
return _bluetooth.disable();
}
return true;
}

//藍牙狀態監聽
public IntentFilter makeFilter() {
IntentFilter filter = new IntentFilter();
// 監視藍牙打開及關閉狀態
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
// 監視藍牙設備與APP連接的狀態
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
// 開始查找以及結束查找
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
// 發現設備
filter.addAction(BluetoothDevice.ACTION_FOUND);
return filter;
}

public void searchBlueTooth(){
//先關閉
stopSearchBlueTooth();
//重新查找
mBtAdapter.startDiscovery();
Log.w(TAG, "startDiscovery...");
}

public void stopSearchBlueTooth(){
if (mBtAdapter.isDiscovering()) {
mBtAdapter.cancelDiscovery();
}

//清空之前獲取的設備列表
if(bTdeviceList != null){
bTdeviceList.clear();
bTdeviceAdapter.notifyDataSetChanged();
}

Log.w(TAG, "stopDiscovery...");
}

public void closeDevice(){
try{
if(_socket != null && _socket.isConnected()){
_socket.close();
_socket = null;

btOs.close();
btOs = null;

btIs.close();
btIs = null;

}
}catch (IOException e){
//
}finally {
conState = false;
}
}

public void connectDevice(int id){
//獲取藍牙設備
String info = bTdeviceList.get(id);
String name = info.split("\n")[0].trim(); //名字
String addr = info.split("\n")[1].trim(); //地址
_device = _bluetooth.getRemoteDevice(addr);
//socket連接
Runnable runnable = new Runnable() {
@Override
public void run() {
try{
_socket = _device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
_socket.connect();

//獲取藍牙輸入輸出流
btIs = _socket.getInputStream();
btOs = _socket.getOutputStream();

conState = true;
listener.connSuccess(name);
}catch (IOException e){
Log.e(TAG, "連接失敗!");

conState = false;
listener.connFailed(name);
}
}
};
btThreadPool.execute(runnable);
}

public void unRegBtReceiver(){
//注銷
mContext.unregisterReceiver(bTreceiver);
}

//接口
public interface BlueToothListener{
void overDiscovery();
void connSuccess(String name);
void connFailed(String name);
void disConn();
void request();
}

public void setListener(BlueToothListener listener){
this.listener = listener;

//注冊
mContext.registerReceiver(bTreceiver, makeFilter());
}
public BlueToothListener getListener(){return listener;}

/**
* @發送數據 字符串
* @param message
*/
public void senData(String message){
try{

if(_socket != null && btOs != null){
btOs.write(message.getBytes("GBK"));
}
}catch (Exception e){
Log.e(TAG, e.toString());
}
}

/**
* @發送數據 字節數組
* @param message
*/
public void sendDataBytes(byte[] message)
{
try
{
if(_socket != null && btIs != null)
{
btOs.write(message);
}
}
catch (Exception e)
{
Log.e(TAG, e.toString());
}
}

//讀取串口請求
private boolean revData() throws IOException{
while (btIs.available() > 0){
int count = btIs.available();

//判斷包長度
if(count < BlueToothData.Cmd.req_len)
return false;

byte[] buffer = new byte[count];
int len = btIs.read(buffer);

return (len == BlueToothData.Cmd.req_len && Arrays.equals(buffer, BlueToothData.Cmd.request));

}

return false;
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM