【发布时间】:2019-11-29 10:24:32
【问题描述】:
我为扫描 BLE 设备创建了简单的前台服务。它应该一直扫描设备。我创建了自己的 BLE 设备,每 0.5 秒传输一帧。我有两台调试设备,一台使用 Android 9,另一台使用 Android 6。
首先我注意到我没有得到所有的 BLE 帧。我应该每 10 秒得到大约 20 帧,但是:
- 搭载 Android 9 的设备大约有 6-7 帧,
- 搭载 Android 6 的设备获得大约 15-17 帧,但设备以特定间隔扫描(扫描 10 秒,然后停止 5-7 秒)。
其次,我注意到当设备屏幕关闭时,它的扫描效果更差(或完全停止扫描):
Android 9 设备在屏幕关闭 1 分钟后停止扫描 BLE 设备,
装有 Android 6 的设备在关闭屏幕后会获得大约 6 帧。
服务代码:
public class DeviceScan extends Service {
BluetoothLeScanner btScanner;
public static final String CHANNEL_ID = "ForegroundServiceChannel";
List<ScanFilter> filterList = new ArrayList<>();
{
filterList.add(new ScanFilter.Builder().setDeviceName("MYBEACON").build());
}
private ScanCallback leScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
Log.e("Adress: ",result.getDevice().getAddress());
Log.e("RSSI: ", " rssi: " + result.getRssi());
}
};
public void startScanning(){
btScanner = mBluetoothAdapter.getBluetoothLeScanner();
AsyncTask.execute(new Runnable() {
@Override
public void run() {
btScanner.startScan(filterList, new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setReportDelay(0) //when I use different value than 0, stop scanning
.build(),leScanCallback);
}
});
}
public void stopScanning() {
btScanner = mBluetoothAdapter.getBluetoothLeScanner();
AsyncTask.execute(new Runnable() {
@Override
public void run() {
btScanner.stopScan(leScanCallback);
}
});
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
createNotificationChannel();
Intent notificationIntent = new Intent(this, AlbumActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText("Scanning")
.setPriority(Notification.PRIORITY_MAX)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
startScanning();
return START_STICKY;
}
private void createNotificationChannel()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
【问题讨论】:
-
您使用的是哪些手机?这里有几个因素在起作用,但对于初学者来说,每个设备制造商(和手机)的 BLE 结果大相径庭(但它们正在慢慢收敛到相似的品质)。此外,您必须检查 LOW_LATENCY 扫描时间是多少,并尝试找出这些扫描时间与您的广告间隔重叠的概率。 iOS 的广告推荐是如何最大化发现概率的一个很好的例子forums.developer.apple.com/thread/9834
-
关于设备屏幕关闭,屏幕关闭时前台服务是否被杀死?
-
@SJoshi 设备:小米 mi 6 (Android 9)、三星 Galaxy Tab S SM-T700 (Android 6)。根据 android.developers 关于 LOW_LATENCY
"Scan using highest duty cycle. It's recommended to only use this mode when the application is running in the foreground."的说法,找不到具体的扫描时间,但三星几乎可以获取所有帧,所以这应该不是问题。我认为该服务没有被杀死,因为当我打开屏幕时,设备的行为就像屏幕关闭之前一样。
标签: java android service bluetooth-lowenergy foreground-service