如何完全关闭蓝牙配对请求对话框?

Posted

技术标签:

【中文标题】如何完全关闭蓝牙配对请求对话框?【英文标题】:How to dismiss bluetooth pairing request dialog completely? 【发布时间】:2016-06-15 12:24:46 【问题描述】:

我的应用应与 BLE 配对,而不显示任何配对请求对话框。我在代码中设置引脚。但实际上对话框显示了几秒钟然后消失了。正在配对,但我不希望显示此对话框。有没有办法做到这一点?

【问题讨论】:

不知道您是否找到了解决方案? 我现在已经离开了这个项目。不幸的是,我无法解决这个问题。 【参考方案1】:

从 SDK 版本 19 开始,这更加困难。我找到了一种使用 BroadcastReceiver 的子类绕过它的方法。

public class BluetoothPairingRequest extends BroadcastReceiver

    @Override
    public void onReceive(Context context, Intent intent) 
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) 
            // convert broadcast intent into activity intent (same action string)
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
            Intent pairingIntent = new Intent();
            pairingIntent.setClass(context, MainActivity.class);
            pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
            pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, type);
            pairingIntent.setAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
            pairingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            if (device != null) 
                try 
                    device.setPin("1111".getBytes("UTF-8"));
                 catch (UnsupportedEncodingException e) 
                    e.printStackTrace();
                
            

            context.startActivity(pairingIntent);
        
    

然后你需要像这样注册一个债券接收者。

/**
 * Lock used in synchronization purposes
 */
private final Object lock = new Object();
private String deviceAddress;

...    

@Override
public void onCreate() 
    super.onCreate();

    ...

    final IntentFilter bondFilter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
    registerReceiver(bondStateBroadcastReceiver, bondFilter);


@Override
public void onDestroy() 
    super.onDestroy();

    ...

    unregisterReceiver(bondStateBroadcastReceiver);

在此之后,您可以在要初始化绑定过程时添加此代码。

...

BluetoothDevice newDevice = bluetoothAdapter.getRemoteDevice(device.getAddress());
deviceAddress = newDevice.getAddress();
createBond(newDevice);
...

createBond is here的实现:

private final BroadcastReceiver bondStateBroadcastReceiver = new BroadcastReceiver() 
    @Override
    public void onReceive(final Context context, final Intent intent) 
        // Obtain the device and check it this is the one that we are connected to
        final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (!device.getAddress().equals(mDeviceAddress))
            return;

        // Read bond state
        final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
        if (bondState == BluetoothDevice.BOND_BONDING)
            return;

        requestCompleted = true;

        // Notify waiting thread
        synchronized (lock) 
            lock.notifyAll();
        
    
;

private boolean createBond(final BluetoothDevice device) 
    if (device.getBondState() == BluetoothDevice.BOND_BONDED)
        return true;

    boolean result;
    requestCompleted = false;

    sendLogBroadcast(LOG_LEVEL_VERBOSE, "Starting pairing...");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
        result = device.createBond();
     else 
        result = createBondApi18(device);
    

    // We have to wait until device is bounded
    try 
        synchronized (lock) 
            while (!requestCompleted) lock.wait();
        
     catch (final InterruptedException e) 
        Log.e(TAG, "Sleeping interrupted", e);
    

    return result;


private boolean createBondApi18(final BluetoothDevice device) 
    /*
     * There is a createBond() method in BluetoothDevice class but for now it's hidden. We will call it using reflections. It has been revealed in KitKat (Api19)
     */
    try 
        final Method createBond = device.getClass().getMethod("createBond");
        if (createBond != null) 
            return (Boolean) createBond.invoke(device);
        
     catch (final Exception e) 
        Log.w(TAG, "An exception occurred while creating bond", e);
        Log.e(TAG, e.toString());
    

    return false;

最后不要忘记在清单中添加以下几行:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

并注册接收者:

<receiver android:name=".bluetooth.BluetoothPairingRequest">
    <intent-filter>
        <action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
        <action android:name="android.bluetooth.device.action.PAIRING_CANCEL" />
    </intent-filter>
</receiver>

【讨论】:

以上是关于如何完全关闭蓝牙配对请求对话框?的主要内容,如果未能解决你的问题,请参考以下文章

手机蓝牙与手机蓝牙连接时不弹出配对码对话框

三星翻盖手机如何关闭蓝牙

蓝牙耳机换手机怎么设置

android蓝牙配对 如何自动配对设置PIN码

苹果MacBook Pro的蓝牙怎么打开

对蓝牙配对对话框输入的反应