How to Create Android BLE Application Faster and Easier?
by ElecFreaks in Circuits > Arduino
123229 Views, 25 Favorites, 0 Comments
How to Create Android BLE Application Faster and Easier?
If you are an electronics enthusiast, and also fond of programming, I would be very glad to share with you an Android BLE application development method, so you can integrate the phone and MCU to do some more interesting things. Right now we begin to explain how to develop an Android BLE application, and you can also refer to the official Google tutorial. This guide is a packed tutorial, which enables you to build your Android BLE application more easily and more quickly. Of course, I’ll upload my source code for everyone to share it and you can also refer to the official sample sdk/samples/android-18/legacy/BluetoothLeGatt.
Source reading: http://www.elecfreaks.com/7906.html
Create a New Android Project
Open Eclipse, File->New->Android Application Project, and then fill the Application name in the Application Name edit box, for example, BleExample, or others. Minimum Required SDK selects API18:Android 4.3, and Target SDK also selects API18:Android 4.3, as buletooth 4.0 must be with Android 4.3edition or above. Others default unchanged and please continue clicking the Next button until Finish button appears, and then click the Finish button.
Add the Permissions and Services
Add the below code in the manifest file:
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> <service android:name="com.elecfreaks.ble.BluetoothLeService" android:enabled="true"/>
Create the ListView Item Layout File
Aiming to display each content of ListView, here we use customization(defining by yourself), so that each ListView can show more content, item_list.xml is demonstrated as below:
<?xml version="1.0"encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textViewDevName" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="24dp"/> android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12dp"/> <TextView android:id="@+id/textViewDevAddress" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12dp"/> </LinearLayout>
Copy the source code of BleExample /com.elecfreaks.ble to your project src directory,and then open the file with error prompt, pressing the shift+ctrl+O keys.
Modify Activity_main.xml, Increasing ScanButton and BleDeviceListView
Increased contents are shown as below:
<Button android:id="@+id/scanButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="scanOnClick" android:text="scan" /> <ListView android:id="@+id/bleDeviceListView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/scanButton" android:layout_below="@+id/scanButton" android:layout_above="@+id/sendButton" > </ListView>
In MainActivity.java, Add ScanButton Mothod of Responding to Events
(onClick="scanOnClick") public void scanOnClick(final View v){ }
Add Member for MainActivity
private Button scanButton; private ListView bleDeviceListView; private BLEDeviceListAdapter listViewAdapter; private BluetoothHandler bluetoothHandler; private boolean isConnected;
Set Member Value in MainActivity.onCreate
scanButton = (Button) findViewById(R.id.scanButton); bleDeviceListView = (ListView) findViewById(R.id.bleDeviceListView); listViewAdapter = new BLEDeviceListAdapter(this); bluetoothHandler = new BluetoothHandler(this); bluetoothHandler.setOnConnectedListener(new OnConnectedListener() { @Override public void onConnected(boolean isConnected) { // TODO Auto-generated method stub setConnectStatus(isConnected); } }); bluetoothHandler.setOnRecievedDataListener(new OnRecievedDataListener() { @Override public void onRecievedData(byte[] bytes) { // TODO Auto-generated method stub System.out.printf("REC:"); for(byte b:bytes) System.out.printf("%02X ", b); System.out.printf("\n"); } });
Adding SetConnectStatus Mothod
public void setConnectStatus(boolean isConnected){ this.isConnected = isConnected; if(isConnected){ showMessage("Connection successful"); scanButton.setText("break"); }else{ bluetoothHandler.onPause(); bluetoothHandler.onDestroy(); scanButton.setText("scan"); } } private void showMessage(String str){ Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); }
Adding Content in ScanOnClick
if(!isConnected){ bleDeviceListView.setAdapter(bluetoothHandler.getDeviceListAdapter)); bleDeviceListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { String buttonText = (String) ((Button)v).getText(); if(buttonText.equals("scanning")){ showMessage("scanning..."){ return ; } BluetoothDevice device = bluetoothHandler.getDeviceListAdapter().getItem(position).device; // connect bluetoothHandler.connect(device.getAddress()); } }); bluetoothHandler.setOnScanListener(new OnScanListener() { @Override public void onScanFinished() { // TODO Auto-generated method stub ((Button)v).setText("scan"); ((Button)v).setEnabled(true); } @Override public void onScan(BluetoothDevice device, int rssi, byte[] scanRecord) {} }); ((Button)v).setText("scanning"); ((Button)v).setEnabled(false); bluetoothHandler.scanLeDevice(true); }else{ setConnectStatus(false);
}
Send Data
byte[] data = new byte[1]; data[0] = 0x02; bluetoothHandler.sendData(data);
Receive Data
Upon receiving data, the mothod of
OnRecievedDataListener.onRecievedData(byte[] bytes) set from bluetoothHandler.setOnRecievedDataListener()OnRecievedDataListener.onRecievedData(byte[] bytes) would be used, and bytes means received data
Send Data to MCU Via Protocol.(Use BLUNO From ElecFreaks)
In src directory, create Transmitter.java, adding the constructed function with two parameters as below:
public Transmitter(Context context, BluetoothHandler bluetoothHandler){ this.context = context; this.mBluetoothHandler = bluetoothHandler; }
How to add sendData()?
private void sendData(byte[] bytes){ mBluetoothHandler.sendData(bytes); }
Receive MCU Data Via Protocol
MCU data receiving and sending protocol uses JSON packet,and the format is {“T”:your value, “V”:your value, …}. Of course you can define other values. Create the MyArray.java in src directory,aiming to connecting two arrays. The code was shown as below:
public class MyArray { static public byte[] arrayCat(byte[] buf1,byte[] buf2){ byte[] bufret=null; int len1 = 0; int len2 = 0; if(buf1 != null) len1 = buf1.length; if(buf2 != null) len2 = buf2.length; if(len1+len2 > 0) bufret = new byte[len1+len2]; if(len1 > 0) System.arraycopy(buf1, 0, bufret, 0, len1); if(len2 > 0) System.arraycopy(buf2, 0, bufret, len1, len2); return bufret; } }
Copy the protocol.java in my sample code to src directory Adding member
private Protocol protocol
From onCreate(),delete:
bluetoothHandler.setOnRecievedDataListener();
Add:
protocol = new Protocol(this, new Transmitter(this, bluetoothHandler)); protocol.setOnReceivedDataListener(recListener);
Adding member in MainActivity:
private static final boolean INPUT = false; private static final boolean OUTPUT = true; private static final boolean LOW = false; private static final boolean HIGH = true; private boolean digitalVal[]; private int analogVal[];
Initializing in onCreate:
digitalVal = new boolean[14]; analogVal = new int[14]; private OnReceivedRightDataListener recListener = new OnReceivedRightDataListener() { @Override public int onReceivedData(String str) { // TODO Auto-generated method stub try { JSONObject readJSONObject = new JSONObject(str); int type = readJSONObject.getInt("T"); int value = readJSONObject.getInt("V"); switch(type){ case Protocol.ANALOG:{ int pin = readJSONObject.getInt("P"); analogVal[pin] = value; }break; case Protocol.DIGITAL:{ int pin = readJSONObject.getInt("P"); digitalVal[pin] = (value>0)?HIGH:LOW; }break; case Protocol.TEMPERATURE:{ float temperature = ((float)value)/100; }break; case Protocol.HUMIDITY:{ float humidity = ((float)value)/100; }break; default:break; } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return 0; } };
Use Protocol to Send Data
protocol.writeAnalogData(9, 20); protocol.writeDigitalData(3, 1);
Use Protocol to Receive Data
protocol.readAnalogDataCommand(9); protocol.readDigitalDataCommand(3);
Note: Returned data is received by recListener
MCU Port Protocol(arduino)
Refer to the sample code of AndroidIOControl provided.
Reference
If you need more information, please refer to our website.