Accessing Bluetooth

Data sometimes needs to be transferred to another device, but to one where there is no network infrastructure. We may therefore want to integrate Bluetooth into our app to transfer data or to interact with various devices that cannot be accessed via the Internet or a local network.

How to do it...

To interact with the various Bluetooth services, we need the BluetoothAdapter instance:

  1. As with most hardware services, we need to request permission to access Bluetooth:
    [assembly: UsesPermission(Manifest.Permission.Bluetooth)]
  2. If we want to directly control the Bluetooth hardware, we need to specify an additional permission:
    [assembly: UsesPermission(
      Manifest.Permission.BluetoothAdmin)]
  3. Once we have the permissions we need, we obtain the BluetoothAdapter instance:
    var bluetooth = BluetoothAdapter.DefaultAdapter;
    if (bluetooth == null) {
      // device does not support Bluetooth
    }
    else {
      State state = bluetooth.State;
    }
  4. If Bluetooth is not enabled, we can request the user to enable it:
    const string RequestToEnableBluetooth = 1; // any ID
    if (!bluetooth.IsEnabled) {
      var intent = new Intent(
        BluetoothAdapter.ActionRequestEnable);
      StartActivityForResult(intent, RequestToEnableBluetooth);
    }
  5. Once the Bluetooth activity has started and finished, we will get a callback to the OnActivityResult() method:
    protected override void OnActivityResult(
      int requestCode, Result resultCode, Intent data) {
        base.OnActivityResult(requestCode, resultCode, data);
        if (requestCode == RequestToEnableBluetooth) {
        bool success = resultCode == Result.Ok;
      }
    }
  6. Once we have Bluetooth enabled, there are several things we can do with the adapter, such as getting a list of paired devices:
    var pairedDevices = bluetooth.BondedDevices;
    foreach (var device in pairedDevices) {
      var name = device.Name;
    }
  7. We can also start listening for new Bluetooth devices:
    bool started = bluetooth.StartDiscovery();
  8. Once we have a device that we want, we can stop listening:
    if (bluetooth.IsDiscovering) {
      bool canceled = bluetooth.CancelDiscovery();
    }
  9. If we want to make this device discoverable to other devices, we can request it for a specified time interval:
    int interval = 300; // seconds
    var intent = new Intent(
      BluetoothAdapter.ActionRequestDiscoverable);
    intent.PutExtra(
      BluetoothAdapter.ExtraDiscoverableDuration,
      interval);
    StartActivity(intent);

If we want to listen for changes to the Bluetooth state or to be notified when a new device is found, we register a broadcast receiver with the activity or service:

  1. For this, we need the receiver that will handle events that we are interested in:
    private class BluetoothReceiver : BroadcastReceiver {
      public override void OnReceive(
        Context context, Intent intent) {
        string action = intent.Action;
        if (action == BluetoothAdapter.ActionStateChanged) {
          var newState = (State)intent.GetIntExtra(
            BluetoothAdapter.ExtraState, 0);
        }
        if (action == BluetoothAdapter.ActionScanModeChanged) {
          var newScanMode = (ScanMode)intent.GetIntExtra(
            BluetoothAdapter.ExtraScanMode, 0);
        }
        if (action == BluetoothDevice.ActionFound) {
          var newDevice = intent.GetParcelableExtra(
            BluetoothDevice.ExtraDevice) as BluetoothDevice;
        }
      }
    }
  2. We can then register the receiver for each action we are interested in:
    receiver = new BluetoothReceiver();
    RegisterReceiver(receiver, new IntentFilter(BluetoothAdapter.ActionStateChanged));
    RegisterReceiver(receiver, new IntentFilter(BluetoothAdapter.ActionScanModeChanged));
    RegisterReceiver(receiver, new IntentFilter(BluetoothDevice.ActionFound));
  3. Finally, we have to be sure to unregister it when we no longer need it:
    if (receiver != null) {
      UnregisterReceiver (receiver);
    }

How it works...

Bluetooth is a wireless technology for transmitting and receiving data over short distances. There are three classes of Bluetooth radios, each with a different range. Typically, Class 3 radios have a very short range of less than one meter, Class 2 radios have a range of 10 meters, and Class 3 radios about 100 meters.

More information on how Bluetooth works can be found on the official Bluetooth website: http://www.bluetooth.com/Pages/Basics.aspx.

We can use the Android Bluetooth API to scan for and connect to other Bluetooth devices, as well as to send data to other devices. But before we start using the Bluetooth adapter, we need to request permission to do so from Android.

Note

In order to control the Bluetooth adapter, we need admin permission.

If we want to interact with the Bluetooth adapter, we need to obtain the current adapter by using the DefaultAdapter property on the BluetoothAdapter type. We need to first verify that there is a Bluetooth adapter, and if there is one, that it is enabled.

We can request that the user enable the adapter by starting an activity with the ActionRequestEnable action intent. This will display a popup requesting permission for the app to enable Bluetooth.

Once we have the adapter, we can view the paired devices as well as scan for other devices. We use the StartDiscovery() method to scan for devices, and we make the device discoverable using the ActionRequestDiscoverable action intent.

A device will only be discovered by other devices if that device has been made discoverable. Before scanning for devices, it may be worth querying the collection of paired devices to see if the device is already known.

Tip

A device may already be known, so querying the collection of paired devices may be more advantageous than starting the discovery scan.

When we want to discover other devices, we initiate the scan with the StartDiscovery() method and then listen for an ActionFound action intent using a broadcast receiver. The scan interval is usually short, around 12 seconds.

We can also make the device discoverable by starting an activity with the ActionRequestDiscoverable action intent. A device can be made discoverable for a slightly longer period than a scan. A value between 0 and 3,600 seconds can be specified by the ExtraDiscoverableDuration intent extra. By default, and for any value outside those bounds, the device will become discoverable for 120 seconds.

Similar to listening for network state changes, we can listen for events from the Bluetooth adapter. We are able to listen to several events, including when the Bluetooth state has changed, when the scan mode has changed, or when a new device has been discovered. In each type of broadcast, we can access the relevant information in the extras of the intent.

There's more...

In addition to normal Bluetooth, the device may also support Bluetooth Low Energy (BLE). BLE is available on Android versions 4.3 and above, and has lower power consumption compared to classic Bluetooth. BLE is used for devices that have low power requirements such as proximity sensors or health and fitness monitors.

To check to see if a device has BLE, we can ask the PackageManager instance:

bool hasBLE = PackageManager.HasSystemFeature(
  PackageManager.FeatureBluetoothLe);

Once we have determined that the device supports BLE, we can then use slightly different mechanisms to scan, connect, and communicate. Instead of StartDiscovery, we would invoke StartLeScan, and instead of the usual RFCOMM channel, we connect to a GATT server.

See also

  • The Obtaining network state changes recipe
  • The Transferring data via Bluetooth recipe
  • The Receiving NFC events recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.171.20