package com.hy.ble.receive.helper;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
import com.hy.ble.receive.base.Common;
import com.hy.ble.receive.bean.BluetoothDeviceBean;
import com.hy.ble.receive.utils.BleUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* <pre>
* author : Agg
* blog : https://blog.csdn.net/Agg_bin
* time : 2019/03/14
* desc :
*
* 1、是否有权限
* 2、是否支持蓝牙4.0
* 3、蓝牙是否开启
* 4、设备搜索
* 5、设备连接
* 6、蓝牙通信
*
* reference :
* 一个系列四篇文章:https://www.jianshu.com/p/dc67e6fe036b
* 一系列几篇文章:http://a1anwang.com/post-47.html
* </pre>
*/
public class BluetoothHelper {
private static final String TAG = BluetoothHelper.class.getSimpleName();
@SuppressLint("StaticFieldLeak")
private volatile static BluetoothHelper bluetoothHelper;
private BluetoothAdapter bluetoothAdapter;
private BluetoothLeScanner bluetoothLeScanner;
private BluetoothGatt bluetoothGatt; // 作为中央来使用和处理数据
private Common.OnDeviceCallBack onDeviceCallBack;
private BluetoothGattCharacteristic characteristicNotification;
private Common.OnConnectDeviceCallBack onConnectDeviceCallBack;
private Common.OnCloseActivity onCloseActivity;
private Handler mainHandler;
private Context context;
private BluetoothHelper() {
}
public static BluetoothHelper getInstance() {
if (bluetoothHelper == null) {
synchronized (BluetoothHelper.class) {
if (bluetoothHelper == null) {
bluetoothHelper = new BluetoothHelper();
}
}
}
return bluetoothHelper;
}
public void init(Context context) {
this.context = context.getApplicationContext();
mainHandler = new Handler();
if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
mainHandler.post(() -> Toast.makeText(context, "蓝牙不支持BLE", Toast.LENGTH_SHORT).show());
onCloseActivity.onClose();
} else if (BluetoothAdapter.getDefaultAdapter() == null) {
mainHandler.post(() -> Toast.makeText(context, "此设备不支持蓝牙", Toast.LENGTH_SHORT).show());
onCloseActivity.onClose();
}
}
public void openBluetooth() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
boolean enable = bluetoothAdapter.enable();// 自动打开蓝牙
if (!enable) {
mainHandler.post(() -> Toast.makeText(context, "请打开蓝牙", Toast.LENGTH_SHORT).show());
onCloseActivity.onClose();
}
}
/**
* 检测蓝牙是否已启用
*
* @return 启用为true,未启用为false
*/
public boolean isEnabled() {
return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
}
public void scanLeDevice() {
// 参考:http://a1anwang.com/post-37.html
if (bluetoothAdapter != null) {
// 在10秒后停止搜索
mainHandler.postDelayed(() -> {
if (bluetoothAdapter.isEnabled()) bluetoothLeScanner.stopScan(scanCallback);
}, Common.SCAN_PERIOD);
// 在广播字段里加入特定的server uuid, app扫描的时候可以过滤其他BLE设备。
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
bluetoothLeScanner.startScan(createScanFilter(), new ScanSettings.Builder().build(), scanCallback);
} else {
Log.i(TAG, "scanLeDevice: 蓝牙未初始化");
}
}
private List<ScanFilter> createScanFilter() {
List<ScanFilter> scanFilters = new ArrayList<>();
scanFilters.add(new ScanFilter.Builder().setServiceUuid(Common.PARCEL_UUID_1).build());
scanFilters.add(new ScanFilter.Builder().setServiceUuid(Common.PARCEL_UUID_2).build());
return scanFilters;
}
public void stopScanLeDevice() {
if (bluetoothLeScanner != null) {
bluetoothLeScanner.stopScan(scanCallback);
} else {
Log.i(TAG, "scanLeDevice: 蓝牙未初始化");
}
}
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
// rssi:RSSI的值作为对远程蓝牙设备信号值,正常为负值; 值越大信号越强;
// scanRecord:远程设备提供的配对号,一般用不到。
Log.i(TAG, "scanRecord: " + BleUtil.toHexString(Objects.requireNonNull(result.getScanRecord()).getBytes())
+ ",address:" + result.getDevice().getAddress());
onDeviceCallBack.onItemClick(new BluetoothDeviceBean(result.getDevice(), result.getRssi()));
}
};
public void connectGatt(BluetoothDeviceBean deviceBean) {
// 实测发现,用false连接比较好,比较快, true会等个十几秒甚至几分钟才会连接上。 开发过程中一般都是用false,扫描到bluetoothdevice之后,直接用false连接即可。
bluetoothGatt = deviceBean.getBluetoothDevice().connectGatt(context, false, bluetoothGattCallback);
}
// BluetoothGattCallback是返回中央的状态和周边提供的数据的一个重要的抽象类
private final BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
/**
* 当GATT客户端已连接到GATT服务器或者从GATT服务器断开连接
* 时回调。
*
* @param gatt gatt
* @param status 连接或断开操作的状态。BluetoothGatt.GATT_SUCCESS表示操作成功
* @param newState 返回新的连接状态。 如 BluetoothProfile.STATE_DISCONNECTED或BluetoothProfile.STATE_CONNECTED
*/
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i(TAG, "连接成功");
onConnectDeviceCallBack.onConnect(gatt.getDevice());
// 查找服务,在成功连接到远程设备时调用,不调用此方法,无法与远程设备进行后续的通信。
// 但是这个方法是异步操作,在回调函数onServicesDiscovered中得到status,通过判断status是否等于BluetoothGatt.GATT_SUCCESS来判断查找Service是否成功.
gatt.discoverServices();
// 有可能自动重连
// bluetoothGatt = gatt;
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.i(TAG, "连接断开");
gatt.connect();
}
}
/**
* 当远程设备的远程服务列表,特征和描述符已被更新,即已发现新服务时,�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
蓝牙BLE4.0接收广播App,手机模拟BLE设备的话可以通过我的另一个下载——手机模拟BLE设备发送广播App. 这两个App可以完成2台Android手机,通过BLE4.0进行通信,可以发送和接收数据。 其中一台Android手机T模拟发出广播,作为BLE设备(周边设备),这个BLE设备在生产环境中就是我们用到的气体检测传感器、智能手环、体重秤、血压计等等; 另一台Android手机B,作为中央设备,搜索手机T发出的广播并连接; 手机B可以接收手机T的数据,也可以发送数据给手机T; 当然手机T也可以通过通知发送数据给手机B。
资源推荐
资源详情
资源评论
收起资源包目录
BLEReceive.zip (59个子文件)
BLEReceive
.gitignore 147B
gradle
wrapper
gradle-wrapper.jar 53KB
gradle-wrapper.properties 236B
local.properties 426B
build.gradle 620B
BLEDemo.iml 861B
BLEReceive.iml 864B
gradlew.bat 2KB
gradlew 5KB
app
.gitignore 8B
build.gradle 2KB
proguard-rules.pro 772B
app.iml 13KB
libs
src
test
java
hy
com
ble
demo
ExampleUnitTest.java 392B
main
AndroidManifest.xml 2KB
java
com
hy
ble
receive
bean
BleAdvertisedData.java 602B
BluetoothDeviceBean.java 883B
utils
BleUtil.java 4KB
RxUtils.java 3KB
view
activity
MainActivity.java 7KB
helper
BluetoothHelper.java 15KB
recyclerview
LeDeviceListAdapter.java 2KB
LeDeviceListHolder.java 1KB
base
Common.java 2KB
res
values
styles.xml 394B
colors.xml 316B
strings.xml 330B
mipmap-xxhdpi
ic_launcher_round.png 10KB
ic_launcher.png 6KB
layout
activity_main.xml 4KB
recycler_view_devices.xml 460B
drawable-v24
ic_launcher_foreground.xml 2KB
mipmap-anydpi-v26
ic_launcher.xml 276B
ic_launcher_round.xml 276B
mipmap-xhdpi
ic_launcher_round.png 7KB
ic_launcher.png 4KB
drawable-hdpi
activity_home_story_search_bg.png 2KB
activity_home_story_search_bg_browsinghistory.png 2KB
mipmap-hdpi
ic_launcher_round.png 5KB
ic_launcher.png 3KB
drawable
et_round_bg_search.xml 432B
ic_launcher_background.xml 6KB
select_device.xml 291B
drawable-mdpi
activity_home_story_search_bg.png 1KB
activity_home_story_search_bg_browsinghistory.png 1KB
drawable-xhdpi
activity_home_story_search_bg.png 2KB
activity_home_story_search_bg_browsinghistory.png 2KB
drawable-xxhdpi
activity_home_story_search_bg.png 3KB
activity_home_story_search_bg_browsinghistory.png 3KB
mipmap-mdpi
ic_launcher_round.png 3KB
ic_launcher.png 2KB
drawable-xxxhdpi
activity_home_story_search_bg.png 5KB
activity_options_off_res_manage.png 3KB
mipmap-xxxhdpi
ic_launcher_round.png 15KB
ic_launcher.png 9KB
expression_normal.png 29KB
androidTest
java
hy
com
ble
demo
ExampleInstrumentedTest.java 740B
gradle.properties 739B
settings.gradle 16B
共 59 条
- 1
Swuagg
- 粉丝: 871
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页