Bluetooth Connection in Android from Matt Bell's blog
Project Structure
Here is the java and xml code from Matt Bell's blog adapted to send data only:
[code]--------------------------------------------------------------------------------------
package here
imports here
public class BluetoothTest extends Activity
{
TextView myLabel;
EditText myTextbox;
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // need a activity_main layout XML file
// with these objects below in it (buttons, labels etc...):
Button openButton = (Button) findViewById(R.id.open);
Button sendButton = (Button) findViewById(R.id.send);
Button closeButton = (Button) findViewById(R.id.close);
myLabel = (TextView) findViewById(R.id.label);
myTextbox = (EditText) findViewById(R.id.entry);
// Open BT connection Button
openButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
findBT();
openBT();
} catch (IOException ex)
{
}
}
});
// Send Button
sendButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
sendData();
} catch (IOException ex)
{
}
}
});
// Close button
closeButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
closeBT();
} catch (IOException ex)
{
}
}
});
}
void findBT()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null)
{
myLabel.setText("No bluetooth adapter available");
}
if (!mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0)
{
for (BluetoothDevice device : pairedDevices)
{
if (device.getName().equals("linvor"))// change accordingly
{
mmDevice = device;
break;
}
}
}
myLabel.setText("Bluetooth Device Found");
}
void openBT() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
if (mmDevice != null)
{
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
myLabel.setText("Bluetooth Opened");
}
}
void sendData() throws IOException
{
String msg = myTextbox.getText().toString();
msg += "\n";
mmOutputStream.write(msg.getBytes());
myLabel.setText("Data Sent");
}
void closeBT() throws IOException
{
mmOutputStream.close();
mmSocket.close();
myLabel.setText("Bluetooth Closed");
}
}// end of java code.
XML code:
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your package"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name" >
<activity android:name="BluetoothTest"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="9"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<supports-screens android:anyDensity="true" />
</manifest>
Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Type here:"/>
<EditText
android:id="@+id/entry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background"
android:layout_below="@id/label"/>
<Button
android:id="@+id/open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/entry"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dip"
android:text="Open" />
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/open"
android:layout_alignTop="@id/open"
android:text="Send" />
<Button
android:id="@+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/send"
android:layout_alignTop="@id/send"
android:text="Close" />
</RelativeLayout>
Arduino Test Code:
#include <SoftwareSerial.h>
int bluetoothTx = 2;
int bluetoothRx = 3;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
const int LED = 10;
char incomingByte = ' ';
void setup()
{
//Setup usb serial connection to computer
Serial.begin(9600);
pinMode(LED, OUTPUT);
//Setup Bluetooth serial connection to android
bluetooth.begin(115200);
bluetooth.print("$$$");
delay(100);
bluetooth.println("U,9600,N");
bluetooth.begin(9600);
Serial.println("Start");
}
void loop()
{
//Read from bluetooth and write to usb serial
if(bluetooth.available())
{
Serial.println("BlueTooth OK");
char toSend = (char)bluetooth.read();
Serial.println(toSend);
incomingByte = toSend;
}
if (incomingByte == 'l')
{
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
}
}
[end code]----------------------------------------------
Only 1 error remains:
ReplyDeletemmDevice = device; // device is red underlined
Type mismatch: cannot convert from BluetoothDevice to String
for (BluetoothDevice device : pairedDevices)
ReplyDelete{
....
The parameter [device] should be a BluetoothDevice not a String, as in the above. Can you please post some more code so I can see a complete block? Thanks
My goal is relatively simple, except I am new to Java / Eclipse. I am ok on the arduino side; I have a home grown project which simply needs to send an ascii character from Android to Arduino via Bluetooth on pressing a button on my phone app. As you can tell I started by cludgeing bits together for www in hope it will compile.
ReplyDeleteThanks for your enduring help, newbies are infuriating I am sure.
My email if it might be easier is les(at)wilkipedia.net
package com.example.onestep;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import android.os.Bundle;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.*;
import android.widget.*;
public class MainActivity extends Activity {
private BluetoothAdapter btAdapter;
public Button btn1; //
public Button btn2;
public EditText etxt1; //
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1=(Button)findViewById(R.id.bt_on);
btn2=(Button)findViewById(R.id.bt_off);
etxt1=(EditText)findViewById(R.id.editText1);
// btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub HERE IS code for BT on button
btAdapter=BluetoothAdapter.getDefaultAdapter();
if(btAdapter.isEnabled()){
String address = btAdapter.getRemoteDevice(address);
String address = btAdapter.getAddress();
String name = btAdapter.getName();
String statusBT = name +" : "+address;
BluetoothDevice mmDevice = "";
etxt1.setText(statusBT);
// Pairing
Set pairedDevices = btAdapter
.getBondedDevices();
if (pairedDevices.size() > 0)
{
for (BluetoothDevice device : pairedDevices)
{
if (device.getName().equals("HC-05")) {
{
mmDevice = device;
break;
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID
BluetoothSocket mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
OutputStream mmOutputStream = mmSocket.getOutputStream();
InputStream mmInputStream = mmSocket.getInputStream();
// Pairing end
}
}
}
}
// else{
// etxt1.setText("BT Adapter not on");
// String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED;
// String actionRequestEnabled = BluetoothAdapter.ACTION_REQUEST_ENABLE;
// IntentFilter filter = new IntentFilter(actionStateChanged);
// registerREceiver(bluetoothState, filter);
// startActivityForResult(new Intent(actionRequestEnabled),0);
}}});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub HERE IS code for BT off button
// btAdapter.disable(); // Every thing crashes with these 3 lines
// btn2.setVisibility(View.GONE);
// etxt1.setText("BTooth is off");
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Hi Les. I emailed you some code. But I also published it above.
DeleteHi Craig,
ReplyDeleteIt complies and uploads but the app errors.
12-09 10:44:26.330: E/AndroidRuntime(13997): FATAL EXCEPTION: main
12-09 10:44:26.330: E/AndroidRuntime(13997): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.lw_blue_2/com.example.lw_blue_2.BluetoothTest}: java.lang.ClassNotFoundException: Didn't find class "com.example.lw_blue_2.BluetoothTest" on path: /data/app/com.example.lw_blue_2-2.apk
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2299)
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.app.ActivityThread.access$700(ActivityThread.java:154)
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.os.Handler.dispatchMessage(Handler.java:99)
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.os.Looper.loop(Looper.java:137)
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.app.ActivityThread.main(ActivityThread.java:5297)
12-09 10:44:26.330: E/AndroidRuntime(13997): at java.lang.reflect.Method.invokeNative(Native Method)
12-09 10:44:26.330: E/AndroidRuntime(13997): at java.lang.reflect.Method.invoke(Method.java:511)
12-09 10:44:26.330: E/AndroidRuntime(13997): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
12-09 10:44:26.330: E/AndroidRuntime(13997): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
12-09 10:44:26.330: E/AndroidRuntime(13997): at dalvik.system.NativeStart.main(Native Method)
12-09 10:44:26.330: E/AndroidRuntime(13997): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.lw_blue_2.BluetoothTest" on path: /data/app/com.example.lw_blue_2-2.apk
12-09 10:44:26.330: E/AndroidRuntime(13997): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:65)
12-09 10:44:26.330: E/AndroidRuntime(13997): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
12-09 10:44:26.330: E/AndroidRuntime(13997): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.app.Instrumentation.newActivity(Instrumentation.java:1071)
12-09 10:44:26.330: E/AndroidRuntime(13997): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2166)
12-09 10:44:26.330: E/AndroidRuntime(13997): ... 11 more
Did not get your direct email last time best use les at wilkipedia.net
If you ever come out to Thailand I owe you a beer.
Many Thanks Les
I have renamed in xml file as per my project name:-
ReplyDeleteHello Again, for some reason my emails went to
Deletewikipedia.net.net
I tested the code I posted earlier and it connects to BT and sends data with arduino using my Google Nexus 7 tablet.
Did you still get all those error messages when you changed the XML ?
Cheers
Craig
PS Thanks for the offer of a beer :)
We all need help starting out. I got lots of help and still do. I find Stack Overflow particularly good for java, except they can be shirty with newbies. It's not as friendly as the Arduino forum.
Hi Craig,
ReplyDeleteSome progress, I have the app now not crashing on my galaxy, it took some twiddling to the manifest file, I noticed that my eclipse generated raw manifest file was differing from yours so I experimented. At foot I will include my version. The main java file is exactly as you provided, other than I changed my bluetooth device name.
The app sadly does not send any characters from galaxy to the arduino.
I presume there is no more one needs to do when using the app other than: click Open, enter an ascii string and click Send. Sadly nothing appears at the other end.
I know also that another android / arduino testing app called ArduDroid works fine for me and it sends ascii characters between galaxy and arduino ok. Which confirms that pairing, modems, arduino can all talk together ok. ( ArduDroid will not make his android code public sadly, it is quite fun to play with )
My diagnosis now: It appears most probable that I still have a problem on the android side, it could also be possible the arduino is not displaying what is being sent, but I feel that is less likely.
I have one idea to eliminate fault on arduino side and that is to loan a friends oscilloscope and monitor the btooth modem Tx pin to see if rs232 is appearing.
I will do this but it will take a while to arrange.
Else if you have any suggestions, gratefully received.
Thanks
Les
Manifest file below
ReplyDeleteHi Craig,
ReplyDeleteSo that you know what I am aiming at with my project.
I am a keen amateur photographer. My photo gallery is at wilkipedia.net
I enjoy taking macro photographs and use a technique which is called focus stitching, this involves taking say 30 photographs of an insect, with each shot moved slightly along its body, so as to have the whole insect in focus by joining all the shots together later in some focus stitching software.
To automate this process I have built an arduino project which controls a stepper motor which moves the camera millimeters at a time along a rail and will automatically take my shots for me once it is setup, the shots are then better as they are very equidistant if it is done by a stepper motor.
I now have the whole Arduino side working ok and the icing on the cake is to have mobile phone control of the stepper rail.
Your assistance has been invaluable in saving time and making progress, I hope my brief summary explains what I am up to.
Thanks
Hi Craig,
ReplyDeleteHave just established that when I press open on the android app it does not switch on Bluetooth services on my samsung phone.
Looking at this bit of code:
void findBT()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null)
{
myLabel.setText("No bluetooth adapter available");
}
if (!mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0)
{
for (BluetoothDevice device : pairedDevices)
{
if (device.getName().equals("HC-05"))// change accordingly
{
mmDevice = device;
break;
}
}
}
myLabel.setText("Bluetooth Device Found");
}
I am surprised that I never see message
myLabel.setText("No bluetooth adapter available");
nor
myLabel.setText("Bluetooth Device Found");
Rgds
Les
Hi Les,
DeleteI send an email about a correction to the code above and some arduino code. Corrections and Arduino code also posted on this page. Android Java correction was put conditional into openBT() method:
void openBT() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
if (mmDevice != null) //conditional only do if NOT null
{
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
myLabel.setText("Bluetooth Opened");
}// end of !null
Hi Craig,
ReplyDeleteI haven't received your email please can you send again to les at wilkipedia.net
Thanks
Hi Craig,
ReplyDeleteAfter adding these lines there is no difference.
It doesn't report "Bluetooth opened"
Also Bluetooth never gets turned on on the Galaxy phone, if I force and I enable BTooth to be on, it still makes no difference.
These lines were added
void openBT() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
if (mmDevice != null) //conditional only do if NOT null
{
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
myLabel.setText("Bluetooth Opened");
}// end of !null
Rgds
Les
Hi Les, I did this:
Delete1. Start with no BT app running on phone
2. turned BT off on my Nexus
3. Run app on Eclipse ADB USB bridge
4. App running on phone
5. press open, system message = "app wants to turn on BT deny / allow"
6. allow
7. bt app message = "bt device found"
8. press open again
9. app message bt opened
10. type a byte, press send, app says "data sent", data is printed on arduino terminal.
and it worked. Please try that sequence of events.
Cheers Craig
Hi les, can't send to les@wikipedia.net don'y know why.
DeletePostMaster says:
SMTP error from remote server after RCPT command:
host mchenry.wikimedia.org[208.80.152.186]:
550 Address les@wikipedia.net does not exist
cheers
Craig
les@wilkipedia.net there is an L in there my surname is Wilk so I kyboshed a known brand.
ReplyDeleteThanks