仅当我的应用程序处于活动状态并且也在后台且未被破坏时,我如何 运行 在后台进行 BLE 扫描?
How do I run a BLE scan in the background only if my application is alive and in the background as well and not destroyed?
我的应用程序在后台扫描 BLE 设备,以便在设备停止广播或 RSSI 低于设定限制时向用户发送通知。
但是,我注意到即使我的应用程序已关闭并且不再在后台运行,我的应用程序有时仍会扫描 BLE 设备。我怎样才能让这些后台 BLE 扫描仅在我的应用程序处于活动状态且在后台时才在后台进行?
我目前正在禁用 onDestroy 回调中的扫描,但我读到不推荐这样做,因为其中的代码并不总是被执行。这也是为什么我的应用程序有时仍然会在后台扫描的原因。
下面是 onDestroy 回调和我用来启动或停止扫描的代码。
@Override
public void onDestroy() {
super.onDestroy();
scanLeDevice(false); //stop scanning and stop notification from showing when app closed
try {
unregisterReceiver(mReceiverOn);
unregisterReceiver(mReceiverOff);
//Register or UnRegister your broadcast receiver here
} catch(IllegalArgumentException e) {
e.printStackTrace();
}
stopService();
Log.d("lifecycle", "onDestroy: isAppRunning in on destroy");
}
private void scanLeDevice(final boolean enable) { //need to update to non deprecated code
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && PackageManager.PERMISSION_GRANTED != getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION))
{
Toast.makeText(DeviceScanActivity.this, R.string.location_permission_needed, Toast.LENGTH_SHORT).show();
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 9); //get fine location, needed for android 10
}
else if (enable && !scanRunning) { //starting a scan that is currently not running
mHandler.postDelayed(new Runnable() {
@Override
public void run() { //Stops scanning after a pre-defined scan period. This is required if you are to scan indefinitely
mBluetoothAdapter.stopLeScan(mLeScanCallback );
scanRunning = false;
if(mScanning)
mHandler2.postDelayed(new Runnable() {
@Override
public void run() {
scanLeDevice(true);
}
}, 650);
invalidateOptionsMenu();
}
}, 8000);
mScanning = true;
scanRunning = true;
boolean onScanner = mBluetoothAdapter.startLeScan(uuid, mLeScanCallback);
Log.d(TAG, "scanLeDevice: onScanner " + onScanner + " isDiscovering " + mBluetoothAdapter.isDiscovering());
} else if (enable && appNotDestroyed){ //scanRunning is true
mScanning = true;
mBluetoothAdapter.startLeScan(uuid, mLeScanCallback);
Log.d(TAG, "scanLeDevice: mScanning " + mScanning + " isDiscovering " + mBluetoothAdapter.isDiscovering());
} else { //enable is false
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
if(!clearHandlerHasRunnable) {
clearHandlerHasRunnable = true;
clearHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (!mScanning)
clearUnsavedDevices(mLeDevices);
clearHandlerHasRunnable = false;
}
}, 3000);
}
}
invalidateOptionsMenu();
if(!mScanning){ //clear indicators for all cells so that user isn't confused by certain indicators being on/off
for (int i = 0; i < mLeDevices.size(); i++){
updateViewScanFor(i);
}
}
}
我不再在我的 onPause() 中启动后台扫描,然后在我的主程序中的 onDestroy() 中停止它 activity。
相反,我正在启动一个进行扫描的前台服务。这允许我的应用程序停止服务,因此当我的应用程序被销毁时停止扫描,因为后台没有发生任何事情。
我的应用程序在后台扫描 BLE 设备,以便在设备停止广播或 RSSI 低于设定限制时向用户发送通知。
但是,我注意到即使我的应用程序已关闭并且不再在后台运行,我的应用程序有时仍会扫描 BLE 设备。我怎样才能让这些后台 BLE 扫描仅在我的应用程序处于活动状态且在后台时才在后台进行?
我目前正在禁用 onDestroy 回调中的扫描,但我读到不推荐这样做,因为其中的代码并不总是被执行。这也是为什么我的应用程序有时仍然会在后台扫描的原因。
下面是 onDestroy 回调和我用来启动或停止扫描的代码。
@Override
public void onDestroy() {
super.onDestroy();
scanLeDevice(false); //stop scanning and stop notification from showing when app closed
try {
unregisterReceiver(mReceiverOn);
unregisterReceiver(mReceiverOff);
//Register or UnRegister your broadcast receiver here
} catch(IllegalArgumentException e) {
e.printStackTrace();
}
stopService();
Log.d("lifecycle", "onDestroy: isAppRunning in on destroy");
}
private void scanLeDevice(final boolean enable) { //need to update to non deprecated code
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && PackageManager.PERMISSION_GRANTED != getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION))
{
Toast.makeText(DeviceScanActivity.this, R.string.location_permission_needed, Toast.LENGTH_SHORT).show();
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 9); //get fine location, needed for android 10
}
else if (enable && !scanRunning) { //starting a scan that is currently not running
mHandler.postDelayed(new Runnable() {
@Override
public void run() { //Stops scanning after a pre-defined scan period. This is required if you are to scan indefinitely
mBluetoothAdapter.stopLeScan(mLeScanCallback );
scanRunning = false;
if(mScanning)
mHandler2.postDelayed(new Runnable() {
@Override
public void run() {
scanLeDevice(true);
}
}, 650);
invalidateOptionsMenu();
}
}, 8000);
mScanning = true;
scanRunning = true;
boolean onScanner = mBluetoothAdapter.startLeScan(uuid, mLeScanCallback);
Log.d(TAG, "scanLeDevice: onScanner " + onScanner + " isDiscovering " + mBluetoothAdapter.isDiscovering());
} else if (enable && appNotDestroyed){ //scanRunning is true
mScanning = true;
mBluetoothAdapter.startLeScan(uuid, mLeScanCallback);
Log.d(TAG, "scanLeDevice: mScanning " + mScanning + " isDiscovering " + mBluetoothAdapter.isDiscovering());
} else { //enable is false
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
if(!clearHandlerHasRunnable) {
clearHandlerHasRunnable = true;
clearHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (!mScanning)
clearUnsavedDevices(mLeDevices);
clearHandlerHasRunnable = false;
}
}, 3000);
}
}
invalidateOptionsMenu();
if(!mScanning){ //clear indicators for all cells so that user isn't confused by certain indicators being on/off
for (int i = 0; i < mLeDevices.size(); i++){
updateViewScanFor(i);
}
}
}
我不再在我的 onPause() 中启动后台扫描,然后在我的主程序中的 onDestroy() 中停止它 activity。
相反,我正在启动一个进行扫描的前台服务。这允许我的应用程序停止服务,因此当我的应用程序被销毁时停止扫描,因为后台没有发生任何事情。