繁体   English   中英

通知栏上的蓝牙配对请求?

[英]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;
}

这是源代码中的一个片段,正如您所看到的,有多种方法可以显示对话框:

  1. 如果设备最近处于可发现模式
  2. 如果设备最近正在发现
  3. 如果最近在设备选择器中选择了设备
  4. 如果蓝牙设置可见

根据我在 android 源代码中看到的评论

BluetoothPairingRequest 是任何蓝牙配对请求的接收器。 它会检查蓝牙设置当前是否可见并显示 PIN、密码或确认输入对话框。 否则,它会在状态栏中放置一个通知,可以单击该通知以显示配对条目对话框。

所以是的,根据 BT 的可见性,将显示对话框/通知。

ninja edit: 

这可能会因所使用的硬件而异。

  • 如果设备最近处于可发现模式
  • 如果设备最近正在发现
  • 如果最近在设备选择器中选择了设备

我知道这个帖子很旧,但我想为有同样问题的人添加一个简单的答案。 上面的答案很好地解释了原因和内容,但没有显示简单的解决方案。

在启动绑定之前调用此函数可以完成以下工作:

private void feintBluetoothDeviceDiscovery() {
    BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
    btAdapter.startDiscovery();
    btAdapter.cancelDiscovery();
}

它只是触发了一个发现。 看起来有点愚蠢,但似乎工作得很好。

另请参见此处: Android 蓝牙配对:如何确保在前面的对话框中获得蓝牙配对请求而不是通知?

是的,线程很旧,但它比@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM