Finding UUIDs in Android 2.0
Asked Answered
J

2

1

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" );
          }
      } 
  });
}
Janes answered 12/6, 2012 at 19:13 Comment(2)
Can you probably give the link to that page?Coursing
Yeah, it's right here wiresareobsolete.com/wordpress/2010/11/android-bluetooth-rfcommJanes
S
5

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

Subclavius answered 13/6, 2012 at 15:1 Comment(7)
If you happen to take a look at this, I came back to this code again today and realized its still not working for me. I have posted a new question if you have a chance to help. #11106391Janes
@Devunwired hi I am getting ParcelUuid[] retval as null when preferring above code. Can you help in this??Flagman
@nick This method only works if you have recently done a discovery operation, as it pulls data from the cache. If you need fresh data from a device you will need to look at fetchUuidsWithSdp() instead. Both of these methods are now public in Android 4.0.3 also, so you may try testing on a device with a newer version to make sure the issue isn't elsewhere in the code.Subclavius
@Devunwired I have gone through your site.Actually the client requirement on only Android 2.2 . Thats why I am working on this.I just want the UUid of my device and afterdiscovery, the uuid of the other device whom i do connect with my device. I have browse on net. Did googling, but unable to find any solution to this.Flagman
@Devunwired Im using uuids[0].getUuid() this for UUid from your method servicesFromDevice(device). it will pair automatically? or we need to code for pairing?Electrode
This works but how can reflection override API levels? the getUUIDs method should only be available on API >=15 but this also works on 13Copestone
The methods were only public starting in 4.0.3., but they've been a part of the core source code since ~2.0Subclavius
S
-1

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();
                    }
                }
            }
        }       
    }
};
Stratocracy answered 23/5, 2014 at 8:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.