蓝牙分为经典蓝牙与低功耗蓝牙(BLE)两种,开源的项目BluetoothKit和FastBle只支持BLE 模式蓝牙,只能自己写一个demo,写个工具类,完整工具类在文末,需要注意的是使用了RxAndroid框架,根据自己的需求改动工具类
需要的权限
//允许程序连接到已配对的蓝牙设备。
<uses-permission android:name="android.permission.BLUETOOTH" />
//允许程序发现和配对蓝牙设备
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
//gps权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
//定位权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
经典蓝牙开发
一、单例模式
private static volatile BluetoothUtil instance;
private BluetoothUtil() {}
public static BluetoothUtil getInstance() {
if (instance == null) {
synchronized (BluetoothUtil.class) {
if (instance == null) {
instance = new BluetoothUtil();
}
}
}
return instance;
}
二、初始化
BluetoothUtil.getInstance().init(getApplication());
工具类
private BluetoothAdapter mBluetoothAdapter;
private Context context;
//是否支持蓝牙
private boolean isBluetooth = true;
public void init(Application application){
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null){
isBluetooth = false;
}
context = application;
application.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
三、开启蓝牙
BluetoothUtil.getInstance().startBluetooth(this);
工具类
/**
* 开启蓝牙
* @param activity
*/
public void startBluetooth(Activity activity){
if (!isBluetooth){
showToast("该设备不支持蓝牙!");
return;
}
//未打开蓝牙
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivity(enableBtIntent);
}else {
//检测gps是否打开(定位权限已经申请,如果没有申请需要检测)
if (!isOpen(activity)){
Intent intent = new Intent();
intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activity.startActivity(intent);
}
}
}
/**
* 判断GPS是否开启,GPS或者AGPS开启一个就认为是开启的
* @param context
* @return true 表示开启
*/
public boolean isOpen(Context context) {
LocationManager locationManager
= (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// 通过GPS卫星定位,定位级别可以精确到街(通过24颗卫星定位,在室外和空旷的地方定位准确、速度快)
boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// 通过WLAN或移动网络(3G/2G)确定的位置(也称作AGPS,辅助GPS定位。主要用于在室内或遮盖物(建筑群或茂密的深林等)密集的地方定位)
boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (gps || network) {
return true;
}
return false;
}
四、搜索蓝牙
BluetoothUtil.getInstance().searchBluetooth(TestActivity2.this);
开个线程获取广播中的蓝牙并实时显示
private Disposable disposable;
private BluetoothAdater bluetoothAdater;
private List<BluetoothDevice> devices;
private RecyclerView recyclerView;
//显示
recyclerView.setLayoutManager(new LinearLayoutManager(TestActivity2.this));
devices = BluetoothUtil.getInstance().getDevices();
bluetoothAdater = new BluetoothAdater(R.layout.ble_bluetooth2,devices);
recyclerView.setAdapter(bluetoothAdater);
//实时更新蓝牙列表
Observable.create(new ObservableOnSubscribe<BluetoothDevice>() {
@Override
public void subscribe(ObservableEmitter<BluetoothDevice> emitter) throws Exception {
BluetoothUtil.getInstance().setEmitter(emitter);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<BluetoothDevice>() {
@Override
public void onSubscribe(Disposable d) {
disposable = d;
}
@Override
public void onNext(BluetoothDevice bluetoothDevice) {
devices.add(bluetoothDevice);
bluetoothAdater.notifyDataSetChanged();
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
工具类
/**
* 搜索蓝牙
*/
public void searchBluetooth(Activity activity){
if (!isBluetooth){
showToast("该设备不支持蓝牙!");
return;
}
//未打开蓝牙
if (!mBluetoothAdapter.isEnabled()) {
startBluetooth(activity);
return;
}
//检测gps是否打开(定位权限已经申请,如果没有申请需要检测)
if (!isOpen(activity)){
Intent intent = new Intent();
intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activity.startActivity(intent);
}else {
Set<BluetoothDevice> pairedDevices = getBondedDevices();
if (pairedDevices != null) {
devices = new ArrayList<>(pairedDevices);
}
//搜索蓝牙,通过广播返回搜索结果
mBluetoothAdapter.startDiscovery();
}
}
4.1查询已配对的设备集
//查询已配对的设备集
private Set<BluetoothDevice> getBondedDevices(){
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() >0){
return pairedDevices;
}
return null;
}
4.2存储BluetoothDevice数据
private List<BluetoothDevice> devices;
public List<BluetoothDevice> getDevices(){
return devices;
}
4.3利用Rx返回广播中获取的BluetoothDevice
private ObservableEmitter<BluetoothDevice> emitter;
public void setEmitter(ObservableEmitter<BluetoothDevice> emitter){
this.emitter = emitter;
}
4.4广播
BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {//获取未配对设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
emitter.onNext(device);
}
}
};
5.1销毁广播
public void onDestroy(){
context.unregisterReceiver(mReceiver);
}
重写onDestroy销毁广播
@Override
protected void onDestroy() {
super.onDestroy();
BluetoothUtil.getInstance().onDestroy();
//取消订阅
disposable.dispose();
}