I'm working on a project which consists of two classes. The first, MainActivity.java, deals with sending a single char over a bluetooth connection. The second, SmsReceiver.java, is a broadcast reciver for detecting incoming sms messages. When SmsReceiver.java detects an incoming message it should call the method turnLedOn, which resides in the bluetooth class.
I've tested both of them and they work. Then I tried connecting them by calling MainActivity.turnLedOn(context); in the onReceive method of the broadcast receiver, but it didn't work.
Does anybody know why and what should be done to remedy this? Below is the code of the whole project.
Thank you in advance.
MainActivity.java
package com.example.bluetooth;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
//You first have to connect with your android phone to the arduino bt module.
BluetoothAdapter mBluetoothAdapter = null;
ConnectThread mConnectThread = null;
BluetoothDevice mDevice = null;
public static ConnectedThread mConnectedThread = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("1".getBytes());
}
});
final Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("0".getBytes());
}
});
BluetoothDevice mDevice = null;
//Check if phone supports bluetooth
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
Toast.makeText(this, "BT supported", Toast.LENGTH_SHORT).show();
Log.e("BLUETOOTH", "BT supported");
// Check if bluetooth is enabled. If not, enable it.
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this, "BT disabled", Toast.LENGTH_SHORT).show();
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
Toast.makeText(this, "BT enabled", Toast.LENGTH_SHORT).show();
Log.e("BLUETOOTH", "BT enabled");
// Chech which device we connected with, at the beginning
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
Toast.makeText(this, "Paired with a BT device", Toast.LENGTH_SHORT).show();
Log.e("BLUETOOTH", "paired with a BT device");
for (BluetoothDevice device : pairedDevices) {
Toast.makeText(this, device.getName() + " " + device.getAddress(), Toast.LENGTH_SHORT).show();
mDevice = device;
}
}
// Source 7 - Creating the connection thread
mConnectThread = new ConnectThread(mDevice);
mConnectThread.start();
}
public static void turnLedOn(Context context){
mConnectedThread.write("1".getBytes());
}
public static void turnLedOff(Context context){
mConnectedThread.write("0".getBytes());
}
#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;
}
//Thread which creates a connection between arduino and phone
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
mBluetoothAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
//Source 10 - create the data transfer thread
//Manage connection
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
// end of connection thread
//Thread for sending and receiving messages
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int begin = 0;
int bytes = 0;
while (true) {
try {
bytes += mmInStream.read(buffer, bytes, buffer.length
- bytes);
for (int i = begin; i < bytes; i++) {
if (buffer[i] == "#".getBytes()[0]) {
mHandler.obtainMessage(1, begin, i, buffer)
.sendToTarget();
begin = i + 1;
if (i == bytes - 1) {
bytes = 0;
begin = 0;
}
}
}
} catch (IOException e) {
break;
}
}
}
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
//End of thread for sending and receiving
//Source 9 - handler for sending
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
byte[] writeBuf = (byte[]) msg.obj;
int begin = (int) msg.arg1;
int end = (int) msg.arg2;
switch (msg.what) {
case 1:
String writeMessage = new String(writeBuf);
writeMessage = writeMessage.substring(begin, end);
break;
}
}
};
}
SmsReceiver.java
package com.example.bluetooth;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
public class SmsReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String messageReceived = "";
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++)
{
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
messageReceived += msgs[i].getMessageBody().toString();
messageReceived += "\n";
}
//---display the new SMS message---
Toast.makeText(context, messageReceived, Toast.LENGTH_SHORT).show();
MainActivity.turnLedOn(context);
// Get the Sender Phone Number
String senderPhoneNumber=msgs[0].getOriginatingAddress ();
}
}
}
MainActivity layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<Button
android:id="#+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_below="#+id/textView1"
android:layout_marginTop="34dp"
android:text="On" />
<Button
android:id="#+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/button1"
android:layout_below="#+id/button1"
android:layout_marginTop="68dp"
android:text="Off" />
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluetooth"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name=
"android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<activity
android:name="com.example.bluetooth.MainActivity"
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-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
</manifest>
Edit: Registered the broadcast receiver in the manifest as #donison24x7 suggested.
Edit2: Sorry about this. Also added the RECEIVE_SMS permission in the manifest. It works now.
You havn't registered the Broadcast receiver 'SmsReceiver.java' in manifest.
Register it like this.....
<receiver
android:name=".SmsReceiver" >
<intent-filter>
<action android:name="your.Action.name" />
</intent-filter>
</receiver>
One possible solution is to use LocalBroadcastManager to communicate between your receiver class and your activity class:
Fire up an Intent in your receiver class in onReceive() with:
Intent i = new Intent("NameYourIntentHere");
LocalBroadcastManager.getInstance(context).sendBroadcast(i);
Get the LocalBroadcast intent in your Activity class:
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Do your stuff here
}
};
And register your LocalBroadcast receiver in your activity class so it gets notified:
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver,
new IntentFilter("NameYourIntentHere"));
}
Related
I'm new in Bluetooth
I want to connect an already paired Bluetooth device and communicate with that device.
For this I use the following code.But it's not properly working
The code Finds the device but can't connect with that device.How to correct my code.
MainActivity.java
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Button;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends Activity
{
TextView myLabel;
EditText myTextbox;
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
int counter;
volatile boolean stopWorker;
private static final UUID MY_UUID = UUID.fromString("0000110E-0000-1000-8000-00805F9B34FB");
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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);
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);
}
//Open 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()
{
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice device : pairedDevices)
{
if(device.getName().equals("BTdevice"))//name of the BT Device I want to connet
{
mmDevice = device;
myLabel.setText("Bluetooth Device Found");
break;
}
}
}
}
void openBT() throws IOException
{
mmSocket = mmDevice.createInsecureRfcommSocketToServiceRecord(MY_UUID);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
myLabel.setText("Bluetooth Opened");
}
void beginListenForData()
{
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
int bytesAvailable = mmInputStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
myLabel.setText(data);
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
stopWorker = true;
}
}
}
});
workerThread.start();
}
void sendData() throws IOException
{
String msg = myTextbox.getText().toString();
msg += "\n";
mmOutputStream.write(msg.getBytes());
myLabel.setText("Data Sent");
}
void closeBT() throws IOException
{
stopWorker = true;
mmOutputStream.close();
mmInputStream.close();
mmSocket.close();
myLabel.setText("Bluetooth Closed");
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:ignore="TextFields,HardcodedText" >
<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:layout_below="#id/label"
android:background="#android:drawable/editbox_background" />
<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:layout_marginTop="48dp"
android:layout_marginRight="24dp"
android:text="Open" />
<Button
android:id="#+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#id/open"
android:layout_marginTop="7dp"
android:layout_marginRight="27dp"
android:layout_toLeftOf="#id/open"
android:text="Send" />
<Button
android:id="#+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#id/send"
android:layout_alignParentStart="true"
android:layout_marginStart="18dp"
android:layout_marginTop="2dp"
android:text="Close"
android:layout_alignParentLeft="true"
android:layout_marginLeft="18dp" />
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tosil.myapplication">
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
And also I would like to Know about which Bluetooth profile is used in this code and where it is mentioned.
I am currently developing an application that is going to connect to a device via bluetooth and receive data from it. I have 2 main pages for the bluetooth in my app (as you can see in the image below), the first one is "connect to TANGO" and the second one is "Translate". The first button "connect to TANGO" is responsible for finding devices and connecting with them. and the second one "Translate" is the page responsible for receiving the data from the device and viewing it. But for some reason when i open my application and click on either of them, it just takes me back to the main menu. Below is the code for both pages, if someone could please help out and point out the error in the code.
Here's the code for "connect to TANGO" button
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import java.util.UUID;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;
public class connection extends AppCompatActivity {
Button b1,b2,b3,b4;
private BluetoothAdapter BA;
private Set<BluetoothDevice>pairedDevices;
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connection);
b1=(Button)findViewById(R.id.button);
b2=(Button)findViewById(R.id.button2);
b3=(Button)findViewById(R.id.button3);
b4=(Button)findViewById(R.id.button4);
BA = BluetoothAdapter.getDefaultAdapter();
lv = (ListView)findViewById(R.id.listView);
}
public void on(View v){
if (!BA.isEnabled()) {
Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOn, 0);
Toast.makeText(getApplicationContext(), "Turned on",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Already on", Toast.LENGTH_LONG).show();
}
}
public void off(View v){
if (BA.disable());
Toast.makeText(getApplicationContext(), "Turned off" ,Toast.LENGTH_LONG).show();
}
public void visible(View v){
Intent getVisible = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(getVisible, 0);
}
public void list(View v){
pairedDevices = BA.getBondedDevices();
ArrayList list = new ArrayList();
for(BluetoothDevice bt : pairedDevices) list.add(bt.getName());
Toast.makeText(getApplicationContext(), "Showing Paired Devices",Toast.LENGTH_SHORT).show();
final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
}
public class RandomStringUUID {
public void main(String[] args) {
// Creating a random UUID (Universally unique identifier).
UUID uuid = UUID.randomUUID();
String randomUUIDString = uuid.toString();
System.out.println("Random UUID String = " + randomUUIDString);
System.out.println("UUID version = " + uuid.version());
System.out.println("UUID variant = " + uuid.variant());
}
}
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public connection(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(UUID.randomUUID());
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
BA.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);
}
private void manageConnectedSocket(BluetoothSocket mmSocket) {
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
public BluetoothDevice getMmDevice() {
return mmDevice;
}
}
And that's the code for the "Translate" button
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class display extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display);
}
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private android.os.Handler mHandler;
public display (BluetoothSocket socket, Handler mHandler) {
mmSocket = socket;
this.mHandler = mHandler;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
int MESSAGE_READ = 0;
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
menu
The Manifest code
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Activity2" />
<activity android:name=".connection" />
<activity android:name=".display" />
<activity android:name=".settings" />
<activity android:name=".help" />
<activity android:name=".contact"></activity>
</application>
I seem to have the same problem but just when receiving bluetooth data. Your problem seems to be having random UUIDs instead f a fixed one. The code I use is as follows:
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("xxxx-Name of your Device"))
{
mmDevice = device;
break;
}
}
}
myLabel.setText("Bluetooth Device Found");
}
void openBT() throws IOException
{
UUID uuid = UUID.fromString("94f39d29-7d6d-437d-973b-fba39e49d4ee"); //Standard SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
myLabel.setText("Bluetooth Opened");
}
This is just a portion of a code I am using
I followed a Bluetooth tutorial video on how to create a connection using my app with other Bluetooth devices.
However, I am unable to connect to the devices directly on the app itself. I was expecting the code to allow me to do something like "Connecting..." once I tap on the device name I want to engage a connection with.
Below is my Bluetooth code:
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.internal.widget.AdapterViewCompat;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
//import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class Bluetooth extends Activity implements AdapterView.OnItemClickListener {
ArrayAdapter<String> listAdapterBt;
ListView listViewBt;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
IntentFilter filter;
BroadcastReceiver receiver;
//String tag = "debugging";
Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg){
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
//do something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
Toast.makeText(getApplicationContext(), "CONNECT", Toast.LENGTH_SHORT).show();
String s = "successfully connected";
connectedThread.write(s.getBytes());
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])msg.obj;
String string = new String(readBuf);
Toast.makeText(getApplicationContext(), "CONNECT", Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
init(); //initiate Bluetooth
if (btAdapter == null){
Toast.makeText(getApplicationContext(), "No bluetooth detected",Toast.LENGTH_SHORT).show();
finish();
}
else{
if (!btAdapter.isEnabled()){
turnOnBT();
}
getPairedDevices();
startDiscovery();
}
}
private void startDiscovery() {
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
}
private void turnOnBT() {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private void getPairedDevices() {
devicesArray = btAdapter.getBondedDevices();
if (devicesArray.size() > 0){
//add devices in array to list array
for(BluetoothDevice device:devicesArray){
pairedDevices.add(device.getName());
}
}
}
private void init() {
listViewBt = (ListView)findViewById(R.id.listViewBt);
listViewBt.setOnItemClickListener(this);
listAdapterBt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
listViewBt.setAdapter(listAdapterBt);
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(device);
String s = "";
for (int a = 0; a < pairedDevices.size(); a++) {
if (device.getName().equals(pairedDevices.get(a))) {
//append
s = "Paired";
break;
}
}
// matt-hp (paired)
listAdapterBt.add(device.getName()+" ("+s+") "+"\n"+device.getAddress());
}
else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
//run some code
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
//run some code
}
else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
if (btAdapter.getState() == btAdapter.STATE_OFF){
turnOnBT();
}
}
}
};
registerReceiver(receiver, filter);
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
protected void onPause(){
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
finish();
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(btAdapter.isDiscovering()){
btAdapter.cancelDiscovery();
}
if (listAdapterBt.getItem(position).contains("Paired")){
BluetoothDevice selectedDevice = devices.get(position);
ConnectThread connect = new ConnectThread(selectedDevice);
connect.start();
Toast.makeText(getApplicationContext(), "device is paired", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "device is not paired", Toast.LENGTH_SHORT).show();
}
}
private class ConnectThread extends Thread {
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;
}
public void run() {
// Cancel discovery because it will slow down the connection
btAdapter.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)
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
buffer = new byte[1024];
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
}
Below is my bluetooth.xml code:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.mdpgrp10.androidmobilecontrollermodule.Bluetooth">
<item android:id="#+id/action_settings" android:title="#string/action_settings"
android:orderInCategory="100" app:showAsAction="never" />
</menu>
Just hoping for any help in any way. Much appreciated!
I'm trying to make an application that is using bluetooth.It's very simple but I'm stuck at connecting devices.
So far I've made 2 listviews, one is displaying paired devices and the other found devices.I dont understand how sockets work and how to make the device server or a client.
Can someone please explain me that or at least tell me what to do with the code I already made(copied).
I've gone through all the tutorials I could find and I still dont understand it.The bluetooth chat example is very confusing, I'm a beginner in android programming and didn't really study much java.
This is the code:
public class ConnectThread extends Thread{
BluetoothDevice device;
private BluetoothSocket socket;
ConnectThread(){
connect(device, MY_UUID);
}
public boolean connect(BluetoothDevice bTDevice, UUID mUUID) {
BluetoothSocket temp = null;
try {
temp = bTDevice.createRfcommSocketToServiceRecord(mUUID);
} catch (IOException e) {
Log.d("CONNECTTHREAD","Could not create RFCOMM socket:" + e.toString());
return false;
}
try {
socket.connect();
} catch(IOException e) {
Log.d("CONNECTTHREAD","Could not connect: " + e.toString());
try {
socket.close();
} catch(IOException close) {
Log.d("CONNECTTHREAD", "Could not close connection:" + e.toString());
return false;
}
}
return true;
}
public boolean cancel() {
try {
socket.close();
} catch(IOException e) {
Log.d("CONNECTTHREAD","Could not close connection:" + e.toString());
return false;
}
return true;
}
}
private class AcceptThread extends Thread {
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 = bluetooth.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
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)
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}}
This is the xml:
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="1"
android:baselineAligned="false">
<ListView
android:layout_width="170dp"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:background="#drawable/lviewbg"
android:id="#+id/paired_devies">
</ListView>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="fill_horizontal"
android:background="#drawable/lviewbg"
android:id="#+id/new_devices">
</ListView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<Button
android:id="#+id/discover"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#aa0000ff"
android:text="#string/disc"
style="?android:attr/buttonBarButtonStyle"
/>
<Button
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#aa0000ff"
android:text="#string/discoverable"
android:onClick="makeDiscoverable"
style="?android:attr/buttonBarButtonStyle"
/>
</LinearLayout>
</LinearLayout>
This is rest of the code if you need it:
package com.example.user.broj;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.util.Set;
import java.util.UUID;
public class BluetoothDevices extends AppCompatActivity{
private static final String TAG = "DeviceListActivity";
private static final boolean D = true;
BluetoothDevice device;
static int REQUEST_ENABLE_BT = 1;
static int DISCOVERABLE_BT_REQUEST_CODE = 1;
static int DISCOVERABLE_DURATION = 120;
public static String EXTRA_DEVICE_ADDRESS = "device_address";
private BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
ArrayAdapter<String> mPairedDevicesArrayAdapter;
private ArrayAdapter<String> mNewDevicesArrayAdapter;
//This is used for connecting devices
static final String NAME = "BluetoothGame";
static final UUID MY_UUID = UUID.fromString("ae19c8fa-9b60-11e5-8994-feff819cdc9f");
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start);
Button scanButton = (Button) findViewById(R.id.discover);
scanButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
doDiscovery();
view.setClickable(false);
}
});
//enabling bluetooth
if(!bluetooth.isEnabled()){
Intent btIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(btIntent, REQUEST_ENABLE_BT);
}
//arrayadapters for paired and new devices list views
mPairedDevicesArrayAdapter = new ArrayAdapter<>(this, R.layout.device_name);
mNewDevicesArrayAdapter = new ArrayAdapter<>(this, R.layout.device_name);
//listview for paired devices
ListView deviceList = (ListView) findViewById(R.id.paired_devies);
deviceList.setAdapter(mPairedDevicesArrayAdapter);
deviceList.setOnItemClickListener(mDeviceClickListener);
//listview for new devices
ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
newDevicesListView.setOnItemClickListener(mDeviceClickListener);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
bluetooth = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = bluetooth.getBondedDevices();
if (pairedDevices.size() > 0) {
//findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
String noDevices = getResources().getText(R.string.none_paired).toString();
mPairedDevicesArrayAdapter.add(noDevices);
}
}
//button onClick for making the device discoverable
public void makeDiscoverable(View view) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERABLE_DURATION);
startActivityForResult(discoverableIntent, DISCOVERABLE_BT_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == DISCOVERABLE_BT_REQUEST_CODE){
if (resultCode == DISCOVERABLE_DURATION){
Toast.makeText(getApplicationContext(), "Your device is now discoverable by other devices for " +
DISCOVERABLE_DURATION + " seconds",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Fail to enable discoverability on your device.",
Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
// Make sure we're not doing discovery anymore
if (bluetooth != null) {
bluetooth.cancelDiscovery();
}
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver);
}
private void doDiscovery() {
if (D) Log.d(TAG, "doDiscovery()");
// Indicate scanning in the title
setProgressBarIndeterminateVisibility(true);
setTitle(R.string.scanning);
// Turn on sub-title for new devices
// findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
// If we're already discovering, stop it
if (bluetooth.isDiscovering()) {
bluetooth.cancelDiscovery();
}
// Request discover from BluetoothAdapter
bluetooth.startDiscovery();
}
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
// Cancel discovery because it's costly and we're about to connect
bluetooth.cancelDiscovery();
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
// Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
};
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Button scanButton = (Button) findViewById(R.id.discover);
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setProgressBarIndeterminateVisibility(false);
setTitle(R.string.select_device);
scanButton.setClickable(true);
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = getResources().getText(R.string.none_found).toString();
mNewDevicesArrayAdapter.add(noDevices);
}
}
}
};
}
Async class for connection via Bluetoothsocket
UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
InputStream is1;
OutputStream os1;
BluetoothAdapter bluetoothAdapter = null;
BluetoothSocket socket = null;
class UserInterface extends Thread {
BluetoothDevice bdDevice;
public UserInterface() {
bdDevice = your pair device;
}
#Override
public void run() {
Looper.prepare();
try {
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(bdDevice.getAddress());
if (socket != null && socket.isConnected()) {
is1.close();
os1.close();
socket.close();
}
try {
socket = device.createInsecureRfcommSocketToServiceRecord(SERIAL_UUID);
} catch (Exception e) {
Log.e("", "Error creating socket");
}
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
try {
socket.connect();
Log.e("", "Connected Rfcomm");
} catch (IOException e) {
Log.e("", e.getMessage());
try {
Log.e("", "trying fallback...");
socket = device.createInsecureRfcommSocketToServiceRecord(SERIAL_UUID);
socket.connect();
Log.e("", "Connected serial UDID");
} catch (Exception e2) {
Log.e("", "Couldn't establish Bluetooth connection!");
}
}
if (socket.isConnected()) {
// dismiss Progress Dialog
os1 = socket.getOutputStream();
is1 = socket.getInputStream();
Log.i("TAG", "Socket Connected");
//code after socket connect
} else {
// dismiss Progress Dialog
showProgressDialogToast("Please restart bluetooth Device");
closeSocket();
Log.i("TAG", "Socket Disconnected");
}
Log.i("Log", "Removed" + bdDevice.getName());
} catch (Exception e) {
// TODO Auto-generated catch block
Log.i("Log", "Under Catch of thread");
e.printStackTrace();
// dismiss Progress Dialog
}
}
}
use Thread class like this
UserInterface userInterface = new UserInterface();
userInterface.start();
Basically refer the tutorial given by android developers on their site.
In every connectivity there should be one server and one client. The server will just run the accept thread and the client will run the connect thread. Once the accept thread started, you need to connect from the client side with the proper device name.
I am developing an android application which transmits queries to a bluetooth device and retrieves data from it. In the app, a connection is established by tapping on an available device in the upper part of the screen, and then there's a button on the bottom half which triggers the sending of the query and the text box next to it displays the data.
I am able to successfully connect to the device and fetch data from it once, but when I hit the query button the second time around, the app crashes.
In the code I start the ConnectedThread thread once I hit the button, and then at the end of the thread code a handler is called which then displays the text on the screen. The second time I hit the button my code tries to start the same thread again - this causes the error. I have been trying out to a way to stop the connectedThread once the received data is received, this way I can start and close the connectedThread for every transmit-receive.
Can you please suggest a solution to the issue or a way to improvise the code structure. Any help will be appreciated.
Thanks
package com.test.bluetooth;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class Main_Activity extends Activity implements OnItemClickListener {
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
ArrayAdapter<String> listAdapter;
ListView listView;
Button mConnect;
TextView mResponse;
IntentFilter filter;
BroadcastReceiver receiver;
String tag = "Debug";
Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.i(tag, "Handler starts");
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
final ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
Toast.makeText(getApplicationContext(), "Connected", 0).show();
mConnect.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
//Log.v("EditText", mCommand.getText().toString());
//String Command = mCommand.getText().toString();
byte[] inputs = {0x30, 0x31, 0x30, 0x44, 0x0d, 0x0a};
connectedThread.write(inputs);
Log.i(tag, "sent ");
connectedThread.start();
Log.i(tag, "sent 2");
}
});
break;
case MESSAGE_READ:
byte[] TxBuf = (byte[])msg.obj;
String string = new String(TxBuf);
Log.d("ReceiverValue", string);
mResponse.setText(string);
break;
}
}
};
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
if(btAdapter.isDiscovering()){
btAdapter.cancelDiscovery();
}
if(listAdapter.getItem(arg2).contains("Paired")){
BluetoothDevice selectedDevice = devices.get(arg2);
ConnectThread connect = new ConnectThread(selectedDevice);
connect.start();
Log.i(tag, "in click listener");
}
else{
Toast.makeText(getApplicationContext(), "device is not paired", 0).show();
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
if(btAdapter==null){
Toast.makeText(getApplicationContext(), "No bluetooth detected", 0).show();
finish();
}
else{
if(!btAdapter.isEnabled()){
turnOn();
}
getPairedDevices();
startDiscovery();
}
}
private void startDiscovery() {
// TODO Auto-generated method stub
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
}
private void turnOn() {
// TODO Auto-generated method stub
Intent intent =new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private void getPairedDevices() {
// TODO Auto-generated method stub
devicesArray = btAdapter.getBondedDevices();
if(devicesArray.size()>0){
for(BluetoothDevice device:devicesArray){
pairedDevices.add(device.getName());
}
}
}
private void init() {
// TODO Auto-generated method stub
listView=(ListView)findViewById(R.id.listView);
mConnect=(Button)findViewById(R.id.bConnectNew);
//mCommand=(EditText)findViewById(R.id.etCommand);
mResponse=(TextView)findViewById(R.id.tvResponse);
listView.setOnItemClickListener(this);
listAdapter= new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
listView.setAdapter(listAdapter);
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(device);
String s = "";
for(int a = 0; a < pairedDevices.size(); a++){
if(device.getName().equals(pairedDevices.get(a))){
//append
s = "(Paired)";
break;
}
}
listAdapter.add(device.getName()+" "+s+" "+"\n"+device.getAddress());
}
else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
}
else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
if(btAdapter.getState() == btAdapter.STATE_OFF){
turnOn();
}
}
}
};
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
finish();
}
}
private class ConnectThread extends Thread {
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;
Log.i(tag, "construct");
// 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) {
Log.i(tag, "get socket failed");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
btAdapter.cancelDiscovery();
Log.i(tag, "connect - run");
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.i(tag, "connect - succeeded");
} catch (IOException connectException) { Log.i(tag, "connect failed");
// 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)
mHandler.obtainMessage(Main_Activity.SUCCESS_CONNECT, mmSocket).sendToTarget();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
buffer = new byte[1024];
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(Main_Activity.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
}
The XML layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Paired Devices"
android:id="#+id/tvPD"
/>
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="100dip"
android:layout_above="#+id/Border"
android:layout_below="#+id/tvPD" >
</ListView>
<Button
android:id="#+id/bConnectNew"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/tvResponse"
android:layout_alignBottom="#+id/tvResponse"
android:layout_alignParentLeft="true"
android:layout_marginLeft="45dp"
android:text="Send" />
<TextView
android:id="#+id/tvResponse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="188dp"
android:layout_marginRight="26dp"
android:text="Response displayed here" />
<View
android:id="#+id/Border"
android:layout_width="wrap_content"
android:layout_height="3dip"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_weight="10"
android:background="#android:color/black" />
</RelativeLayout>
enter code here