-
Near Field Communication, BlueTooth and Android
Near Field Communication
- There are a range of Near Field Communications techniques. These include:
- RFID
- Bluetooth
- QR Codes
- Near Field Communication (NFC) is a set of protocols that permit 2 electronic devices to establish communication with each other and to potentially exchange information. Please visit Links to learn more about near field communication.
- 🔗 http://www.nearfieldcommunication.org/
- 🔗 http://nfc-forum.org/
Android and Bluetooth
The Android platform includes support for the Bluetooth network stack, which allows a device to wirelessly exchange data with other Bluetooth devices.
Bluetooth API
The application framework provides access to the Bluetooth functionality through the Android Bluetooth APIs. These APIs let applications wirelessly connect to other Bluetooth devices, enabling point-to-point and multipoint wireless features.
API Functionality
- Using the Bluetooth APIs, an Android application can perform the following:
- Scan for other Bluetooth devices
- Query the local Bluetooth adapter for paired Bluetooth devices
- Establish RFCOMM channels
- Connect to other devices through service discovery
- Transfer data to and from other devices
- Manage multiple connections
Please visit the following link for bluetooth Development
🔗 http://developer.android.com/guide/topics/wireless/bluetooth.html
- The following are supporting classes for API functionality. These will be discussed in detail.
- BluetoothAdapter
- BluetoothDevice
- BluetoothServerSocket
- BluetoothSocket
-
Let us learn more about supporting classes for API functionality as previously outlined.
Bluetooth Adapter
BluetoothAdapter represents the local Bluetooth adapter (Bluetooth radio). The BluetoothAdapter is the entry-point for all Bluetooth interaction. Using this, you can discover other Bluetooth devices, query a list of bonded (paired) devices, instantiate Bluetoothdevice using a known MAC address, and create a BluetoothServerSocket to listen for communications from other devices.
Bluetooth Device
BluetoothDevice represents a remote Bluetooth device. Use this to request a connection with a remote device through a BluetoothSocket or query information about the device such as its name, address, class, and bonding state.
Bluetooth Socket
BluetoothSocket represents the interface for a Bluetooth socket (similar to a TCP Socket). This is the connection point that allows an application to exchange data with another Bluetooth device via InputStream and OutputStream.
Bluetooth Server Socket
BluetoothServerSocket represents an open server socket that listens for incoming requests (similar to a TCP ServerSocket). In order to connect two Android devices, one device must open a server socket with this class. When a remote Bluetooth device makes a connection request to this device, the BluetoothServerSocket will return a connected Bluetooth Socket when the connection is accepted.
-
Bluetooth Class
BluetoothClass describes the general characteristics and capabilities of a Bluetooth device. This is a read-only set of properties that define the device's major and minor device classes and its services. However, this does not reliably describe all Bluetooth profiles and services supported by the device, but is useful as a hint to the device type.
Bluetooth Permisions
You need to add a permission to the manifest file for your Activity.
<uses-permission android:name="android.permission.BLUETOOTH“ />
Bluetooth Adaptor
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { // Device does not support Bluetooth // so inform the user }
Enabling Bluetooth
Next, you need to ensure that Bluetooth is enabled. Call isEnabled() to check whether Bluetooth is currently enabled. If this method returns false, then Bluetooth is disabled. To request that Bluetooth be enabled, call startActivityForResult() with the ACTION_REQUEST_ENABLE action Intent. This will issue a request to enable Bluetooth through the system settings (without stopping your application).
if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent( BluetoothAdapter. ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }
The REQUEST_ENABLE_BT constant passed to startActivityForResult() is a locally defined integer (which must be greater than 0), that the system passes back to you in your onActivityResult() implementation as the requestCode parameter.
If enabling Bluetooth succeeds, your activity receives the RESULT_OK result code in the onActivityResult() callback. If Bluetooth was not enabled due to an error (or the user responded "No") then the result code is RESULT_CANCELED.
-
Finding Devices
Using the BluetoothAdapter, you can find remote Bluetooth devices either through device discovery or by querying the list of paired (bonded) devices.
Pairing
Once a connection is made with a remote device for the first time, a pairing request is automatically presented to the user. When a device is paired, the basic information about that device (such as the device name, class, and MAC address) is saved and can be read using the Bluetooth APIs.
Pairing/Connection
Remember there is a difference between being paired and being connected. To be paired means that two devices are aware of each other's existence, have a shared link-key that can be used for authentication, and are capable of establishing an encrypted connection with each other.
To be connected means that the devices currently share an RFCOMM channel and are able to transmit data with each other. The current Android Bluetooth API's require devices to be paired before an RFCOMM connection can be established. (Pairing is automatically performed when you initiate an encrypted connection with the Bluetooth APIs.)
-
Querying Paired Devices
For example, you can query all paired devices and then show the name of each device to the user, using an ArrayAdapter.
Paired Devices
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { // Add the name and address to an // array adapter to show in a ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } }
Discovering Devices
To start discovering devices, simply call startDiscovery(). The process is asynchronous and the method will immediately return with a boolean indicating whether discovery has successfully started. The discovery process usually involves an inquiry scan of about 12 seconds, followed by a page scan of each found device to retrieve its Bluetooth name.
Discovery
// Create a BroadcastReceiver for ACTION_FOUND private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 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); // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } };
-
Connection/Data Transfer
All that's needed from the Bluetooth device object in order to initiate a connection is the MAC address.
In order to create a connection between your application on two devices, you must implement both the server-side and client-side mechanisms, because one device must open a server socket and the other one must initiate the connection (using the server device's MAC address to initiate a connection).
The server and client are considered connected to each other when they each have a connected BluetoothSocket on the same RFCOMM channel. At this point, each device can obtain input and output streams and data transfer can begin.
Server
When you want to connect two devices, one must act as a server by holding an open Bluetooth Server Socket. The purpose of the server socket is to listen for incoming connection requests and when one is accepted, provide a connected BluetoothSocket. When the BluetoothSocket is acquired from the Bluetooth Server Socket, the BluetoothServerSocket can (and should) be discarded, unless you want to accept more connections.
-
Connecting Step 1
Get aBluetoothServerSocket by calling thelistenUsingRfcommWithServiceRecord(String, UUID). The string is an identifiable name of your service, which the system will automatically write to a new Service Discovery Protocol (SDP) database entry on the device (the name is arbitrary and can simply be your application name).
Connecting Step 2
Start listening for connection requests by calling accept().This is a blocking call. It will return when either a connection has been accepted or an exception has occurred. A connection is accepted only when a remote device has sent a connection request with a UUID matching the one registered with this listening server socket. When successful, accept() will return a connected BluetoothSocket.
Connecting Step 3
Unless you want to accept additional connections, call close(). This releases the server socket and all its resources, but does not close the connected BluetoothSocket that's been returned by accept().
-
Threads
The accept() call should not be executed in the main activity UI thread because it is a blocking call and will prevent any other interaction with the application. It usually makes sense to do all work with a BluetoothServerSocket or BluetoothSocket in a new thread managed by your application.
Server Code part 1
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; }
Server Code part 2
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); mmServerSocket.close(); break; } } }
-
Connecting as a Client step 1
Using the BluetoothDevice, get a BluetoothSocket by calling createRfcommSocketToServiceRecord(UUID). This initializes a BluetoothSocket that will connect to the Bluetooth Device. The UUID passed here must match the UUID used by the server device when it opened its BluetoothServerSocket (with listenUsingRfcommWithServiceRecord(String, UUID)).
Connecting as a Client step 2
Initiate the connection by calling connect(). Upon this call, the system will perform an SDP lookup on the remote device in order to match the UUID. If the lookup is successful and the remote device accepts the connection, it will share the RFCOMM channel to use during the connection and connect() will return.
Note: - connect() is a blocking call, therefore this connection procedure should always be performed in a thread separate from the main activity thread.
Client Code part 1
private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; public ConnectThread(BluetoothDevice device) { // Use a temporary object that is later assigned to mmSocket, // because mmSocket is final BluetoothSocket tmp = null; mmDevice = device; // Get a BluetoothSocket to connect with the given BluetoothDevice try { // MY_UUID is the app's UUID string, also used by the server code tmp = device.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { } mmSocket = tmp; }
-
Client Code part 2
public void run() { // 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(); } catch (IOException connectException) { // Unable to connect; close the socket and get out try { mmSocket.close(); } catch (IOException closeException) { } return; } // Do work to manage the connection (in a separate thread) manageConnectedSocket(mmSocket); }
Connecting as a Client step 2
This method is a blocking call. If, for any reason, the connection fails or the connect() method times out (after about 12 seconds), then it will throw an exception. For example, a Bluetooth Chat on Android.
Example Bluetooth Chat
- This application allows two Android devices to carry out two-way text chat over Bluetooth. It demonstrates all the fundamental Bluetooth API capabilities, such as:
- Scanning for other Bluetooth devices
- Querying the local Bluetooth adapter for paired Bluetooth devices
- Establishing RFCOMM channels/sockets
- Connecting to a remote device
- Transfering data over Bluetooth
-
Using a Database to Persist Data
SQLite on Android
What is SQLite?
- Open Source Database that supports standard relational database features, such as:
- SQL Syntax
- Transactions
- Prepared Statements
SQLite and Android
Runs on every android device and does not require any setup or administration. Database access may be time consuming so run in a separate thread.
SQLite Database Location
Usually SQLite database is located in DATA/data/APP_NAME/databases/FILENAME. Where APP_NAME is the name of your application and FILENAME is the name you have given the database. In order to use SQLite, you need to know the basics features and functionality of Relational Database Development.
Creating an SQLite Database
To create and upgrade a database in your Android application you usually subclass SQLiteOpenHelper. To do that, in the constructor of your subclass you can call the super() method ofSQLiteOpenHelper, specifying the database name and the current database version.
Method Override
Within the class, you need to override the onCreate() and onUpgrade() methods.
Creating the Database
onCreate() is called by the framework, if the database does not exists.
Updating the Database
onUpgrade() is called, if the database version is increased in your application code. This method allows you to update the database schema.
Parameters
Both methods receive an SQLiteDatabase object as parameter which represents the database.
Accessing the Database
SQLiteOpenHelper provides the methods getReadableDatabase() and getWriteableDatabase() to get access to an SQLiteDatabase object; either in read or write mode.