BluetoothServerSocket hangs on accept - android

I've seen many other posts regarding this specific issue, all with results that did not help me or were relevant to my case.
Here is my problem, I'm trying to setup a bluetooth piconet, with one node as a server and 7 as clients, each given a number as a location representative starting from 0 ( the server) and going to 7 (the clients). Currently I'm trying to get this to work for just two devices, the server and one client. And I assume that they're already paired. In the following code uuid is
private UUID uuid=UUID.fromString("0000111f-0000-1000-8000-00805f9b34fb");
Here is my thread which accepts incoming connections, ad is just the bluetooth adapter
private class BTServerThread implements Runnable{
#Override
public void run() {
try {
if (ad != null) {
if (ad.isEnabled()) {
BluetoothServerSocket btss=ad.listenUsingInsecureRfcommWithServiceRecord("MyApp",uuid);
Location=0;
Integer loc=1;
Log.wtf("Server","Searching");
while(loc<=7){
Thread t=new Thread(new BTServerHandler(btss.accept(),loc));
t.start();
Log.wtf("BTS","Found");
loc++;
}
} else {
Log.e("error", "Bluetooth is disabled.");
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
And here is my client thread which attempts to connect
private class BTClientThread implements Runnable{
#Override
public void run() {
try {
if (ad != null) {
if (ad.isEnabled()) {
Set<BluetoothDevice> bondedDevices = ad.getBondedDevices();
if (bondedDevices.size() > 0) {
Iterator<BluetoothDevice> iter = bondedDevices.iterator();
BluetoothDevice device = iter.next();
Log.wtf("dev", device.getName());
BluetoothSocket clientsocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
clientsocket.connect();
Log.wtf("Connected",device.getName());
}
Log.e("error", "No appropriate paired devices.");
} else {
Log.e("error", "Bluetooth is disabled.");
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
Hold your breath, here comes the weird part, the call btss.accept() hangs forever (Doesn't even return once), while at the same time, the client device connects somehow. When I call
BluetoothSocket clientsocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
clientsocket.connect()
This pops the toast on the phone which is hanging on accept saying "DeviceName connected" then after a while it pops another toast saying "DeviceName disconnected" on its own, without me doing ANYTHING, and at the same time the serverphone is still hanging on accept.
Here are my questions, why is it hanging on accept when the toast popped saying connected? And how could it possibly connect when the other phone is still listening for a connection?
Thanks for the help.

As it turns out, using that specific UUID caused a problem from some reason I still don't understand? After trying many random things, I finally decided to try another random UUID and that magically caused it to work.
Here is my new UUID
private UUID uuid = UUID.fromString("56e8a14a-80b3-11e5-8bcf-feff819cdc9f");

Related

Will a Slave device need a different application than the Master?

All Bluetooth projects I have previously done, had an Android device acting as the Master, with a Bluetooth dongle or chip acting as a single Slave. The project I am working on will have an Android Tablet acting as the Master, then have several other Android Devices acting as the Slaves.
What is the best practice in this situation? Should I write two separate applications? One for the master, another for the slaves? Or would it be plausible to use one application for both rolls?
The best way to do this would be to just make one application and then just have different code logic based on if the device is a master or a slave.
Instead of doing just a simple SPP connection, you could create a sort of bluetooth "Server" and wait until x number of devices connect to the server and then do whatever it is you want to do in your app.
An example (From the developer guide: Here)
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket);
//in your case you wouldn't want to close the server socket since you want to
//connect more than one device. So keep listening until you get all the devices.
//you're also going to have to use different UUID's for each new device.
// mmServerSocket.close();
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
In this code the server is closed as soon as one connection is made, in your case you would just keep listening for more sockets until you get all the sockets. You're going to need multiple threads to handle all the connections and some synchronization for handling all the data from all the connections depending on what you intend on doing.

IOException on accept thread

One part of my application connects to a device through Bluetooth and normally works fine but occasionally it won't connect and I get the following error
03-11 10:29:20.328: E/BluetoothComService(8059): accept() failed
03-11 10:29:20.328: E/BluetoothComService(8059): java.io.IOException: Operation Canceled
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothSocket.acceptNative(Native Method)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothSocket.accept(BluetoothSocket.java:316)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothServerSocket.accept(BluetoothServerSocket.java:105)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothServerSocket.accept(BluetoothServerSocket.java:91)
03-11 10:29:20.328: E/BluetoothComService(8059): at com.mypackage.name.bluetooth.BluetoothService$AcceptThread.run(BluetoothService.java:298)
This is the line where I get the exception
socket = mmServerSocket.accept();
And this is the complete AcceptThread
private class AcceptThread extends Thread {
// The local server socket
private BluetoothServerSocket mmServerSocket;
public boolean successInit = false;
public AcceptThread() {
closeAllConnections();
/*
* if(mmServerSocket != null) { try { mmServerSocket.close(); } catch
* (IOException e) { e.printStackTrace(); } }
*/
BluetoothServerSocket tmp = null;
// Create a new listening server socket
while (!successInit) {
try {
tmp = mAdapter
.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
successInit = true;
} catch (Exception e) {
successInit = false;
}
}
/*
* try { tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME,
* MY_UUID); successInit= true; } catch (IOException e) { Log.e(TAG,
* "listen() failed", e); tmp = null; successInit = false; }
*/
mmServerSocket = tmp;
}
public void run() {
if (D)
Log.d(TAG, "BEGIN mAcceptThread" + this);
setName("AcceptThread");
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mAdapter.cancelDiscovery();
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "accept() failed", e);
Log.e("Error", "This isn't connecting");
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (BluetoothService.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice());
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new
// socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (D)
Log.i(TAG, "END mAcceptThread");
}
public void cancel() {
if (D)
Log.d(TAG, "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of server failed", e);
}
}
}
Here is the function I call at the beginning of AcceptThread in hopes to close everything to restart it
public void closeAllConnections() {
if (mmInStream != null) {
try {mmInStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmOutStream != null) {
try {mmOutStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmSocket != null) {
try {
mmSocket.close();
//mmSocket.connect();
}
catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
I've read through the Bluetooth Docs and SO questions but I haven't found anything that works for me and it gets a bit confusing for me as this is my first time connecting through BT.
Note
The only "fix" I have found when this happens is to turn off the BT adapter, force close the program, restart BT adapter and restart app, which is not good for obvious reasons. I tried restarting the adapter programmatically but I still can't connect.
Can anyone see what might be wrong in my BlutoothService class, which is where AcceptThread is located? Or how I would go about resolving this issue? Thanks!
Update
It does, in fact, seem like the connection is sometimes closed on one Thread and trying to reconnect on another. The problem is that I can't figure out what would cause it to try and connect on a separate Thread or how to fix it when this happens.
The only way I can successfully reproduce this is if my BT device is turned off then I turn the BT adapter off. When I turn everything back on then I get the exception and cannot connect. I have customers that it happens to randomly and periodically so I'm hoping the issues are related.
Well, part of my problem was a hardware issue that was found out to be a problem on the third-party manufacturers end. They're firmware wasn't quite right and when it was reading the BT address, it was occasionally being corrupted.
On the software side, it was running the AcceptThread in two separate Threads periodically. What I did to fix that was to create a function to close the socket and input/output streams...
public void closeAllConnections()
{
if (mmInStream != null)
{
try {mmInStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmOutStream != null)
{
try {mmOutStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmSocket != null)
{
try {
mmSocket.close();
Log.e("TAG", "close() of connect socket successfu;");
} catch (IOException e) {
Log.e("TAG", "close() of connect socket failed", e);}
}
Then in the BluetoothCom class, I noticed it wasn't always checking for the BT object to be null before trying to restart the service.
private void setupService() {
// Initialize the BluetoothChatService to perform bluetooth connections
if((mChatService != null) && (mChatService.getState() != 0)) {
mChatService.stop();
}
// I didn't have this so it would always start a new instance of the Service
if (mChatService == null)
mChatService = new BluetoothService(mHandler);
mChatService.start();
}
This seems to have helped and I no longer have those problems. However, now testing on the Samsung Galaxy Tab 4 and I am once again having connection issues but only on this device. Maybe this information can help someone and I will update my answer if I figure anything else out with the new problem.
Note: As stated above, this Bluetooth app uses modified code from Android's BluetoothChat app.
Also, I have read (and noticed) that different manufacturers implement the BT stack differently which can lead to headaches (at least if yo don't know enough about it).
Although this is old post but I recently contact same issue so I want to write down the way I solve it.
It seems your code is from Google samples BlutoothChat (as it looks same, sorry if I misunderstand). I also create my own application that base on this sample (on API level 10). I meet the accept() fail issues if I try to connect one device to other device but at the end I solve this question by simply remove some code in MainActivty
On the Google samples main activity it contain many methods when activity change (Start, Pause, etc).
Original code have this
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
if (mChatService != null) {
if (mChatService.getState() == ChatService.STATE_NONE) {
mChatService.start();
}
}
}
This code start the Chat Service and running the AcceptThread to listening incoming connections.
When application start, this method will be call "once" and create the AcceptThread. If you do any other things that make the main activity onPause() pause (In Google samples case, if you click menu to start device_list activity the main activity will pause), when the application back to main activity it will call create AcceptThread method "one more time", this cause the problem because one thread already running but you try to interrupt it. And at the end happen accept() fail error and throw java.io.IOException: Operation Canceled error.
So to avoid this is simply remove the codes in OnResume()
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
}
or if you don't want delete any codes because you afraid cause some problem, put this code (mChatService != null) mChatService.stop(); in...
#Override
public synchronized void onPause() {
super.onPause();
if (mChatService != null) mChatService.stop();
if(D) Log.e(TAG, "- ON PAUSE -");
}
Both works perfect in my project. Method 1 not create the new thread if activity resume, and Method 2 kill all the thread if you leave the current activity and disconnect all current connections if you already have one (it will start the thread again once you turn back). Method 1 wouldn't return any error but method 2 will throw accept fail again if you leave the current activity, so I suggest to use method 1.
Need to notice that this error usually happen after you modify Google samples BlutoothChat, it will never appear on the original app.
I have seen many post talk about this issue, but not see any one come out with this answer, so just want to share this. Hope this is helpful.
That exception should occur when the BluetoothServerSocket is closed or garbage collected. I suspect that the exception is happening on an OLD copy of the thread. So something like: When you create the new thread the old thread gets cancelled and thus the BluetoothServerSocket is closed and thus accept correctly fails with that error. Check this in the debugger and/or logging on which thread the various events occur; e.g. set breakpoints on the line after accept and perhaps on the cancel function, then inspect the thread IDs there -- is the exception occurring on a previous thread?

Service Discovery Failed on reconnect with bluetooth device

i am trying to connect a bluetooth device with my android app. so far its working fine.
Now the issue is when my device gets out of range , i am showing one dialog box and asking user to reconnect or not.
sometimes i am able to re-connect with the device and sometimes i do get error i.e.
Service Discovery Failed
and i really don't know why its happening
private class ConnectThread extends Thread {
public ConnectThread() {
try {
bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(UUID);
} catch (IOException e) {
System.out.println("IO EXCEPTION" + e.getMessage() +"");
}
}
public void run() {
bluetoothAdapter.cancelDiscovery();
try {
// I AM GETTING ERROR HERE
bluetoothSocket.connect();
} catch (IOException connectException) {
Log.d("Exception : ConnectThread -> Run" , connectException.getMessage()+"");
try {
bluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
}
}
From experience, and actually having the same issue today,
If I was to speculate, I would say your other device, upon disconnection(link loss) does not immediately detect it has disconnected (it can take up to 30 seconds if I remember), or it just behaves badly.
Thus, it does not readvertise the service on SDP (does not open the socket again), so when Android initiates the connection(as client) your server fails - has no open socket.
You should post the other device logs. And try with a different other device - but same Android phone and code!
Again, just a guess.
I had the same problem; my solution may be specific to the device I am using, but I found that by sleeping the thread for 1000ms between the last communication to the socket and the socket.close(), it would restart successfully.

Android to detect possibilities of no data connection

I have an application which needs to communicate with the server at some random interval through GPRS or EDGE.. But there are few possibilities at which internet cannot be accessed by the application when the user is in call or deactivated etc. At these time i have two scenario's recoverable and non recoverable.
Recoverable scenarios
On phone call ( User will hang up and data connection will be active
again)
No Signal (Sometimes signal may drop and the phone will get
signal again)
Non Recoverable Scenarios
Flight mode
Deactivating Data Connection
When its recoverable i can try again for the connection after some defined interval. And during non recoverable i have to alert user. For instance if the user deactivates data connection or enables flight mode i have to alert the user.
EDIT:I can able to detect flight mode through one of the intents. I couldn't able to find for others.
The below code return if valid connections are available
public boolean isConnectionsAvailable() {
boolean lRet = false;
try{
ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info= conMgr.getActiveNetworkInfo();
if(info != null && info.isConnected()) {
lRet = true ;
}else{
lRet = false ;
}
}catch (Exception e) {
Log.d("Connection Error", e.toString());
lRet = false ;
}
return lRet;
}
After this, if you have low signal strength then you make a HTTP request by setting relevant time out to it. If timeout happened give relevant alert msg to user as below
public void serverCall(String pURL){
if (isConnectionsAvailable()){
// Call server by setting proper timeout
}
}
Edit:
To check the Airplane mode status:
private static boolean isAirplaneModeOn(Context context) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) != 0;
}
You could try surrounding your method with try and catch. If the method fails because it cannot connect to your server for whatever reason you could call postDelayed from a Handler and re-run your method again in a pre-determined length of time.
Handler mHandler = new Handler();
Runnable yourMethodRunnable = new Runnable(){
#Override
public void run(){
yourMethod();
}
};
private void yourMethod(){
try{
// talk to server
} catch (InCallException e) {
mHandler.postDelayed(yourMethodRunnable, delay)
} catch (NoSignalException e) {
// etc...
} catch (OtherException e) {
// etc...
}
}
The exceptions are just examples, and likely don't exist, get the exceptions that you want to catch either from the Android Developer Docs, or by looking at the output from LogCat when you re-enact each time that the connection to the server would fail.

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