Programmatically pairing with a BLE device on Android 4.4+
<p>Does anyone have a complete working example of how to programmatically pair with a BLE (<em>not</em> Bluetooth Classic) device that uses passkey entry (i.e. a 6-digit PIN) or Numeric Comparison on Android 4.4 or later? By 'programmatically' I mean I tell Android the PIN - the user isn't prompted.</p>

<p>There are many similar questions about this on SO but they are either a) about Bluetooth Classic, b) old (before <a href="https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#setPin(byte[])" rel="noreferrer"><code>setPin()</code></a> and <a href="https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createBond()" rel="noreferrer"><code>createBond()</code></a> were public), or c) unanswered.</p>

<p>My understanding is as follows.</p>

<ol>
<li>You connect to the device and discover its services.</li>
<li>You try to read a 'protected' characteristic.</li>
<li>The device returns an authentication error.</li>
<li>Android somehow initiates pairing and you tell it the PIN.</li>
<li>You can now read the characteristic.</li>
</ol>

<p>I have created a device using <a href="https://developer.mbed.org/" rel="noreferrer">mBed</a> running on the <a href="https://developer.mbed.org/platforms/Nordic-nRF51-DK/" rel="noreferrer">nRF51-DK</a> and given it a single characteristic.</p>

<p>I set up the security parameters like so:</p>

<pre><code>ble.securityManager().init(
    true, // Enable bonding (though I don't really need this)
    true, // Require MitM protection. I assume you don't get a PIN prompt without this, though I'm not 100% sure.
    SecurityManager::IO_CAPS_DISPLAY_ONLY, // This makes it us the Passkey Entry (PIN) pairing method.
    "123456"); // Static PIN
</code></pre>

<p>And then in the characteristic I used</p>

<pre><code>requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM);
</code></pre>

<p>Now when I try to read it with the <a href="https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp" rel="noreferrer">Nordic Master Control Panel</a>, I get a pairing request notification like this:</p>

<p><a href="https://i.stack.imgur.com/lHvrD.png" rel="noreferrer"><img src="https://i.stack.imgur.com/lHvrD.png" alt="pairing request"></a></p>

<p><a href="https://i.stack.imgur.com/A3V68.png" rel="noreferrer"><img src="https://i.stack.imgur.com/A3V68.png" alt="passkey entry"></a></p>

<p>And I can put this PIN in, and then MCP says I'm bonded, and can read the characteristic.</p>

<p>However, in my app I would like to avoid having the user enter the PIN, since I know it already. Does anyone have a complete recent example of how to do this?</p>

<p><em>Edit</em>: By the way <a href="https://stackoverflow.com/questions/31858774/programmatically-bonding-to-ble-device-on-android">this</a> is the most relevant question I found on SO, but the answer there doesn't seem to work.</p>