简体   繁体   English

如何完全消除蓝牙配对请求对话框?

[英]How to dismiss bluetooth pairing request dialog completely?

My app should pair with a BLE without showing any pairing request dialog. 我的应用程序应与BLE配对,而不显示任何配对请求对话框。 I am setting pin in the code. 我在代码中设置了pin。 But actually dialog is showing for a sec and then disappearing. 但是实际上对话框显示了几秒钟,然后消失了。 Pairing is happening, but i don't want this dialog to be shown. 正在进行配对,但我不希望显示此对话框。 Is there a method to do that? 有没有办法做到这一点?

Since the SDK version 19 this is more difficult. 从SDK版本19开始,这更加困难。 I found a way to bypass it using a subclass of BroadcastReceiver. 我找到了一种使用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);
        }
    }
}

Then you need register a bond receiver like this. 然后,您需要像这样注册一个债券接收者。

/**
 * 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);
}

After this you can add this code when you want to initialize the bonding process. 此后,您可以在想要初始化绑定过程时添加此代码。

...

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

The implementation of the createBond is here : createBond is here的实现在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;
}

Finally don't forget to add to your manifest these lines: 最后,不要忘记在清单中添加以下行:

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

And register the receiver: 并注册接收者:

<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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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