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

时间:2011-07-25 14:20:28

标签: android bluetooth request android-notification-bar

大家好!

在Android之前开始使用蓝牙编程。但现在我遇到了一些问题。我想知道为什么配对请求有时会出现在通知栏中,有时会跳过此对话框并直接显示对话框。

例如: 我从嵌入式设备发起配对请求,然后发出通知,例如:

In english: Pairing request for Bluetooth

有时我不必费心通知,我的对话框就像我预期的那样出现。

Pairing dialog shows up and there was no notification on the status bar

有没有办法捕获该通知并显示对话框,或者当我启动蓝牙配对时,这是我的代码中的错误?

编辑:

更新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. 如果可以看到蓝牙设置

3 个答案:

答案 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();
}

它只是触发发现。看起来有些愚蠢,但似乎效果很好。

另请参见:Android Bluetooth Pairing: How to make sure to get bluetooth pairing request in the front dialog instead of a notification?

答案 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'处理程序。我想我可以一个接一个地删除其他对话框,看看是否仍然可以看到对话框,但是我被一连串的懒惰所打击。