How to get the bluetooth a2dp connetcted event on xamarin? - android

I have a xamarin project (API 28, soon to be 29), and I need to catch the event of bluetooth a2dp device.
I have a broadcast receiver with the following intent filter:
IntentFilter bluetoothFilter = new IntentFilter();
bluetoothFilter.AddAction(BluetoothDevice.ActionAclConnected);
bluetoothFilter.AddAction(BluetoothDevice.ActionAclDisconnectRequested);
bluetoothFilter.AddAction(BluetoothDevice.ActionAclDisconnected);
var btReciever = new BluetoothReceiver();
this.RegisterReceiver(btReciever, bluetoothFilter);
In my manisfest, I got the following permission:
<uses-permission android:name="android.permission.BLUETOOTH" />
In the Receiver.OnReceive, I got this code:
public override void OnReceive(Context context, Intent intent) {
String action = intent.Action;
BluetoothDevice device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
There I have a switch:
switch (action)
{
case BluetoothDevice.ActionFound:
Android.Util.Log.Debug(TAG, "Device Found");
//Device found
break;
case BluetoothDevice.ActionAclConnected:
Android.Util.Log.Debug(TAG, "Device Connected");
BluetoothAdapter.DefaultAdapter.GetProfileProxy(context, btsListener, ProfileType.A2dp);
Thread.Sleep(1500);
var manager = context.GetSystemService(Context.AudioService) as AudioManager;
var devices = manager.GetDevices(GetDevicesTargets.Outputs);
Android.Util.Log.Debug(TAG, "devices=" + devices.Length);
foreach (var dev in devices)
{
Android.Util.Log.Debug(TAG, "dev: id={0} name={1} type={2}", dev.Id, dev.ProductName, dev.Type);
if (dev.ProductName == device.Name)
{
if (dev.Type.ToString().Contains("a2dp"))
{
BluetoothAdapter.DefaultAdapter.GetProfileProxy(context, btsListener, ProfileType.A2dp);
}
Android.Util.Log.Debug(TAG, "Found output device");
}
}
//Device is now connected
break;
...
}
And I got a listener that implements the IBluetoothProfileServiceListener interface, and looks like this:
var btsListener = new BTServiceListener();
class BTServiceListener : AppCompatActivity, IBluetoothProfileServiceListener
{
public void OnServiceConnected([GeneratedEnum] ProfileType profile, IBluetoothProfile proxy)
{
if (profile == ProfileType.A2dp)
{
Android.Util.Log.Debug(TAG, "A2dp");
}
}
...
}
I need to catch the event onConnect of the bluetooth a2dp (and later headset), but I have no idea how exactly I should do it.
This code in the receiver, shows the bluetooth onConnect event (BluetoothDevice.ActionAclConnected in the switch), then I check the device list, there is not yet the connected device, then I wait 1500ms (I need somehow to improve this method, this cannot stay like this), for the audioService to add the actual a2dp device to the list, and in the for loop, I find the additional device via its name, and I am certain it is the right one. BUT, I have no programmaticaly way to find out what type of device was connected (remote, headset, a2bp...) other than to check is the name contains a2dp (see for loop)
After my research, I found this line:
BluetoothAdapter.DefaultAdapter.GetProfileProxy(context, btsListener, ProfileType.A2dp);
This uses the context, the listener, and the desierd type of device (see Listener: BTServiceListener ), the problem is, I don't know if the proxy in the listener is the same device as the device in the broadcast receiver onConnect, and I have no idea how to use that function.
So my questions:
How and when should I use the BluetoothAdapter.DefaultAdapter.GetProfileProxy function and be certain that I have the same device in the listener and in the onConnect function?
How to get all the devices from the manager without putting the thread to sleep? Because, without the Thread.Sleep, the actual device is not in the list because the onConnect function is called earlyer then the addition of the device to the audioService.
Thread.Sleep(1500); // <-- this needs to go
var manager = context.GetSystemService(Context.AudioService) as AudioManager;
var devices = manager.GetDevices(GetDevicesTargets.Outputs);
How should I distinguish between the device types? Because, I have a feeling that my method of String.Contains(string) is not the way to go
Sorry for the long question, thank you for your help and time.
Let me know, if you need anything else.

Related

Under USB-hub the USB_DEVICE_DETACHED broadcast event fired not on all detaching devices

I write an app which uses three hardware USB-devices.
When I operate with any single device - both events (USB_DEVICE_ATTACHED/USB_DEVICE_DETACHED) fires normally. Not matter how I bind the Receiver - under the manual registration in the code or in the manifest. And not matter how this single device attached - under the HUB or directly to the device.
The problem is: when I connect three device all in one time (by connecting the filled HUB), USB_DEVICE_ATTACHED event fired for all three devices - I receive notification via onNewIntent callback (or standalone Receiver binded via manifest), and do the permission-approve trip.
But on physical removal all devices behind the HUB (by detaching the HUB itself) DETACH event fires not on all devices. It may fired on random single device, or random two devices. But never on all three devices.
As result, for the time UsbManager holds a lot of dead dev-handles of not physically connected devices. At the same time, when I look into /dev/usb/ folder in connecion/disconnection time, device-files appears and removes correctly. As next result, when app is restarted by the some reason, I can not recognize which device is dead and which device is physically present.
The device is ASUS P1801 tablet, OS 4.2.1
As I can see, it is the last firmware from asus (JOP40D.US_epad-10.6.1.22.5-20130715)
For caching purposes, handles of the wrapped-device I pin to the Application singleton (when device appears with the USB_DEVICE_ATTACHED event or app initialisation):
public class HWMountReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Application.getAppContext().isAppReady() && (Application.getAppContext() != null) && (Application.getAppContext().getUsbHWManager() != null)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
Application.getAppContext().getUsbHWManager().refreshDevice(device);
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(Application.getAppContext(), 0, new Intent(Application.MED_ONLINE_DEVICE_PERMISSION), 0);
((UsbManager) Application.getAppContext().getSystemService(Context.USB_SERVICE)).requestPermission(device, mPermissionIntent);
}
}
}
The singleton:
private static FirstDevice firstDevice;
private static SecondDevice secondDevice;
private static ThirdDevice thirdDevice;
public void refreshDevice(UsbDevice device) {
HWDevice dev = HWDevicesFactory.newInstance(device);
if (dev instanceof FirstDevice) {
firstDevice = (FirstDevice) dev;
} else if (dev instanceof SecondDevice) {
secondDevice = (SecondDevice) dev;
} else if (dev instanceof ThirdDevice) {
thirdDevice = (ThirdDevice) dev;
}
}
Factory do reInstantination of each device-wrapper:
public static HWDevice newInstance(final UsbDevice device) {
int vendorId = device.getVendorId();
int productId = device.getProductId();
if ((vendorId == FIRST_VENDOR_ID) && (productId == FIRST_PRODUCT_ID)) {
return new FirstDevice(device);
...
Device-Wrapper more specific, because each one is very different. But typicaly it contain cached handles on UsbInterface, UsbDeviceConnection, UsbEndpoints and finally UsbDevice itself.
The main thing - DETACH not fired on random device. Not matter how it was "wrapped" by mine
Is there a probably bug in the ASUS firmware,
-or-
I miss some necessary steps/checks with the device connection
-or-
?

Android Speech Recognizer with Bluetooth Microphone

I've been writing a chat app to work with bluetooth headsets/earphones.
So far I've been able to record audio files via the mic in a bluetooth headset and
I've been able to get Speech-to-text working with the Android device's built in microphone, using RecogniserIntent etc.
But I can't find a way of getting SpeechRecogniser to listen through the Bluetooth mic.Is it even possible to do so, and if so, how?
Current Device: Samsung Galax
Android Version: 4.4.2
Edit: I found some options hidden in my tablets settings for the Speech Recognizer, one of these is a tick box labeled "use bluetooth microphone" but it seems to have no effect.
Found the answer to my own question so I'm posting it for others to use:
In order to get speak recognition to work with a Bluetooth Mic you first need to get the device as a BluetoothHeadset Object and then call .startVoiceRecognition() on it, this will set the mode to Voice recognition.
Once finished you need to call .stopVoiceRecognition().
You get the BluetoothHeadset as such:
private void SetupBluetooth()
{
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = btAdapter.getBondedDevices();
BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy)
{
if (profile == BluetoothProfile.HEADSET)
{
btHeadset = (BluetoothHeadset) proxy;
}
}
public void onServiceDisconnected(int profile)
{
if (profile == BluetoothProfile.HEADSET) {
btHeadset = null;
}
}
};
btAdapter.getProfileProxy(SpeechActivity.this, mProfileListener, BluetoothProfile.HEADSET);
}
Then you get call startVoiceRecognition() and send off your voice recognition intent like so:
private void startVoice()
{
if(btAdapter.isEnabled())
{
for (BluetoothDevice tryDevice : pairedDevices)
{
//This loop tries to start VoiceRecognition mode on every paired device until it finds one that works(which will be the currently in use bluetooth headset)
if (btHeadset.startVoiceRecognition(tryDevice))
{
break;
}
}
}
recogIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recogIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
recog = SpeechRecognizer.createSpeechRecognizer(SpeechActivity.this);
recog.setRecognitionListener(new RecognitionListener()
{
.........
});
recog.startListening(recogIntent);
}

Android - Listening to NFC Adapter State Changed

I am trying to build an application which uses NFC. The goal is to display a DialogFragment containing a button link to go the settings and change it manually and when the feature is enabled, disable the DialogFragment.
Problem: If the user enables/disables NFC using the icon in the pull down notifications tray , then the onPause/onResume doesn't get called and misses the condition entirely.
I am sure there is a receiver that I can register to instead and respond appropriately in real time. Any ideas, thoughts or reference will be greatly appreciated!
The following code checks if the state is enabled/disabled. I am also responding to it appropriately in the onResume event.
NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter();
if(adapter != null && adapter.isEnabled()) {
detector = new NfcDetector(this);
detector.setListener(this);
onNfcFeatureFound();
}
else {
onNfcFeatureNotFound();
}
For others looking at this post, the code below will take the user directly into settings to enable/disable NFC:
startActivity(new Intent(android.provider.Settings.ACTION_NFC_SETTINGS));
Thought I should post the answer for other people looking for the same problem, since I wasn't able to find one easily.
Add the following code to your activities onCreate() method:
IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
this.registerReceiver(mReceiver, filter);
Inner private class declared within your activity (or anywhere else you like):
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
final int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
NfcAdapter.STATE_OFF);
switch (state) {
case NfcAdapter.STATE_OFF:
break;
case NfcAdapter.STATE_TURNING_OFF:
break;
case NfcAdapter.STATE_ON:
break;
case NfcAdapter.STATE_TURNING_ON:
break;
}
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
// Remove the broadcast listener
this.unregisterReceiver(mReceiver);
}
// The following check needs to also be added to the onResume
#Override
protected void onResume()
super.onResume();
// Check for available NFC Adapter
NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
if(adapter != null && adapter.isEnabled()) {
createNfcDetector();
//NFC is available on device, but disabled
}
else {
//NFC Is available and enabled
}
}
You can use ACTION_ADAPTER_STATE_CHANGED to receive a broadcast message when the state of the adapter changes, but that option is only available in API 18 and above. See this for the documentation.
For prior to 18, I don't know of a way to do this unfortunately.
Also, as an aside, the android.provider.Settings.ACTION_NFC_SETTINGS will work on API levels 16 and above. For prior versions, the NFC settings are under "wireless settings". Take a look at the ensureSensorIsOn method at the bottom of this blog post for a code sample that checks against the API level and redirects to the correct settings pane.

Android Bluetooth Low Energy Pairing

How to pair a Bluetooth Low Energy(BLE) device with Android to read encrypted data.
Using the information in the Android BLE page, I am able to discover the device, connect to it, discover services and read un-encrypted characteristics.
When I try to read an encrypted characteristic (one that will cause iOS to show a popup asking to pair and then complete the read) I am getting an error code 5, which corresponds to Insufficient Authentication.
I am not sure how to get the device paired or how to provide the authentication information for the read to complete.
I toyed with BluetoothGattCharacteristics by trying to add descriptors, but that did not work either.
Any help is appreciated!
When you get the GATT_INSUFFICIENT_AUTHENTICATION error, the system starts the bonding process for you. In the example below I'm trying to enable notifications and indications on glucose monitor. First I'm enabling the notifications on Glucose Measurement characteristic which can cause the error to appear.
#Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if (GM_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
mCallbacks.onGlucoseMeasurementNotificationEnabled();
if (mGlucoseMeasurementContextCharacteristic != null) {
enableGlucoseMeasurementContextNotification(gatt);
} else {
enableRecordAccessControlPointIndication(gatt);
}
}
if (GM_CONTEXT_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
mCallbacks.onGlucoseMeasurementContextNotificationEnabled();
enableRecordAccessControlPointIndication(gatt);
}
if (RACP_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
mCallbacks.onRecordAccessControlPointIndicationsEnabled();
}
} else if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
// this is where the tricky part comes
if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
mCallbacks.onBondingRequired();
// I'm starting the Broadcast Receiver that will listen for bonding process changes
final IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
mContext.registerReceiver(mBondingBroadcastReceiver, filter);
} else {
// this situation happens when you try to connect for the second time to already bonded device
// it should never happen, in my opinion
Logger.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug?");
// I don't know what to do here
// This error was found on Nexus 7 with KRT16S build of Andorid 4.4. It does not appear on Samsung S4 with Andorid 4.3.
}
} else {
mCallbacks.onError(ERROR_WRITE_DESCRIPTOR, status);
}
};
Where the mBondingBroadcastReceiver is:
private BroadcastReceiver mBondingBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, final Intent intent) {
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
Logger.d(TAG, "Bond state changed for: " + device.getAddress() + " new state: " + bondState + " previous: " + previousBondState);
// skip other devices
if (!device.getAddress().equals(mBluetoothGatt.getDevice().getAddress()))
return;
if (bondState == BluetoothDevice.BOND_BONDED) {
// Continue to do what you've started before
enableGlucoseMeasurementNotification(mBluetoothGatt);
mContext.unregisterReceiver(this);
mCallbacks.onBonded();
}
}
};
Remember to unregister the broadcast receiver when exiting the activity. It may have not been unregistered by the receicver itself.
You might need to check the Kernel smp.c file, which method of paring it invoke for paring. 1) passkey 2)Just work or etc . i guess if it will be able to invoke MIMT and passkey level of security , there will not be any authentication issue. Make sure all flags is set to invoke the SMP passkey methods. track by putting some print in smp.c file.
A solution which works in ICS : with btmgmt tool in android and hooking it in encryption APIs. with passkey or any other methods. it works. You might need to add the passkey APIs in btmgmt from latest bluez code.
i think new android 4.4 provide pairing method. same problem already i am facing so wait for update and hope over problem solved createBond() method .
http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#setPairingConfirmation%28boolean%29

How to programmatically pair a bluetooth device on Android

For my application I'm trying to programmatically pair a bluetooth device. I'm able to show the pairing dialog for the device I want to pair and I can enter a pincode. When I press "Pair" the dialog is removed and nothing happens.
I only need to support devices with Android 2.0 and newer.
Currently I am using the following code to start the pairing progress:
public void pairDevice(BluetoothDevice device) {
String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
Intent intent = new Intent(ACTION_PAIRING_REQUEST);
String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
intent.putExtra(EXTRA_DEVICE, device);
String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT";
int PAIRING_VARIANT_PIN = 0;
intent.putExtra(EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
Before starting a pairing request I stop scanning for new devices.
My application has the following bluetooth permissions:
android.permission.BLUETOOTH_ADMIN
android.permission.BLUETOOTH
I managed to auto request a pairing procedure with keyboard featured devices through an app working as a service checking the presence of a specific kind of device and a modified version of the Settings app.
I have to say that I was working on a custom device running Android 4.0.3 without external controls (no back/Home/confirm buttons): pairing a controller on boot complete without any interaction until PIN request was mandatory.
First I created a service starting an activity on boot (with android.intent.action.BOOT_COMPLETED and android.permission.RECEIVE_BOOT_COMPLETED) that checks periodically the presence of a 1344 class device (a keyboard, the only way to input data on request) on the onReceive callback:
public void onReceive(Context context, Intent intent)
...
BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
...
if(dev.getBluetoothClass().getDeviceClass() == 1344){...}
Once filtered I choose the first keyboard available and then I pass the BT address to the Settings app:
Intent btSettingsIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
btSettingsIntent.putExtra("btcontroller", dev.getAddress());
startActivityForResult(btSettingsIntent, 1);
The tricky part was looking for the best position to call the pairing process. Using only the
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
led me to a paring dialog that once closed left me with the device paired, but unusable.
Digging into the classes of com.Android.settings.Bluetooth I found my way through the
createDevicePreference(CachedBluetoothDevice cachedDevice)
in the DeviceListPreferenceFragment.
From there I did compare my previously selected BT address with those available coming up and once successfully matched I call
cachedDevice.startPairing();
I know, it's tricky and requires access to the Android source code, but in a custom environment it works.
I hope this could be helpful.
It's my answer:
in onCreate() write this:
registerReceiver(incomingPairRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST));
then create variable
private final BroadcastReceiver incomingPairRequestReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//pair from device: dev.getName()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
dev.setPairingConfirmation(true);
//successfull pairing
} else {
//impossible to automatically perform pairing,
//your Android version is below KITKAT
}
}
}
};
Unfortunately, I think the best that you are going to get is opening up Settings/Wireless & networks/Bluetooth Settings for the user like so:
Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
startActivityForResult(intent, REQUEST_PAIR_DEVICE);
Using reflection you can call the method createBond from the BluetoothDevice class.
See this post: How to unpair or delete paired bluetooth device programmatically on android?
There is also a solution for unpair.
Reflection is DODGY, different manufacturers can change these underlying methods as they wish! I have tested many different apps on our 10 devices here and these reflection method only works fully on roughly 75% of devices. If you want an app that works for everyone be very careful when using reflection - try some cloud testing to test your app on 100+ devices and check the failure rate.
In this case reflection is not needed at all since API 19 (KitKat 4.4)
BluetoothDevice has new method CreateBond.
private void pairDevice(BluetoothDevice device) {
device.createBond();
}
developer.android.com/reference/android/bluetooth/BluetoothDevice.html
May be you need to startActivityForResult instead of only startActivity?
Other option is to look into the BluetoothChat application sample and start an RFComm connection socket, as soon as you start the socket a pairing request will automatically appear without needing to send a separate intent for pairing. This way you won't need to handle pairing.
http://developer.android.com/resources/samples/BluetoothChat/index.html
I am using this class to do connection between my client smartphone and the server device:
private class ConnectThread extends Thread
{
private final BluetoothSocket mmSocket;
private final UUID WELL_KNOWN_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
public ConnectThread(BluetoothDevice device)
{
// Use a temporary object that is later assigned to mmSocket,because
// mmSocket is final
BluetoothSocket tmp = null;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try
{
tmp = device.createRfcommSocketToServiceRecord(WELL_KNOWN_UUID);
//This is the trick
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, 1);
} catch (Exception e)
{
e.printStackTrace();
}
mmSocket = tmp;
}
public void run()
{
DebugLog.i(TAG, "Trying to connect...");
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try
{
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
DebugLog.i(TAG, "Connection stablished");
} catch (IOException connectException)
{
// Unable to connect; close the socket and get out
DebugLog.e(TAG, "Fail to connect!", connectException);
try
{
mmSocket.close();
} catch (IOException closeException)
{
DebugLog.e(TAG, "Fail to close connection", closeException);
}
return;
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel()
{
try
{
mmSocket.close();
} catch (IOException e)
{
}
}
}
First, get the BluetoothDevice object that you want to connect (listing paired devices or discoverying devices). Then do:
ConnectThread ct = new ConnectThread(device);
ct.start();
Because connect() is a blocking call, this connection procedure should always be performed in a thread separate from the main activity thread. See Android Developers for more detailed info.
I've found that using different values for PAIRING_VARIANT_PIN result in different pairing UI behaviours.
See this page:
http://code.google.com/p/backport-android-bluetooth/source/browse/trunk/backport-android-bluetooth201/src/backport/android/bluetooth/BluetoothDevice.java?spec=svn67&r=67
I suspect the problem you're having is that both devices are Bluetooth 2.1, in which case a pairing request should result in a 6 digit passkey being displayed on both devices.
The best result I was able to achieve was using PAIRING_VARIANT_PIN = 0. When prompted by my application, I entered pin 1234 and a 6 digit passkey appeared on my target device. The pairing UI finished and that was that.
Either you need to find out how to initiate a Bluetooth 2.1 pairing request, using some other pairing variant or pairing variant pin. Or, you're not catching the result of the activity that's running properly.
Given the amount of time I've been trying to do this, I've decided that my end users will just have to pair using the android settings before using my application.
This is how I get it:
Bluetooth device = mBtAdapter.getRemoteDevice(address);
//address:11:23:FF:cc:22
Method m = device.getClass()
.getMethod("createBond", (Class[]) null);
m.invoke(device, (Object[]) null); // send pairing dialog request
After pairing//
connectDevice(address);
in addition to my comment, by the way, even if these ACTION types did exist, that's not how you use them. here's an example:
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(EXTRA_DEVICE, device);
int PAIRING_VARIANT_PIN = 272;
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
sendBroadcast(intent);

Categories

Resources