Я создаю приложение BLE, которое необходимо постоянно запускать и останавливать сканирование для предопределенных интервалов. Образом я реализовал это с двумя runnables, которые называют друг друга следующим образом:Остановить текущий Runnable Android
private Runnable scan = new Runnable() {
@Override
public void run() {
scanHandler.postDelayed(stopScan, SCAN_PERIOD);
mLEScanner.startScan(filters, settings, mScanCallback);
Log.e("BLE_Scanner", "Start Scan");
}
};
private Runnable stopScan = new Runnable() {
@Override
public void run() {
mLEScanner.stopScan(mScanCallback);
scanHandler.postDelayed(scan, STOP_PERIOD);
Log.e("BLE_Scanner", "Stop Scan");
}
};
Я пытающегося начать непрерывное сканирование и пауза на кнопку мыши. Кнопка «Пуск» запускает процесс, но у меня возникают проблемы с остановкой сканирования.
//scan button functionality
scanButton=(Button)findViewById(R.id.scan_button);
scanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
spinner.setVisibility(View.VISIBLE);
scan.run();
}
});
//stop scan button functionality
stopButton=(Button)findViewById(R.id.stop_button);
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
spinner.setVisibility(View.INVISIBLE);
scanHandler.removeCallbacks(scan);
scanHandler.removeCallbacks(stopScan);
}
});
Если я нажму кнопку остановки в течение интервала остановки, сканирование остановится. Однако, если я нажимаю кнопку остановки во время запуска запуска сканирования, появляется возможность удалить обратные вызовы для запуска stopScan, оставив непрерывный запуск сканирования. Мне нужно, чтобы обе стопы остановились при нажатии кнопки. Чтобы предоставить более подробную информацию, весь мой код приведен ниже. Спасибо за помощь.
public class MainActivity extends Activity {
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 1;
private static final long SCAN_PERIOD = 5000;
private static final long STOP_PERIOD = 1000;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
private Button scanButton;
private Button stopButton;
//private String proximityUUID = "0000180f-0000-1000-8000-00805f9b34fb";
private ProgressBar spinner;
private Handler scanHandler;
private String[] filterList = {
"D9:ED:5F:FA:0E:02",
"FF:37:3A:25:56:C7",
"F4:57:89:69:93:91"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scanHandler = new Handler();
//determine if device supports BLE
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE Not Supported",
Toast.LENGTH_SHORT).show();
finish();
}
//set up bluetooth manager
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
//scan progress bar
spinner=(ProgressBar)findViewById(R.id.progressBar);
spinner.setVisibility(View.GONE);
//scan button functionality
scanButton=(Button)findViewById(R.id.scan_button);
scanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
spinner.setVisibility(View.VISIBLE);
scan.run();
}
});
//stop scan button functionality
stopButton=(Button)findViewById(R.id.stop_button);
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
spinner.setVisibility(View.INVISIBLE);
scanHandler.removeCallbacks(scan);
scanHandler.removeCallbacks(stopScan);
}
});
}
@Override
protected void onResume() {
super.onResume();
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
//scan settings
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
//scan filter
//populate the filter list
filters = new ArrayList<ScanFilter>();
for (int i=0; i< filterList.length ; i++) {
ScanFilter filter = new ScanFilter.Builder().setDeviceAddress(filterList[i]).build();
filters.add(filter);
}
}
}
@Override
protected void onPause() {
super.onPause();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
}
}
@Override
protected void onDestroy() {
if (mGatt == null) {
return;
}
mGatt.close();
mGatt = null;
super.onDestroy();
}
//start scan
private Runnable scan = new Runnable() {
@Override
public void run() {
scanHandler.postDelayed(stopScan, SCAN_PERIOD);
mLEScanner.startScan(filters, settings, mScanCallback);
Log.e("BLE_Scanner", "Start Scan");
}
};
private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
Log.i("callbackType", String.valueOf(callbackType));
Log.i("result", result.toString());
BluetoothDevice device = result.getDevice();
int mRSSI = result.getRssi();
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.i("ScanResult - Results", sr.toString());
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
//stop scan
private Runnable stopScan = new Runnable() {
@Override
public void run() {
mLEScanner.stopScan(mScanCallback);
scanHandler.postDelayed(scan, STOP_PERIOD);
Log.e("BLE_Scanner", "Stop Scan");
}
};
private static double calculateAccuracy(int txPower, double rssi) {
if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1.
}
double ratio = -rssi*1.0/txPower;
if (ratio < 1.0) {
return Math.pow(ratio,10);
}
else {
double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111;
return accuracy;
}
}
}