Now we are going to load up Eclipse and make a simple app to connect to our Bluetooth enabled Arduino. The first stage will be to make an activity to select an already paired BT device. Once working we will make another activity that will do something with that selected device in part 3.
Set up a new project named “simple bluetooth” with a minimum api of 8 and target of 18. Let eclipse make a main activity and name it “Device List”. Do not add a navigation type. Hit finish and let it all load up.
I have structured this so that we will get the manifest and layout files out of the way first and then tackle the activity programming.
Open up the file explorer for your new project and open the manifest file. Add Bluetooth permissions to your manifest under the <uses-sdk> declaration. I won’t post whole files of code for some things as it takes up a lot of room. There is a downloadable file of the full project at the end of the final part if you wish to see complete xml files etc.
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
We don’t need the ADMIN permission for this app but put it in anyway in case you get adventurous later. The times I have forgotten this step is unforgivable. Manifest done.
In the res/layout directory find your activity_device_list layout file. Delete the hello world stuff and put in a listView and 3 textViews. The listView will show our paired devices and the textViews are there to show instruction and information useful to the user.<code snippet>.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/title_paired_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Select btSerial device from paired devices:" android:visibility="gone" android:background="#666" android:textColor="#fff" android:paddingLeft="5dp" /> <ListView android:id="@+id/paired_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:stackFromBottom="false" android:layout_weight="1" /> <TextView android:id="@+id/connecting" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/infoText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="If no devices are listed please pair your device in Android settings" android:textAppearance="?android:attr/textAppearanceLarge" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center"> </LinearLayout> </LinearLayout>
You will notice some yellow warnings underneath where I have used text strings. Usually I would suggest using the strings.xml in the values folder to keep all text strings and then reference to them via r.id but as this is a simple example I didn’t want to deviate from the main point.
That paragraph was quite the deviation. In the layout directory add another xml layout file called device_name (remember to have.xml end the filename). This will be used for the actual device names populating the list.
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:padding="5dp"> </TextView>
Now that all the layouts are complete we can move on to programming the Device List activity. This activity is based on the Google Chat example but has been slimmed down and simplified so there is a little less to learn. Functionality wise it will generate a list of the paired devices on an Android device. From there we will add the ability to pick a paired device and take its details through to a new activity, where we will send data to the Arduino.
Below is the code from the Device List activity. I have tried to comment as much as I can to give answers on what each bit of code is doing, rather than explain it all in one big paragraph here. I won’t go in to every detail, instead I will focus on the bits exclusive to the functionality of this app. The main parts to focus on are getting the bluetooth adapter for the device and setting up the array adapter and the list view. Paired devices are then retrieved from the Bluetooth adapter and added to the array adapter, which in turn are displayed using the list view.
package com.example.simplebluetooth; import java.util.Set; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class DeviceListActivity extends Activity { // textview for connection status TextView textConnectionStatus; ListView pairedListView; // Member fields private BluetoothAdapter mBtAdapter; private ArrayAdapter<String> mPairedDevicesArrayAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_device_list); textConnectionStatus = (TextView) findViewById(R.id.connecting); textConnectionStatus.setTextSize(40); // Initialize array adapter for paired devices mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); // Find and set up the ListView for paired devices pairedListView = (ListView) findViewById(R.id.paired_devices); pairedListView.setAdapter(mPairedDevicesArrayAdapter); } @Override public void onResume() { super.onResume(); //It is best to check BT status at onResume in case something has changed while app was paused etc checkBTState(); mPairedDevicesArrayAdapter.clear();// clears the array so items aren't duplicated when resuming from onPause textConnectionStatus.setText(" "); //makes the textview blank // Get the local Bluetooth adapter mBtAdapter = BluetoothAdapter.getDefaultAdapter(); // Get a set of currently paired devices and append to pairedDevices list Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); // Add previously paired devices to the array if (pairedDevices.size() > 0) { findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);//make title viewable for (BluetoothDevice device : pairedDevices) { mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } else { mPairedDevicesArrayAdapter.add("no devices paired"); } } //method to check if the device has Bluetooth and if it is on. //Prompts the user to turn it on if it is off private void checkBTState() { // Check device has Bluetooth and that it is turned on mBtAdapter=BluetoothAdapter.getDefaultAdapter(); // CHECK THIS OUT THAT IT WORKS!!! if(mBtAdapter==null) { Toast.makeText(getBaseContext(), "Device does not support Bluetooth", Toast.LENGTH_SHORT).show(); finish(); } else { if (!mBtAdapter.isEnabled()) { //Prompt user to turn on Bluetooth Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, 1); } } } }
So hopefully nothing new here but in case a little learning/refresher is needed, I would recommend having a look at this post on Lists/arrayAdapter and the google documentation for setting up bluetooth. Both are explained in much more detail that I could ever give!
Now run the App on your device. Make sure your BT module has already been paired in settings and that it is on. I would leave BT off to check that the app correctly prompts you to turn it on. Once BT is enable and the app starts up you should see something similar to the below. You will see I changed the name of my BT module to ‘btserial’ for this tutorial.
If it works be proud, half of the work is done. If not, check your code against my version[adding this soon]. As useful as this is it doesn’t currently do anything with our Arduino, which isn’t ideal. So in part 3 we will create a new activity that will talk to our BT enabled Arduino. Have a break and look at a cat or something, then move on to part 3.
Receiving error: Cannot convert from element type Object to BluetoothDevice.
Eclipse is highlighting these lines in particular:
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);//make title viewable
for (BluetoothDevice device : pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + “\n” + device.getAddress());
}
} else {
mPairedDevicesArrayAdapter.add(“no devices paired”);
}
hello i followed your entire code word by word in eclipse and i tried to run it on my android phone but when i open the app i am getting a message displaying “Unfortunatley Simple bluetooth has stopped working” please help me
Look into the LogCat and see where it crashed. Hopefully it will be something quite simple.
The message is also displayed everytime I choose a paired device. This is the error stated in the LogCat. I don’t know how to troubleshoot it. Please help me.
12-28 11:56:59.509 9209-9209/com.example.jbipanag.simplebluetooth2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.jbipanag.simplebluetooth2, PID: 9209
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.jbipanag.simplebluetooth2/com.example.jbipanag.simplebluetooth2.MainActivity}: android.view.InflateException: Binary XML file line #2: Error inflating class android.support.design.widget.CoordinatorLayout
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class android.support.design.widget.CoordinatorLayout
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:707)
at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
at android.view.LayoutInflater.inflate(Native Method)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:341)
at android.app.Activity.setContentView(Activity.java:1948)
at com.example.jbipanag.simplebluetooth2.MainActivity.onCreate(MainActivity.java:43)
at android.app.Activity.performCreate(Activity.java:5343)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2331)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn’t find class “android.support.design.widget.CoordinatorLayout” on path: DexPathList[[zip file “/data/app/com.example.jbipanag.simplebluetooth2-1.apk”],nativeLibraryDirectories=[/data/app-lib/com.example.jbipanag.simplebluetooth2-1, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at android.view.LayoutInflater.createView(LayoutInflater.java:559)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
at android.view.LayoutInflater.inflate(Native Method)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:341)
at android.app.Activity.setContentView(Activity.java:1948)
at com.example.jbipanag.simplebluetooth2.MainActivity.onCreate(MainActivity.java:43)
at android.app.Activity.performCreate(Activity.java:5343)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2331)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(Native Method)
I need this for study purposes. Thank you!
Hello!
I am getting this message: “Cannot resolve symbol ‘device_name’ “.
It appears on this line: mPairedDevicesArrayAdapter = new ArrayAdapter(this, R.layout.device_name);
Can you help me out?
Check that device_name exists in your layout file
device_name was not even exist in your layout file?
I’m also having this problem.
i met a problem with String noDevices = getResources().getText(R.string.none_paired).toString();
what is the “none_paired”? it is red thanks for your help in advance
That is referring to a string value stored in Res/Values/Strings. Find that file and add an entry for none_paired. This is to help with localisation etc and is only in the version I put on Github. Alternatively you are fine to put a hardcoded string in if you like. e.g. mPairedDevicesArrayAdapter.add(“no devices paired”);
Hi, in the line:
setContentView(R.layout.activity_device_list);
it underlines “activity_device_list” in red because it can’t resolve the symbol, and it can’t because there’s no activity_device_list in any of my xml files (I copy pasted exactly what is shown). What should I do?
Early on in the tutorial I mention naming your activity device list activity, so the generated xml layout file should be named by the system similarly. Perhaps your layout file is called something like “main_activity”? Use that instead. Essentially whatever the activity class is called.
It does not work for me. I’ve correted every error but the connection doesn’t even start. Can someone help me?
It does not work for me. I’ve correted every error but the connection doesn’t even start. Can someone help me? Everything is correct but the only thing that really works is that it shows the devices that i’ve paired from android settings. Help me please it’s for school
Great work! really helped me. Thanks You!!
You awesome duuuuuuuuude!!! Thank you so much!
When I test the app on the android device, it will stop. Could you help me?
Sounds like its crashing, better have a look at the crash logs
When running the app no devices are appearing even though I have several paired devices. Not sure why this is happening.
Hello, I have modified this code according to my need but facing problem in this code. whenever I am trying to open this app its not responding please help me in this.
Thank you so much
that was incredibly helpful for me,
but do I need to use threads if I have only one sensor to read from ?
another question, I’m using pulse sensor in my project, which will keep sending the heartbeat continuously, how can I stop the transfer after only one min ?
2 Pingbacks
Recent Posts
Archives
Recent Comments
Categories
Meta
Recent Posts
Recent Comments
Archives
Categories
Meta