我在 iPad 上有一个应用程序可以发送蓝牙 LE 信息来代替其设备名称。我正在尝试在我的 Android 代码中捕获该信息并以某种方式更新 UI。基本上我需要不断扫描设备并根据我的协议(protocol)使用“设备名称”来更新我的 Android UI。我知道这不是正确的做事方式,我确实计划重构这两个应用程序以正确使用蓝牙 LE,但我需要尽快完成这项工作,但我现在没有时间。
在我下面的代码中,我知道由于我输入的一些日志,scanLeDevices 被调用,但是我在 onLeScan 中的打印语句永远不会被调用。谁能告诉我为什么?我已经坚持了很长时间......
public class MainActivity extends Activity {
private static final String TAG = "...";
List<String> listItems=new ArrayList<String>();
ArrayAdapter<String> adapter;
BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
TextView mainView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
setProgressBarIndeterminate(true);
mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
mainView = (TextView) findViewById(R.id.main_view);
scanLeDevice(true);
}
@Override
protected void onResume() {
super.onResume();
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
//Bluetooth is disabled
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBtIntent);
finish();
return;
}
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "No LE Support.", Toast.LENGTH_SHORT).show();
finish();
return;
}
scanLeDevice(true);
}
private static final long SCAN_TIME = 1000;
boolean mScanning = false;
private void scanLeDevice(final boolean enable) {
Log.i(null, "Inside scanLeDevice");
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
Log.i(null, "Calling stopLeScan");
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_TIME);
mScanning = true;
Log.i(null, "Calling startLeScan");
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.i(null, "INSIDE ONLESCAN");
//DO MY WORK
}
});
}
};
}
最佳答案
我不能确定哪里出了问题,但这里有一些想法:
- 测试 startLeScan() 的返回值。如果 startLeScan() 返回 false,扫描没有开始,可能是由于权限问题。参见 http://developer.android.com/guide/topics/connectivity/bluetooth-le.html#permissions
- 延长 SCAN_TIME。例如 SCAN_TIME = 10000。如果 SCAN_TIME 比您的 Beacon 的广播间隔短,您的程序可能检测不到它。
- 从 onCreate() 中删除对 scanLeDevice() 的调用。事实上,当这个程序启动时,onCreate() 调用 scanLeDevice(),然后几乎立即调用 onResume(),并再次调用 scanLeDevice()。我不知道如果在扫描已经运行时调用 startLeScan() 会发生什么,但我认为最好避免这样做。
- 重新启动您的 Android 设备。当我的 BLE 应用程序停止工作时,我发现这在 BLE 开发过程中很有用。
- 测试另一个 BLE 检测应用是否可以检测到您的 BLE 设备。
关于android - onLeScan 永远不会被称为 android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21515885/