AndroidManifest.xml文件加入藍牙權限聲明,6.0??以上需要動態申請權限,這里不做說明
類:
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;
}
}