【发布时间】:2014-06-10 10:48:16
【问题描述】:
我正在制作一个应连续扫描低功耗蓝牙设备 RSSI 的 android 应用程序。我正在使用 Google API,我的 Android 版本是 4.3。我在智能手机上使用三星 Galaxy S3,我正在尝试扫描 tod Smart Beacon:https://www.todhq.com/。
问题是,我得到这样的系列值:
- 从信标中快速获取 8 个 RSSI 值,每个值的距离约为 0.4 秒。
- 然后有一个很大的停顿(5-6 秒),什么都没有发生。
- 然后我再次从信标中获得 7-8 个 RSSI 值...
- 又是大停顿...
等等。
我想要得到的是每个 RSSI 值之间的连续间隔。它们不必是精确的间隔,但至少是接近的。我尝试过不同的示例,但并不真正知道问题出在哪里。也许 tod 智能信标只在 5 秒之间做广告?我可以通过更新固件来改变广告的间隔。但是,它在非常短的时间间隔之间获得许多值是没有意义的,并且这些值是不同的(= 它们不是每个值的副本)。
我一直使用的代码在这里:
public class MainActivity extends ListActivity {
ArrayList<String> listItems=new ArrayList<String>();
ArrayAdapter<String> adapter;
private static final String TAG=MainActivity.class.getSimpleName();
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler = new Handler();
private int scanCount;
private static final int REQUEST_ENABLE_BT=123456;
// Stops scanning after 1000 seconds.
private static final long SCAN_PERIOD = 1000000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems);
setListAdapter(adapter);
checkBLE();
init();
boolean ret = enableBLE();
if(ret){
startScan(false);
}else{
Log.d(TAG,getCtx()+" onCreate Waiting for on onActivityResult");
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void init(){
// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
}
private void startScan(boolean success){
if(mBluetoothAdapter == null){
init();
}
if(success){
mScanning=true;
scanLeDevice(mScanning);
return;
}
if(enableBLE()){
mScanning=true;
scanLeDevice(mScanning);
}else{
Log.d(TAG,getCtx()+" startScan Waiting for on onActivityResult success:"+success);
}
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
Log.d(TAG,getCtx() + "run stopLeScan");
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
Log.d(TAG,getCtx()+" scanLeDevice startLeScan:"+enable);
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
Log.d(TAG,getCtx()+ " scanLeDevice stopLeScan:"+enable);
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
private static String getCtx(){
Date dt = new Date();
return dt+ " thread:"+Thread.currentThread().getName();
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
final byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
scanCount++;
String msg=getCtx()+
"\nLeScanCallback.onLeScan stopLeScan run " +scanCount+
"\nDevice:" +device+
"\nRssi:" + rssi+
"\nScanRecord:";
Log.d(TAG,msg);
addItems(msg);
}
});
}
};
private void addItems(String msg) {
synchronized(listItems){
listItems.add(msg);
adapter.notifyDataSetChanged();
}
}
public void startScan(View v) {
startScan(false);
}
public void stopScan(View v) {
mScanning=false;
scanLeDevice(mScanning);
}
public void clear(View v) {
Log.d(TAG,getCtx()+" called clear");
synchronized(listItems){
listItems.clear();
adapter.notifyDataSetChanged();
}
}
private void checkBLE(){
// Use this check to determine whether BLE is supported on the device. Then
// you can selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
}
private boolean enableBLE(){
boolean ret=true;
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Log.d(TAG,getCtx()+" enableBLE either mBluetoothAdapter == null or disabled:"+mBluetoothAdapter);
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
ret=false;
}
return ret;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG,getCtx()+" onActivityResult requestCode="+requestCode+
", resultCode="+resultCode+", Intent:"+data
);
if(requestCode == REQUEST_ENABLE_BT && resultCode == RESULT_OK){
startScan(true);
}
}
}
【问题讨论】: