目录
一、第一种框架集成方式
1.在项目根目录的build.gradle文件中,添加如下配置:
2.在app module的build.gradle中,添加依赖:
3.使用前先在你应用的Application中调init方法初始化框架
4.然后必须调用enableBluetooth()方法开启蓝牙功能,你可以在activity中调用:
5.如果是低功耗蓝牙,需要设置配置项,经典蓝牙忽略跳过这一步即可:
6.开启蓝牙能力后,接着你就可以开始进行蓝牙设备扫描,其中,type 为蓝牙设备类型(经典蓝牙或低功耗蓝牙):
7.一旦扫描到设备,你就可以找到目标设备并连接:
8.设备连接成功后,你可以开始跟设备进行通信:
9.那么如何接收蓝牙设备返回给你的数据呢,很简单,在Receiver中接收:
10.最后,调用以下方法去主动断开连接并释放资源 :
第二种集成方式
1.由于是代码引入,故无需像第一步那样进行库的引入,直接在Application中初始化。
2.蓝牙界面
3.UUidStateBean对象
4.蓝牙信息对象BletoothInfoBen
5.进度对话框
6.ble_servies_select_dialog布局
7.gble_layout蓝牙布局
Android 蓝牙开发,很多项目会使用到,自己去摸索封装或者引用其他框架,也能解决部分问题。为何说是部分问题,Android蓝牙分为低功耗版与经典版,经典版是可以直接选择即可实现链接,低功耗版是需要配置uuid。故推荐一个框架,下面来分享使用教程。分两部分第一部分是直接使用框架,第二部分是修改框架源码,使用哪一种方式可以结合自己的需要。Android开发建议使用Android蓝牙调试工具app初步调试使用,这里推荐BLE调试助手app,各大应用市场都可以下载。BLE调试助手首页展示。
Java语言版本地址:https://github.com/g-HJY/HBluetooth
Kotlin语言版本地址:https://github.com/g-HJY/Kotlin-HBluetooth (暂停维护)
首先是集成方式,当然你可以直接在github上将整个项目下载下来,也可以将其以依赖的形式集成到你的项目中,具体步骤如下:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.g-HJY:HBluetooth:V1.3.6'
}
public class XiaoYaApp extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
HBluetooth.init(this);
}
}
//开启蓝牙功能
HBluetooth.getInstance().enableBluetooth()
分别是主服务UUID(withServiceUUID)、读写特征值UUID(withWriteCharacteristicUUID)、通知UUID(withNotifyCharacteristicUUID)以及是否设置最大传输单元(setMtu不设置不用调)等; 您还可以设置分包发送的时间间隔和包长度
//请填写你自己设备的UUID
//低功耗蓝牙才需要如下配置BleConfig,经典蓝牙不需要new HBluetooth.BleConfig()
HBluetooth.BleConfig bleConfig = new HBluetooth.BleConfig();
bleConfig.withServiceUUID("0000fe61-0000-1000-8000-00805f9b34fb")
.withWriteCharacteristicUUID("0000fe61-0000-1000-8000-00805f9b34fb")
.withNotifyCharacteristicUUID("0000fe61-0000-1000-8000-00805f9b34fb")
//命令长度大于20个字节时是否分包发送,默认false,分包时可以调两参方法设置包之间发送间隔
//.splitPacketToSendWhenCmdLenBeyond(false)
//useCharacteristicDescriptor 默认false
//.useCharacteristicDescriptor(false)
.setMtu(200, new BleMtuChangedCallback() {
@Override
public void onSetMTUFailure(int realMtuSize, BluetoothException bleException) {
Log.i(TAG, "bleException:" + bleException.getMessage() + " realMtuSize:" + realMtuSize);
}
@Override
public void onMtuChanged(int mtuSize) {
Log.i(TAG, "Mtu set success,mtuSize:" + mtuSize);
}
});
//低功耗蓝牙才需要调setBleConfig
HBluetooth.getInstance().setBleConfig(bleConfig);
HBluetooth.getInstance()
.scan(type, new ScanCallBack() {
@Override
public void onScanStart() {
Log.i(TAG, "开始扫描");
}
@Override
public void onScanning() {
Log.i(TAG, "扫描中");
}
@Override
public void onError(int errorType, String errorMsg) {
}
@Override
public void onScanFinished(List bluetoothDevices) {
Log.i(TAG, "扫描结束");
if (bluetoothDevices != null && bluetoothDevices.size() > 0) {
list.clear();
list.addAll(bluetoothDevices);
adapter.notifyDataSetChanged();
}
}
});
或者,如果你想在第一步操作后直接进行扫描,则可以这样调用:
HBluetooth.getInstance()
.enableBluetooth()
.scan(type, new ScanCallBack() {
@Override
public void onScanStart() {
Log.i(TAG, "开始扫描");
}
@Override
public void onScanning() {
Log.i(TAG, "扫描中");
}
@Override
public void onError(int errorType, String errorMsg) {
}
@Override
public void onScanFinished(List bluetoothDevices) {
Log.i(TAG, "扫描结束");
if (bluetoothDevices != null && bluetoothDevices.size() > 0) {
list.clear();
list.addAll(bluetoothDevices);
adapter.notifyDataSetChanged();
}
}
});
HBluetooth.getInstance()
.connect(device, new ConnectCallBack() {
@Override
public void onConnecting() {
Log.i(TAG, "连接中...");
}
@Override
public void onConnected(Sender sender) {
Log.i(TAG, "连接成功,isConnected:" + mHBluetooth.isConnected());
//调用发送器发送命令
byte[] demoCommand = new byte[]{0x01, 0x02};
sender.send(demoCommand, new SendCallBack() {
@Override
public void onSending(byte[] command) {
Log.i(TAG, "命令发送中...");
}
@Override
public void onSendFailure(BluetoothException bleException) {
Log.e("mylog", "发送命令失败->" + bleException.getMessage());
}
});
}
@Override
public void onDisConnecting() {
Log.i(TAG, "断开连接中...");
}
@Override
public void onDisConnected() {
Log.i(TAG, "已断开连接,isConnected:" + mHBluetooth.isConnected());
}
@Override
public void onError(int errorType, String errorMsg) {
Log.i(TAG, "错误类型:" + errorType + " 错误原因:" + errorMsg);
}
//低功耗蓝牙才需要BleNotifyCallBack
//经典蓝牙可以只调两参方法connect(BluetoothDevice device, ConnectCallBack connectCallBack)
}, new BleNotifyCallBack() {
@Override
public void onNotifySuccess() {
Log.i(TAG, "打开通知成功");
}
@Override
public void onNotifyFailure(BluetoothException bleException) {
Log.i(TAG, "打开通知失败:" + bleException.getMessage());
}
});
HBluetooth.getInstance()
.send(demoCommand, new SendCallBack() {
@Override
public void onSending(byte[] command) {
Log.i(TAG, "命令发送中...");
}
@Override
public void onSendFailure(BluetoothException bleException) {
Log.e("mylog", "发送命令失败->" + bleException.getMessage());
}
});
public void initListener() {
HBluetooth.getInstance().setReceiver(new ReceiveCallBack() {
@Override
public void onReceived(DataInputStream dataInputStream, byte[] result) {
// 打开通知后,设备发过来的数据将在这里出现
Log.e("mylog", "收到蓝牙设备返回数据->" + Tools.bytesToHexString(result));
}
});
}
HBluetooth.getInstance().release();
其他APi
1.带设备名称过滤条件的扫描:
public void scan(@BluetoothType int scanType, int timeUse, ScanFilter filter, ScanCallBack scanCallBack);
public void scan(@BluetoothType int scanType, ScanFilter filter, ScanCallBack scanCallBack);
2.设置连接超时:
HBluetooth.getInstance().setConnectTimeOut(5000);
3.BleConfig(BLE)设置分包发送时间间隔(默认20ms)及包长度(默认20个字节):
public BleConfig splitPacketToSendWhenCmdLenBeyond(boolean splitPacketToSendWhenCmdLenBeyond, int sendTimeInterval);
public BleConfig splitPacketToSendWhenCmdLenBeyond(boolean splitPacketToSendWhenCmdLenBeyond, int sendTimeInterval, int eachSplitPacketLen);
4.开启断开后自动重连机制,默认关闭重连:
HBluetooth.getInstance().openReconnect(3, 4000);
与第一种区别,第二种是修改第一种源码实现的蓝牙连接,主要是针对低功耗蓝牙适配,第一种是直接在初始化的时候配置uuid,实现要先通过测试工具拿到uuid或者由对方给出uuid,而本demo是通过弹出对话框的方式,由用户去选择,但是也是需要知道对方传递数据的uuid是多少,这就需要用到蓝牙调试助手BLE调试助手。下面是蓝牙调试助手演示界面选择包含读写、通知的uuid去尝试看能否拿到数据,拿到数据的就是低功耗蓝牙的可用uuid。
资源地址:
https://download.csdn.net/download/shi450561200/88621789
由于模块引入hawk作为已选择的蓝牙数据存储,故还需引入hawk框架。 //hawk数据存储 implementation "com.orhanobut:hawk:2.0.1"
public class XiaoYaApp extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
//蓝牙
HBluetooth.init(this);//初始化蓝牙
HBluetooth.getInstance()
.setConnectTimeOut(4000);
}
}
/**
* 经典
* 蓝牙
*/
public class GeNBleActivity extends AppCompatActivity implements HandlerUtils.OnReceiveMessageListener {
private RecyclerView recycleview;
private Switch switchBt;
private SwipeRefreshLayout swipeLayout;
private HandlerUtils.HandlerHolder myHandlerUtils;
private int clickState = 1999;//防止误碰蓝牙连接
private TextView blueTxt;//蓝牙数据显示
private LinearLayout finish;
private String tys = "";//
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gble_layout);
FullScreenrUtils.initBar(this);//全屏
StatusBarUtils.setLightStatusBar(this, true);//设置状态栏黑色字体
// new Thread(new Runnable() {
// @Override
// public void run() {
// registerCustomBroadcastReceiver();
// }
// }).start();
tys = getIntent().getExtras().get("typs").toString();
initView();
}
/**
* 刷新
* 数据
*/
private int refreshCount = 0;
private void refreshView() {
swipeLayout.setColorSchemeColors(ContextCompat.getColor(this, R.color.colorPrimary));
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
clickState = 0;
//开关试图打开
switchBt.setSwitchPadding(2);
switchBt.setChecked(true);
//开关试图打开
if (refreshCount > 0) {
//搜索蓝牙子线程中执行
new Thread(new Runnable() {
@Override
public void run() {
HBluetooth.getInstance().release();
// HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
initData();
}
}).start();
} else {
switchBt.setSwitchPadding(2);
switchBt.setChecked(true);
}
//1.5s后关掉下拉刷新
swipeLayout.postDelayed(new Runnable() {
@Override
public void run() {
swipeLayout.setRefreshing(false);
refreshCount = refreshCount + 1;
}
}, 2000);
}
});
}
/**
* 初始化
* 数据
*/
private static final int REQUEST_ENABLE_BT = 0xff000099;//启用蓝牙请求码
@SuppressLint("WrongConstant")
private void initData() {
int type = 2;
// 或者,如果你想在第一步操作后直接进行扫描,则可以这样调用:
HBluetooth.getInstance()
.enableBluetooth()
.scan(type, 3000, new ScanCallBack() {
@Override
public void onScanStart() {
// Log.i(TAG, "==开始扫描==");
}
@Override
public void onScanning(List scannedDevices, BluetoothDevice currentScannedDevice) {
// Log.i(TAG, "==扫描中==");
if (scannedDevices != null && scannedDevices.size() > 0) {
list.clear();
list.addAll(scannedDevices);
runOnUiThread(new Runnable() {
@Override
public void run() {
bluetoothDevicesAdapter.notifyDataSetChanged();
}
});
}
}
@Override
public void onError(int errorType, String errorMsg) {
// Log.d(TAG, "onError");
}
@Override
public void onScanFinished(List bluetoothDevices) {
// Log.d(TAG, "==onScanFinished===");
if (bluetoothDevices != null && bluetoothDevices.size() > 0) {
list.clear();
list.addAll(bluetoothDevices);
runOnUiThread(new Runnable() {
@Override
public void run() {
bluetoothDevicesAdapter.notifyDataSetChanged();
}
});
}
}
});
}
//蓝牙设备适配器
private MyDemoBluetoothDevicesAdapter bluetoothDevicesAdapter;
private List list = new ArrayList<>();
private static final String TAG = "TAG";
private String bleDevicesAdress = "";
private void initView() {
XiaoYaApp.setUuidTmp("");
// XiaoYaApp.setUuidTmp("0000ffe0-0000-1000-8000-00805f9b34fb");
finish = findViewById(R.id.finish);
recycleview = findViewById(R.id.recycleview);
switchBt = findViewById(R.id.switch_bt);
swipeLayout = findViewById(R.id.swipeLayout);
blueTxt = findViewById(R.id.blue_txt);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(GeNBleActivity.this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recycleview.setLayoutManager(linearLayoutManager);
recycleview.setHasFixedSize(true);
bluetoothDevicesAdapter = new MyDemoBluetoothDevicesAdapter(GeNBleActivity.this, list);
recycleview.setAdapter(bluetoothDevicesAdapter);
myHandlerUtils = new HandlerUtils.HandlerHolder(GeNBleActivity.this);
bluetoothDevicesAdapter.setMyOnItemClickListener(new MyDemoBluetoothDevicesAdapter.OnItemClickListener() {
@Override
public void OnItemClick(View view, int position) {
if (view.getId() == R.id.tv_cancle_conn) {
new Thread(new Runnable() {
@Override
public void run() {
HBluetooth.getInstance().release();
// HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
}
}).start();
} else {
if (clickState == 1999) {
return;
}
clickState = 1999;
myListPosition = position;
try {
//4、连接
// Log.e(getPackageName(), "===开始连接=Exception===");
// Log.e(TAG, "==扫描uuid==" + Arrays.toString(list.get(position).getUuids()));
//保存蓝牙Address数据,供直连使用。
bleDevicesAdress = list.get(position).getAddress();
new Thread(new Runnable() {
@Override
public void run() {
HBluetooth.getInstance().release();
// HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
initListener();
connectData(list.get(position));
}
}).start();
} catch (Exception e) {
}
}
}
@Override
public void OnItemLonClick(int position) {
}
});
//选择
switchBt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!getPermission()) {
return;
}
if (isChecked) {
//打开蓝牙
switchBt.setSwitchPadding(2);
//扫描蓝牙
new Thread(new Runnable() {
@Override
public void run() {
HBluetooth.getInstance().release();
// HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
initData();
}
}).start();
} else {
//关闭蓝牙
switchBt.setSwitchPadding(1);
//关闭蓝牙
new Thread(new Runnable() {
@Override
public void run() {
HBluetooth.getInstance().release();
// HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
}
}).start();
list.clear();
bluetoothDevicesAdapter.notifyDataSetChanged();
}
}
});
clickState = 0;
refreshView();
//一进入页面就取一次缓存
// MyEventManager.postMsg("=getcahegetcahe=", "getCache");
getCacheData();
finish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
//打开蓝牙搜索
switchBt.setSwitchPadding(2);
switchBt.setChecked(true);
}
/**
* 修改
* 蓝牙数据
*/
private int myListPosition = 0;
private void upBlutoothSata(boolean isConnnted) {
if (isConnnted) {
XiaoYaApp.getBlDevices().setType(999);
// Toast.makeText(GeNBleActivity.this, "蓝牙连接成功", Toast.LENGTH_SHORT).show();
} else {
XiaoYaApp.getBlDevices().setType(333);
// Toast.makeText(GeNBleActivity.this, "蓝牙已断开", Toast.LENGTH_SHORT).show();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
// bluetoothDevicesAdapter.notifyItemChanged(myListPosition, XiaoYaApp.getBlDevices());
bluetoothDevicesAdapter.notifyDataSetChanged();
// MyEventManager.postMsg("==更新页面状态==" + XiaoYaApp.getBlDevices().getType(), "formAndroid");
myHandlerUtils.sendEmptyMessageDelayed(UPDATE_DEVICESTYPE, 100);
// XiaoYaApp.getBlDevices().setType(2);
}
});
}
/**
* 连接
* 蓝牙
*/
private void connectData(BluetoothDevice device) {
runOnUiThread(new Runnable() {
@Override
public void run() {
showProgressDialog();
}
});
//保存蓝牙信息
Logger.d("===开始连接--====" + (device != null));
isConneted = false;//蓝牙能否重连,false表示不重连
// Log.d(TAG, "===connectData:开始 000===");
if (device != null) {
XiaoYaApp.setBlDevices(device);//保存全局的device
} else {
cancleDialogProgress();
return;
}
// Log.d(TAG, "===connectData:开始 1111===");
HBluetooth.getInstance()
.setConnectTimeOut(4000)
.connect(device, new ConnectCallBack() {
@Override
public void onConnecting() {
Logger.d("=====连接中=====");
}
@Override
public void onConnected(Sender sender) {
clickState = 0;
Logger.d("=====连接成功=====");
myHandlerUtils.sendEmptyMessageDelayed(TIPS_SELECT_UUID, 3000);
//调用发送器发送命令
byte[] demoCommand = new byte[]{0x01, 0x02};
sender.send(demoCommand, new SendCallBack() {
@Override
public void onSending(byte[] command) {
// Log.i(TAG, "==命令发送中..==");
}
@Override
public void onSendFailure(BluetoothException bleException) {
// Log.d(TAG, "==发送命令失败->===" + bleException.getMessage());
}
});
}
@Override
public void onDisConnecting() {
// Log.d(TAG, "===断开连接中...===");
}
@Override
public void onDisConnected() {
clickState = 0;
Logger.d("=====已断开连接=====");
myHandlerUtils.sendEmptyMessage(UPDATE_BLT_DISC_STATE);//修改蓝牙为断开状态
// Log.d(TAG, "===断开...===");
cancleDialogProgress();
}
@Override
public void onError(int errorType, String errorMsg) {
// Log.d(TAG, "==错误类型:" + errorType + " ===错误原因:" + errorMsg);
}
//低功耗蓝牙才需要BleNotifyCallBack
//经典蓝牙可以只调两参方法connect(BluetoothDevice device, ConnectCallBack connectCallBack)
}, new BleNotifyCallBack() {
@Override
public void onNotifySuccess() {
isConneted = true;
myHandlerUtils.sendEmptyMessageDelayed(UPDATE_BLT_CONNTED_STATE, 3000);//修改蓝牙显示连接状态
cancleDialogProgress();
// senDMsgDataDe();
Logger.d("===打开通知成功--====");
}
@Override
public void onNotifyFailure(BluetoothException bleException) {
cancleDialogProgress();
Logger.d("===打开通知失败--====");
}
});
}
/**
* 接收
* 数据
* 监听
*/
public void initListener() {
HBluetooth.getInstance().setReceiver(new ReceiveCallBack() {
@Override
public void onReceived(DataInputStream dataInputStream, byte[] result) {
Logger.d("===接收数据====" + Tools.bytesToHexString(result));
// 打开通知后,设备发过来的数据将在这里出现
}
});
HBluetooth.getInstance().openReconnect(200, 4000);
}
/**
* Create a
* BroadcastReceiver
* for ACTION_FOUND.
* 扫描发现设备
* 蓝牙配对并连接
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ENABLE_BT) {//打开蓝牙回调
if (resultCode == RESULT_OK) {
// Log.d("TAG", "====onActivityResult:成功======");
}
}
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
HBluetooth.getInstance().release();
// HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
}
/**
* 重连
* 监听
*/
private static final int UPDATE_BLT_CONNTED_STATE = 0x000666;
private static final int UPDATE_BLT_DISC_STATE = 0x0000777;
private static final int TIPS_SELECT_UUID = 0x000888;//提示选择服务id
private static final int UPDATE_DEVICESTYPE = 1000;
private static final int SELECT_CONN = 0X0001;
private boolean isConneted = false;
@Override
public void handlerMessage(Message msg) {
switch (msg.what) {
case UPDATE_BLT_CONNTED_STATE://修改蓝牙为连接待接收数据状态
isConneted = true;
new Thread(new Runnable() {
@Override
public void run() {
upBlutoothSata(true);
}
}).start();
break;
case UPDATE_BLT_DISC_STATE://修改蓝牙为断开状态
new Thread(new Runnable() {
@Override
public void run() {
upBlutoothSata(false);
}
}).start();
break;
case TIPS_SELECT_UUID:
// Log.d(TAG, "===延时2S显示配置服务UUID: ==" + isConneted);
showServicesUUid();//延时2S显示配置服务UUID
break;
case UPDATE_DEVICESTYPE://修 XiaoYaApp.getBlDevices().setType(2);
new Thread(new Runnable() {
@Override
public void run() {
XiaoYaApp.getBlDevices().setType(2);
}
}).start();
break;
case SELECT_CONN:
oneConnectBle();//选择服务连接
break;
default:
break;
}
}
/**
* 只连接
* 蓝牙一次
*/
private void oneConnectBle() {
BluetoothDevice bluetoothDevice = XiaoYaApp.getBlDevices();
new Thread(new Runnable() {
@Override
public void run() {
Logger.d("===连接蓝牙====");
// Log.d(TAG, "====handleMessage:==只连接蓝牙一次===");
if (bluetoothDevice != null) {
// HBluetooth.getInstance().release();
// HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
XiaoYaApp.getBlDevices().setType(2);
connectData(bluetoothDevice);
}
}
}).start();
}
/**
* 判断权限
* 是否通过,
* 如果通过
* 就初始化
*/
private boolean mHasPermission; // 是否通过权限
private boolean getPermission() {
mHasPermission = checkPermission();
if (!mHasPermission) {
// 未获取权限,申请权限
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GeNBleActivity.this, "未获取权限,申请权限", Toast.LENGTH_SHORT).show();
}
});
requestPermission();
} else if (mHasPermission) {
// 已经获取权限
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GeNBleActivity.this, "已经获取权限", Toast.LENGTH_SHORT).show();
}
});
}
return mHasPermission;
}
/**
* 显示UUID
*/
private void showServicesUUid() {
mServiceList = new ArrayList<>();
uUidStateBeanList = new ArrayList<>();
mServiceList.clear();
uUidStateBeanList.clear();
mServiceList = XiaoYaApp.getmServiceList();
Log.d(TAG, "==showServicesUUid: =mServiceList集合大小==" + (mServiceList == null));
for (int y = 0; y < mServiceList.size(); y++) {
UUidStateBean uu = new UUidStateBean();
uu.setUUid(mServiceList.get(y).getUuid() + "");
uu.setSelected(false);
uUidStateBeanList.add(uu);
}
// Log.d(TAG, "===showServicesUUid:取消对话框======");
cancleDialogProgress();
if (!isConneted && mServiceList != null) {
showDialog();
// Toast.makeText(GeNBleActivity.this, "数据", Toast.LENGTH_LONG).show();
} else {
BluetoothDevice blethDeviceInfo = XiaoYaApp.getBlDevices();
saveBleDevicesInfo(blethDeviceInfo.getName(), blethDeviceInfo.getAddress(), "");
}
}
/**
* 显示UUId
* 供用户
* 选择
*/
private RecyclerView dialogServList;
private BtUUIDSelectAdapter btUUIDSelectAdapter;
private List mServiceList;
private List uUidStateBeanList;
private int selectUUidPosition = 0;
private void showDialog() {
View view = getLayoutInflater().from(this).inflate(R.layout.ble_servies_select_dialog, null);
dialogServList = view.findViewById(R.id.dialogServList);
btUUIDSelectAdapter = new BtUUIDSelectAdapter(GeNBleActivity.this, uUidStateBeanList);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(GeNBleActivity.this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
dialogServList.setLayoutManager(linearLayoutManager);
dialogServList.setHasFixedSize(true);
dialogServList.setAdapter(btUUIDSelectAdapter);
final AlertDialog dialog = new AlertDialog.Builder(this).create();
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(false);
TextView tv_cancle = view.findViewById(R.id.common_dialog_cancel_tv);
tv_cancle.setText("取消");
TextView tv_sure = view.findViewById(R.id.common_dialog_confirm_tv);
tv_sure.setText("确定");
tv_sure.setTextColor(Color.parseColor("#ff333333"));
TextView tv_title = view.findViewById(R.id.common_dialog_title_tv);
tv_title.setText("请选择可用UUID");
//确定
tv_sure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
BluetoothDevice blethDevice = XiaoYaApp.getBlDevices();
new Thread(new Runnable() {
@Override
public void run() {
HBluetooth.getInstance().release();
// HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
String uuidServices = uUidStateBeanList.get(selectUUidPosition).getUUid() + "" + XiaoYaApp.getUuidTmp();
XiaoYaApp.setUuidTmp(uuidServices + "");
//取缓存
myHandlerUtils.sendEmptyMessageDelayed(SELECT_CONN, 200);
myHandlerUtils.sendEmptyMessageDelayed(UPDATE_BLT_CONNTED_STATE, 1000);
//保存蓝牙信息
saveBleDevicesInfo(blethDevice.getName(), blethDevice.getAddress(), uuidServices);
dialog.dismiss();
}
}).start();
}
});
//取消对话框
tv_cancle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
//设置位置窗体
Window window = dialog.getWindow();
window.setGravity(Gravity.CENTER);
// WindowManager.LayoutParams lp = window.getAttributes();
// lp.dimAmount =0.0f;
// lp.x = 0; //新位置X坐标
// lp.y = -400; //新位置Y坐标
// dialog.onWindowAttributesChanged(lp);
window.setContentView(view);
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);//弹框
dialog.getWindow().setLayout((this.getWindowManager().getDefaultDisplay().getWidth() / 5 * 3), LinearLayout.LayoutParams.WRAP_CONTENT);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
btUUIDSelectAdapter.notifyDataSetChanged();
btUUIDSelectAdapter.setMyOnItemClickListener(new BtUUIDSelectAdapter.OnItemClickListener() {
@Override
public void OnItemClick(View view, int position) {
selectUUidPosition = position;
for (int y = 0; y < uUidStateBeanList.size(); y++) {
uUidStateBeanList.get(y).setSelected(false);
}
UUidStateBean uUidStateBean = new UUidStateBean();
uUidStateBean.setSelected(true);
uUidStateBean.setUUid(uUidStateBeanList.get(position).getUUid() + "");
uUidStateBeanList.set(position, uUidStateBean);
btUUIDSelectAdapter.notifyDataSetChanged();
}
@Override
public void OnItemLonClick(int position) {
}
});
}
/**
* 发送
* 数据
*/
public void senDMsgDataDe() {
// MyEventManager.postMsg("==拉取数据请求==" + strHex, "formAndroid");
byte[] demoCommand = BlueToothUtils.hex2Byte("ff fe 0b 27 01 d0 00 17 04 03 0f 1e 00");
// byte[] demoCommand = BlueToothUtils.hex2Byte(strHex);
int s = 0;
while (true) {
s++;
if (s > 2) {
break;
}
try {
Thread.sleep(1500);
HBluetooth.getInstance()
.send(demoCommand, new SendCallBack() {
@Override
public void onSending(byte[] command) {
// Log.d(TAG, "命令发送中123...");
}
@Override
public void onSendFailure(BluetoothException bleException) {
// Log.d(TAG, "发送命令失败->" + bleException.getMessage());
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 申请
* 权限
*/
private void requestPermission() {
ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, PERMISSION_REQUEST_CODE);
}
/**
* @return 检查
* 是否
* 已经
* 授予权限
*/
private boolean checkPermission() {
for (String permission : NEEDED_PERMISSIONS) {
if (ActivityCompat.checkSelfPermission(this, permission)
!= PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
private static final int PERMISSION_REQUEST_CODE = 0;
// 两个权限需要动态申请
private static final String[] NEEDED_PERMISSIONS = new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
/**
* 监听从uni-app
* 传过来的蓝牙uuid
* 缓存数据
*/
private String cacheServicesId = "";
private List blueListInfo;//蓝牙设备信息
private void getCacheData() {
blueListInfo = new ArrayList<>();
String tp = tys;//页面跳转的时候传过来
String value = Hawk.get(tp);//取低功耗蓝牙数据
Gson gson = new Gson();
Type type = new TypeToken>() {
}.getType();
blueListInfo = gson.fromJson(value, type);
StringBuilder stb = new StringBuilder();
if (blueListInfo==null){
return;
}
// 拿到蓝牙yaservicesID
if (blueListInfo.size() > 0) {
for (int y = 0; y < blueListInfo.size(); y++) {
stb.append(blueListInfo.get(y).getServicesId() + " ");
}
}
XiaoYaApp.setUuidTmp(stb + ",");
Logger.d("=====获取到缓存蓝牙数据======" + stb);
}
/**
* 保存
* 蓝牙设备
* 信息数据
*/
private void saveBleDevicesInfo(String name, String devicesAdress, String servicesId) {
long str = System.currentTimeMillis();
String tp = tys;//页面跳转的时候传过来
String names = "";
if (name != null) {
names = name;
}
String times = MyDateUtils.getSimpleYMDDate(str);
BletoothInfoBen bluetoothDevice = new BletoothInfoBen();
bluetoothDevice.setName(names);
bluetoothDevice.setTypes(tp);
bluetoothDevice.setDeviceId(devicesAdress);
bluetoothDevice.setServicesId(servicesId);
bluetoothDevice.setBindTime(times);
if (blueListInfo==null){
return;
}
blueListInfo.add(bluetoothDevice);
String result = JSON.toJSONString(blueListInfo);
Hawk.put(tp, result);//保存低功耗蓝牙
}
/**
* 关闭对话框
*/
private void cancleDialogProgress() {
if (dialogProgress != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
dialogProgress.cancel();
}
});
}
}
/**
* 进度对话框
*/
private AlertDialog dialogProgress;
private void showProgressDialog() {
View view = getLayoutInflater().from(this).inflate(R.layout.ble_dialog_progress_layout, null);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(GeNBleActivity.this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// TextView progress_dialog_title = view.findViewById(R.id.progress_dialog_title);
// progress_dialog_title.setText("启动蓝牙连接");
dialogProgress = new AlertDialog.Builder(this).create();
dialogProgress.setCancelable(true);
dialogProgress.setCanceledOnTouchOutside(true);
dialogProgress.show();
dialogProgress.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
//设置位置窗体
Window window = dialogProgress.getWindow();
window.setGravity(Gravity.CENTER);
window.setContentView(view);
dialogProgress.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);//弹框
dialogProgress.getWindow().setLayout((this.getWindowManager().getDefaultDisplay().getWidth() / 5 * 3), LinearLayout.LayoutParams.WRAP_CONTENT);
dialogProgress.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
}
}
public class UUidStateBean {
private int state;
private String UUid;
private boolean selected;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getUUid() {
return UUid;
}
public void setUUid(String UUid) {
this.UUid = UUid;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
@Override
public String toString() {
return "UUidStateBean{" +
"state=" + state +
", UUid='" + UUid + '\'' +
", selected=" + selected +
'}';
}
}
/**
* 蓝牙
* 信息对象
*/
public class BletoothInfoBen implements Serializable {
private String name;//蓝牙名称
private String types;//蓝牙类型 体温计or 血糖仪等等
private String deviceId;//蓝牙设备id
private String servicesId;//蓝牙服务id
private String bindTime;//绑定时间
public BletoothInfoBen() {
}
public BletoothInfoBen(String name, String types, String deviceId, String servicesId, String bindTime) {
this.types = types;
this.name = name;
this.deviceId = deviceId;
this.servicesId = servicesId;
this.bindTime = bindTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTypes() {
return types;
}
public void setTypes(String types) {
this.types = types;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getServicesId() {
return servicesId;
}
public void setServicesId(String servicesId) {
this.servicesId = servicesId;
}
public String getBindTime() {
return bindTime;
}
public void setBindTime(String bindTime) {
this.bindTime = bindTime;
}
@Override
public String toString() {
return "BletoothInfoBen{" +
"name='" + name + '\'' +
", deviceId='" + deviceId + '\'' +
", servicesId='" + servicesId + '\'' +
", bindTime='" + bindTime + '\'' +
'}';
}
}