[英]Bluetooth pairing request on notification bar?
嘿大家!
不久前开始在 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;
}
这是源代码中的一个片段,正如您所看到的,有多种方法可以显示对话框:
BluetoothPairingRequest 是任何蓝牙配对请求的接收器。 它会检查蓝牙设置当前是否可见并显示 PIN、密码或确认输入对话框。 否则,它会在状态栏中放置一个通知,可以单击该通知以显示配对条目对话框。
所以是的,根据 BT 的可见性,将显示对话框/通知。
ninja edit:
这可能会因所使用的硬件而异。
我知道这个帖子很旧,但我想为有同样问题的人添加一个简单的答案。 上面的答案很好地解释了原因和内容,但没有显示简单的解决方案。
在启动绑定之前调用此函数可以完成以下工作:
private void feintBluetoothDeviceDiscovery() {
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
btAdapter.startDiscovery();
btAdapter.cancelDiscovery();
}
它只是触发了一个发现。 看起来有点愚蠢,但似乎工作得很好。
是的,线程很旧,但它比@maze 的解决方案略多。
编辑:我接受了这个补充。 我发现在我的 BTLE-only 应用程序中,我没有在为其分配的时间段内调用 startDiscovery,这就是 @maze 解决方案不起作用的原因。 我认为添加工作的唯一原因是我之前尝试过我的经典和 BTLE 应用程序并且时间还没有过去。
如果我想要弹出一个对话框而不是配对事件的通知,我必须在配对请求的一分钟内调用 startDiscovery()。 但这也需要多走一步。 我必须在 BroadcastReceiver 中有一个事件处理程序。
我偶然发现了这一点,因为我编写了一个使用连续后台搜索过程的 PHG,该过程在 startDiscovery() 之间循环 X 秒,然后 Btle 扫描 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”处理程序。 我想我可以一个一个地删除其他人,看看我是否仍然能看到对话,但我被一连串的懒惰击中了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.