赞
踩
蓝牙是一种低功耗、低成本、近距离的无线连接方案,已经经历了2.0、2.1、3.0、4.0、4.2、5.0、5.1、5.2等多个版本迭代。
安卓4.3版本引入了蓝牙支持,可以用于发现设备、查询服务和传输信息。
安卓支持的蓝牙通讯主要是两种:
安卓开发蓝牙程序一般过程:
<!-- 通用蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- 位置权限,安卓6.0以上发现过程需要位置权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
SDK23以上需要添加运行时权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION ,
Manifest.permission.CAMERA,}, 1);
}
private BluetoothAdapter mBluetoothAdapter;
final BluetoothManager bletoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdatper bluetoothManager.getAdapter();
if(mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()){
// 如果没有开启,转到用户蓝牙设备界面
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 6);
}
}
以下三种方式可以用来执行查找蓝牙设备的操作。
BluetoothAdapter的 startLeScan方法用来查找设备。查找过程是一个异步方法,查找完成,通过 实现 BluetoothAdapter.LeScanCallback回调查看查找结果 。
在onLeScan() 中不能做耗时操作,否则容易堵塞。
startLeScan的定义:
public boolean startLeScan(LeScanCallback callback) ;
public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) ;
可以通过UUID[] 来设置扫描特定类型的外设。
扫描的代码片段:
private Handler mHandler;
// 延迟执行的函数,用来限定扫描时间
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, 10*1000);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
bluetoothAdapter.getBluetoothLeScanner()用来获取一个扫描器,这个扫描器可以设置扫描蓝牙的模式、过滤器等参数。整体来说,与上一种方式区别不大。
List<ScanFilter> filters = new ArrayList<>();
ScanFilter filter = new ScanFilter.Builder().setDeviceName("要限定的蓝牙名称").build();
filters.add(filter);
ScanSettings scanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
scanner.startScan(filters, scanSettings, scanCallback);
Looper.prepare();
new Handler().postDelayed(() -> {
scanner.stopScan(scanCallback);
Looper.myLooper().quit();
}, 30 * 1000L);
Looper.loop();
这个方法要继承一个BroadcastReceiver的广播,重写其中的onReceive方法。
// 定义 广播接收 class SingBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action) ){ // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Add the name and address to an array adapter to show in a Toast String derp = device.getName() + " - " + device.getAddress(); Toast.makeText(context, derp, Toast.LENGTH_LONG).show(); } } } // 注册广播、创建SingBroadcastReceiver对象。 SingBroadcastReceiver mReceiver=new SingBroadcastReceiver (); mBluetoothAdapter.startDiscovery(); IntentFilter ifilter1= new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, ifilter1); // 扫描 mBluetoothAdapter.startDiscovery(); // 停止扫描 mBluetoothAdapter.cancelDiscovery();
使用这种方式注意广播要及时关闭。
上面每种扫描方式对应的回调函数有所不同。
BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
lv_bluetooth.setAdapter(mArrayAdapter);
Log.d(TAG, "onLeScan:563463 ");
}
};
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
Log.i(TAG, "蓝牙设备名称:" + device.getName() + ";address=" + device.getAddress());
super.onScanResult(callbackType, result);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。