2016-02-15 4 views
1

Я создаю приложение 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; 
    } 
} 

}

ответ

0

Итак, я нашел способ заставить его работать должным образом. Я не знаю, способ, которым я занимаюсь, - это лучшая практика, поскольку я новичок в Android и Java, но это то, что сработало для меня. Все, что я сделал, это вызвать метод stopScan в кнопке остановки после удаления обратных вызовов обработчика.

//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.removeCallbacksAndMessages(null); 
      mLEScanner.stopScan(mScanCallback); 
     } 
    }); 
0

Я полагаю, вы просто хотите, чтобы немедленно вызвать startScan на кнопку пуска пресса (не в Runnable, не планируется через Handler). Вызов асинхронный, поэтому ничего не будет блокировано, и Android выполнит все сканирование в другом потоке. Если вы хотите запланировать вызов, чтобы остановить его в будущем, то вы используете обработчик для отправки Runnable, который вызывает stopScan с необходимой задержкой.

Кнопка для остановки сканирования также может непосредственно вызвать stopScan(), если известно, что ранее выполнялось сканирование. Возможно, вы захотите использовать логическое значение для блокировки вызова stopScan, только если был предыдущий вызов startScan().

 Смежные вопросы

  • Нет связанных вопросов^_^