Reputation: 4191
I am writing a program which needs to be run in Android 2.0. I am currently trying to connect my android device to an embedded bluetooth chip. I have been given information as to use fetchuidsWithSDP(), or getUuids(), but the page I read explained that these methods are hidden in the 2.0 SDK, and must be called using reflection. I have no idea what that means and there is no explanation. There is example code given, but very little explanation behind it. I was hoping someone could help me understand what is actually going on here, as I am very new to Android development.
String action = "android.bleutooth.device.action.UUID";
IntentFilter filter = new IntentFilter( action );
registerReceiver( mReceiver, filter );
The page I read also says that in the first line bluetooth is spelled "bleutooth" on purpose. If anyone can explain that, I would appreciate that as well as it makes no sense to me, unless the developers made a typo.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive( Context context, Intent intent ) {
BluetoothDevice deviceExtra = intent.getParcelableExtra("android.bluetooth.device.extra.Device");
Parcelable[] uuidExtra = intent.getParcelableArrayExtra("android.bluetooth.device.extra.UUID");
}
};
I am having trouble grasping how exactly I find the correct UUID for my embedded bluetooth chip. If anyone could help it'd be greatly appreciated.
EDIT: I am going to add the rest of my onCreate() method so you can see what I'm working with.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up window View
setContentView(R.layout.main);
// Initialize the button to scan for other devices.
btnScanDevice = (Button) findViewById( R.id.scandevice );
// Initialize the TextView which displays the current state of the bluetooth
stateBluetooth = (TextView) findViewById( R.id.bluetoothstate );
startBluetooth();
// Initialize the ListView of the nearby bluetooth devices which are found.
listDevicesFound = (ListView) findViewById( R.id.devicesfound );
btArrayAdapter = new ArrayAdapter<String>( AndroidBluetooth.this,
android.R.layout.simple_list_item_1 );
listDevicesFound.setAdapter( btArrayAdapter );
CheckBlueToothState();
// Add an OnClickListener to the scan button.
btnScanDevice.setOnClickListener( btnScanDeviceOnClickListener );
// Register an ActionFound Receiver to the bluetooth device for ACTION_FOUND
registerReceiver( ActionFoundReceiver, new IntentFilter( BluetoothDevice.ACTION_FOUND ) );
// Add an item click listener to the ListView
listDevicesFound.setOnItemClickListener( new OnItemClickListener()
{
public void onItemClick(AdapterView<?> arg0, View arg1,int arg2, long arg3)
{
// Save the device the user chose.
myBtDevice = btDevicesFound.get( arg2 );
// Open a socket to connect to the device chosen.
try {
btSocket = myBtDevice.createRfcommSocketToServiceRecord( MY_UUID );
} catch ( IOException e ) {
Log.e( "Bluetooth Socket", "Bluetooth not available, or insufficient permissions" );
} catch ( NullPointerException e ) {
Log.e( "Bluetooth Socket", "Null Pointer One" );
}
// Cancel the discovery process to save battery.
myBtAdapter.cancelDiscovery();
// Update the current state of the Bluetooth.
CheckBlueToothState();
// Attempt to connect the socket to the bluetooth device.
try {
btSocket.connect();
// Open I/O streams so the device can send/receive data.
iStream = btSocket.getInputStream();
oStream = btSocket.getOutputStream();
} catch ( IOException e ) {
Log.e( "Bluetooth Socket", "IO Exception" );
} catch ( NullPointerException e ) {
Log.e( "Bluetooth Socket", "Null Pointer Two" );
}
}
});
}
Upvotes: 1
Views: 5345
Reputation: 11
I also faced the same issue and this is how I solved it for Android 2.3.3. I think the same solution will work for android 2.2 also.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@SuppressLint("NewApi")
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(getApplicationContext(),"Device: "+device.getName(),Toast.LENGTH_SHORT).show();
devices.add(device.getName() + "\n" + device.getAddress());
list.add(device);
}
else if(BluetoothDevice.ACTION_UUID.equals(action)){
Toast.makeText(getApplicationContext(),"I am Here",Toast.LENGTH_SHORT).show();
}
else {
if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Toast.makeText(getApplicationContext(),"Done Scanning..",Toast.LENGTH_SHORT).show();
Iterator<BluetoothDevice> itr = list.iterator();
while(itr.hasNext())
{
BluetoothDevice dev=itr.next();
if(dev.fetchUuidsWithSdp())
{
Parcelable a[]=dev.getUuids();
Toast.makeText(getApplicationContext(),dev.getName()+":"+a[0],Toast.LENGTH_SHORT).show();
}
}
}
}
}
};
Upvotes: -1
Reputation: 63293
You're probably better off using the synchronous version so you don't have to deal with all the moving parts of setting up the BroadcastReceiver
. Since you are always doing this on the heels of discovery, the cached data will always be fresh.
Here the functionality of getting the UUID data encapsulated up into a method. This code was in one of the comments of the blog post you linked:
//In SDK15 (4.0.3) this method is now public as
//Bluetooth.fetchUuisWithSdp() and BluetoothDevice.getUuids()
public ParcelUuid[] servicesFromDevice(BluetoothDevice device) {
try {
Class cl = Class.forName("android.bluetooth.BluetoothDevice");
Class[] par = {};
Method method = cl.getMethod("getUuids", par);
Object[] args = {};
ParcelUuid[] retval = (ParcelUuid[]) method.invoke(device, args);
return retval;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
You can then call this method anywhere in your code, passing it a BluetoothDevice
and getting back an array of UUIDs for that device's services (typically for small embedded stacks the array is only 1 item); something like:
// Save the device the user chose.
myBtDevice = btDevicesFound.get( arg2 );
//Query the device's services
ParcelUuid[] uuids = servicesFromDevice(myBtDevice);
// Open a socket to connect to the device chosen.
try {
btSocket = myBtDevice.createRfcommSocketToServiceRecord(uuids[0].getUuid());
} catch ( IOException e ) {
Log.e( "Bluetooth Socket", "Bluetooth not available, or insufficient permissions" );
} catch ( NullPointerException e ) {
Log.e( "Bluetooth Socket", "Null Pointer One" );
}
in the block you posted above.
As a side note, calling all this code in the manner you have will make your application sad later. The block of code calling connect()
and obtaining the streams should be done on a background thread because that method will block for a period of time and calling this code on the main thread will freeze your UI temporarily. You should move that code into an AsyncTask
or a Thread
like the BluetoothChat sample in the SDK does.
HTH
Upvotes: 5