大家好!
在Android之前开始使用蓝牙编程。但现在我遇到了一些问题。我想知道为什么配对请求有时会出现在通知栏中,有时会跳过此对话框并直接显示对话框。
例如: 我从嵌入式设备发起配对请求,然后发出通知,例如:
有时我不必费心通知,我的对话框就像我预期的那样出现。
有没有办法捕获该通知并显示对话框,或者当我启动蓝牙配对时,这是我的代码中的错误?
编辑:
更新1:
检查了Reno给我的答案,这实际上取决于各种各样的事情。还有其他方法可以直接显示对话框。当配对请求到达时,调用以下方法。进行检查以查看对话框是应该显示在前台(true)还是显示为通知(false):
public boolean shouldShowDialogInForeground(String deviceAddress) {
// If Bluetooth Settings is visible
if (mForegroundActivity != null) return true;
long currentTimeMillis = System.currentTimeMillis();
SharedPreferences sharedPreferences = getSharedPreferences();
// If the device was in discoverABLE mode recently
long lastDiscoverableEndTime = sharedPreferences.getLong(
BluetoothDiscoverableEnabler.SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, 0);
if ((lastDiscoverableEndTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
> currentTimeMillis) {
return true;
}
// If the device was discoverING recently
if (mAdapter != null && mAdapter.isDiscovering()) {
return true;
} else if ((sharedPreferences.getLong(SHARED_PREFERENCES_KEY_DISCOVERING_TIMESTAMP, 0) +
GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND) > currentTimeMillis) {
return true;
}
// If the device was picked in the device picker recently
if (deviceAddress != null) {
String lastSelectedDevice = sharedPreferences.getString(
SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE, null);
if (deviceAddress.equals(lastSelectedDevice)) {
long lastDeviceSelectedTime = sharedPreferences.getLong(
SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME, 0);
if ((lastDeviceSelectedTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
> currentTimeMillis) {
return true;
}
}
}
return false;
}
这是源代码的一个片段,您可以看到有方法可以显示对话框:
答案 0 :(得分:9)
根据a comment I saw in the android source code
BluetoothPairingRequest是任何蓝牙配对的接收器 请求。它会检查蓝牙设置当前是否可见 显示PIN,密钥或确认输入对话框。 否则它会在状态栏中放置一个通知,即可 单击以显示配对输入对话框。
所以是的,根据BT的可见性,将显示对话框/通知。
ninja edit:
这可能因使用的硬件而异。
答案 1 :(得分:0)
我知道这个线程很旧,但是我想为遇到相同问题的人添加一个简单的答案。上面的答案很好地解释了原因和原因,但没有给出简单的解决方案。
在启动绑定之前调用此函数即可完成工作:
private void feintBluetoothDeviceDiscovery() {
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
btAdapter.startDiscovery();
btAdapter.cancelDiscovery();
}
它只是触发发现。看起来有些愚蠢,但似乎效果很好。
答案 2 :(得分:0)
是的,线程很旧,但是它比@maze的解决方案稍微多了。
编辑:我在后面加上了这个补充。我在仅BTLE的应用程序中发现,在分配给它的期间内,我没有调用startDiscovery,这就是为什么@maze解决方案不起作用的原因。我认为添加项起作用的唯一原因是我刚刚尝试了我的经典&BTLE应用程序,而且时间还没有过去。
如果我要弹出对话框而不是有关配对事件的通知,则必须在配对请求的一分钟内调用startDiscovery()。但是,它也需要采取进一步的措施。我必须在BroadcastReceiver中具有该事件的处理程序。
我偶然发现了这是因为我编写了一个使用连续背景搜索过程的PHG,该过程在startDiscovery()持续X秒,然后进行Btle Scan持续Y秒。它同时处理了经典设备和Btle设备。我知道我需要进行startDiscovery调用,但是由于经典发现是在BroadcastReceiver中处理的,因此我有相应的处理程序。
现在,我正在编写类似的PHG,仅 可以进行BTLE。我将startDiscovery()循环保留在后台扫描器中,因为我知道我至少需要这样做才能获取对话框。但是我删除了BroadcastReceiver中的处理程序。我仅有的处理程序用于配对事件。结果-没有对话框。所以我添加了以下内容,即使他们现在除了打印日志之外什么也不做:
//================ CONNECT ==============================
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(intent.getAction()))
{
Log.i(TAG, "BT State Receiver signaled with connected for device " + device.getName() + " with bond state " + device.getBondState());
}
//================ DISCONNECT ==============================
else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(intent.getAction()))
{
Log.i(TAG, "BT State Receiver signaled with disconnect for device " + device.getName() + " with bond state " + device.getBondState());
}
//================ START/STOP DISCOVERY ==============================
else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction()))
{
Log.i(TAG, "BT State Receiver signaled discovery started");
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction()))
{
Log.v(TAG, "BT State receiver, discovery stopped");
}
//================ FOUND DEVICE ==============================
else if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction()))
{
Log.v(TAG, "Device discovered: name " + device.getName() +
" Bond state " + device.getBondState());
}
不幸的是,我不知道我是否需要以上所有内容或仅需要'ACTION_FOUND'处理程序。我想我可以一个接一个地删除其他对话框,看看是否仍然可以看到对话框,但是我被一连串的懒惰所打击。