I am trying to create an android app to communicate with an Arduino Uno R3 using a HC-05 Bluetooth Transceiver. When I try to use getOutputStream() on my open socket in openBT() it returns null.
Here is my code:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.bluetooth.*;
import android.content.Intent;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.io.IOException;
import java.io.DataOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
public static BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private static final int REQUEST_ENABLE_BT = 1;
private ArrayAdapter<String> mArrayAdapter;
BluetoothDevice mmDevice;
BluetoothSocket mmSocket;
OutputStream mmOutputStream;
InputStream mmInputStream;
DataOutputStream out;
String LEDOn = "zero";
String msg = "zero";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//mArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
final TextView mTextView = (TextView) this.findViewById(R.id.myLabel);
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("HC-05")) {
mmDevice = device;
mTextView.setText("Connected to " + mmDevice.toString());
}
// Add the name and address to an array adapter to show in a ListView
// mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
try {
openBT();
} catch (IOException e) {
}
} else {
discover();
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (LEDOn == "zero") {
LEDOn = "one";
} else {
LEDOn = "zero";
}
try {
sendData();
} catch (IOException e) {
}
}
});
}
public void discover() {
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
mBluetoothAdapter.cancelDiscovery();
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
}
void openBT() throws IOException {
final UUID MY_UUID = UUID.fromString("4eb3ab89-05e4-4180-b530-964c7ed2d83e");
mmSocket = mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
mmSocket.connect();
try {
if (mmSocket.isConnected()) {
mmOutputStream = mmSocket.getOutputStream();
} else {
System.out.println("mmOutputStream = " + mmOutputStream.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
mmInputStream = mmSocket.getInputStream();
}
void sendData() throws IOException {
try {
msg = LEDOn;
mmOutputStream.write(msg.getBytes());
} catch (NullPointerException e) {
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
On my Arduino side the code looks like this:
#include <SoftwareSerial.h>// import the serial library
SoftwareSerial bluetooth(2, 3); // RX, TX
int ledpin = 13; // led on D13 will show blink on / off
char BluetoothData; // the data given from Computer
void setup() {
// put your setup code here, to run once:
bluetooth.begin(9600);
bluetooth.println("Bluetooth On please press 1 or 0 blink LED ..");
pinMode(ledpin, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
if (bluetooth.available()) {
BluetoothData = bluetooth.read();
if (BluetoothData == 'one') { // if number 1 pressed ....
digitalWrite(ledpin, 1);
bluetooth.println("LED On D13 ON ! ");
}
if (BluetoothData == 'zero') { // if number 0 pressed ....
digitalWrite(ledpin, 0);
bluetooth.println("LED On D13 Off ! ");
}
}
delay(100);// prepare for next data ...
}
Any help at all is appreciated. I have been scouring this site and google for hours trying to find answers.
Related
I am creating an Android app that allows me to control a device connected to Arduino using Bluetooth, with Android 4.4.2, Arduino Uno and HC-05 Module.
Right now I'm finding serious difficulties to print data in the Arduino serial (in order to verify if it's really working). I tried everything I have found in this or other forums related to this topic.
For the moment, I have been able to detect the devices, pair with them and create the Socket and the OutputStream, but for some reason the data doesn't show up.
The code is 2 basic Activities and their layouts (Android) and the Arduino code:
Image of how it shows the available devices.
Image of how now that device is paired with our Android Device.
GetPaired.java:
Basically gets the available devices, show them in a custom ListView, allows you to pair/unpair with them and after you get the device paired, you go to the ConnectionControl activity.
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Set;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
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.AdapterView.OnItemClickListener;
import android.widget.Toast;
public class GetPaired extends Activity {
ListView listViewPaired;
ListView listViewDetected;
ArrayList<String> arrayListpaired;
Button buttonSearch,buttonControl;
ArrayAdapter<String> adapter, detectedAdapter;
BluetoothDevice bdDevice;
ArrayList<BluetoothDevice> arrayListPairedBluetoothDevices;
ListItemClickedonPaired listItemClickedonPaired;
BluetoothAdapter bluetoothAdapter = null;
ArrayList<BluetoothDevice> arrayListBluetoothDevices = null;
ListItemClicked listItemClicked;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth_demo);
listViewDetected = (ListView)
findViewById(R.id.listViewDetected);
listViewPaired = (ListView) findViewById(R.id.listViewPaired);
buttonSearch = (Button) findViewById(R.id.buttonSearch);
buttonControl = (Button) findViewById(R.id.buttonControl);
arrayListpaired = new ArrayList<String>();
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
arrayListPairedBluetoothDevices = new ArrayList<BluetoothDevice();
listItemClickedonPaired = new ListItemClickedonPaired();
arrayListBluetoothDevices = new ArrayList<BluetoothDevice>();
adapter = new ArrayAdapter<String>(GetPaired.this,
R.layout.custom_layout, arrayListpaired);
detectedAdapter = new ArrayAdapter<String>(GetPaired.this,
R.layout.custom_layout);
listViewDetected.setAdapter(detectedAdapter);
listItemClicked = new ListItemClicked();
detectedAdapter.notifyDataSetChanged();
listViewPaired.setAdapter(adapter);
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
//Get all the paired bluetooth devices with Android.
getPairedDevices();
listViewDetected.setOnItemClickListener(listItemClicked);
listViewPaired.setOnItemClickListener(listItemClickedonPaired);
}
private void getPairedDevices() {
Set<BluetoothDevice> pairedDevice =
bluetoothAdapter.getBondedDevices();
if (pairedDevice.size() > 0) {
for (BluetoothDevice device : pairedDevice) {
arrayListpaired.add(device.getName() + "\n" +
device.getAddress());
arrayListPairedBluetoothDevices.add(device);
break;
}
}
adapter.notifyDataSetChanged();
}
//When clicked a bluetooth device from the available list, a bond is
created between them.
class ListItemClicked implements OnItemClickListener{
#Override
public void onItemClick(AdapterView<?> parent, View view, int
position, long id) {
// TODO Auto-generated method stub
bdDevice = arrayListBluetoothDevices.get(position);
Log.i("Log", "The device : " + bdDevice.toString());
Boolean isBonded = false;
try {
isBonded = createBond(bdDevice);
if (isBonded) {
getPairedDevices();
adapter.notifyDataSetChanged();
Log.i("Log", "The bond is created: " + isBonded);
}
} catch (Exception e) {
e.printStackTrace();
}
connect(bdDevice);
}
}
//When clicked in the list of paired devices, you remove the bond and
the pairing.
class ListItemClickedonPaired implements OnItemClickListener{
#Override
public void onItemClick(AdapterView<?> parent, View view, int
position, long id) {
bdDevice = arrayListPairedBluetoothDevices.get(position);
try {
Boolean removeBonding = removeBond(bdDevice);
if (removeBonding) {
arrayListpaired.remove(position);
adapter.notifyDataSetChanged();
}
Log.i("Log", "Removed" + removeBonding);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private Boolean connect(BluetoothDevice bdDevice) {
Boolean bool = false;
try {
Log.i("Log", "service method is called ");
Class cl = Class.forName("android.bluetooth.BluetoothDevice");
Class[] par = {};
Method method = cl.getMethod("createBond", par);
bool = (Boolean) method.invoke(bdDevice);
} catch (Exception e) {
Log.i("Log", "Inside catch of serviceFromDevice Method");
e.printStackTrace();
}
return bool.booleanValue();
}
public boolean removeBond(BluetoothDevice btDevice)
throws Exception {
Class btClass =
Class.forName("android.bluetooth.BluetoothDevice");
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
public boolean createBond(BluetoothDevice btDevice)
throws Exception {
Class class1 = Class.forName("android.bluetooth.BluetoothDevice");
Method createBondMethod = class1.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
//Searches for available bluetooth devices to add them to the
Detected
List.
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
Toast.makeText(context, "ACTION_FOUND",
Toast.LENGTH_SHORT).show();
BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (arrayListBluetoothDevices.size() < 1) // this checks
if the size of bluetooth device is 0,then add the
{ // device to
the arraylist.
detectedAdapter.add(device.getName() + "\n" +
device.getAddress());
arrayListBluetoothDevices.add(device);
detectedAdapter.notifyDataSetChanged();
} else {
boolean flag = true; // flag to indicate that
particular device is already in the arlist or not
for (byte i = 0; i < arrayListBluetoothDevices.size();
i++) {
if
(device.getAddress().equals(arrayListBluetoothDevices.get(i).getAddress())
) {
flag = false;
}
}
if (flag == true) {
detectedAdapter.add(device.getName() + "\n" +
device.getAddress());
arrayListBluetoothDevices.add(device);
detectedAdapter.notifyDataSetChanged();
}
}
}
}
};
//Method that starts the search of bluetooth devices to connect with.
public void startSearching(View v) {
arrayListBluetoothDevices.clear();
Log.i("Log", "in the start searching method");
IntentFilter intentFilter = new
IntentFilter(BluetoothDevice.ACTION_FOUND);
GetPaired.this.registerReceiver(myReceiver, intentFilter);
bluetoothAdapter.startDiscovery();
}
//When you have the device paired with Android, you can go to the
next
Activity, where the proper connection is stablished.
public void onControl(View v) {
if (arrayListPairedBluetoothDevices.size() > 0) {
Log.i("Log", "There is a paired device.");
Intent sipoptent = new Intent(getApplicationContext(),
ConnectionControl.class).putExtra("Bluetooth",
arrayListPairedBluetoothDevices.get(0));
startActivity(sipoptent);
if (arrayListPairedBluetoothDevices.get(0) != null) {
} else {
}
} else {
Log.i("Log", "Not paired to a device yet.");
Toast.makeText(GetPaired.this, "Not paired to a device
yet.",
Toast.LENGTH_SHORT).show();
}
}
}
The ConnectionControl Activity:
Receives an intent with a BluetoothDevice Object, as the device we are going to connect with. Creates the BluetoothSocket, the connection Thread the OutputStream.
*In this part of the code I tried to get another UUID, but again couldn't find anything.
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
import java.util.UUID;
import java.io.OutputStream;
public class ConnectionControl extends AppCompatActivity {
Button on, off;
private BluetoothSocket btSocket = null;
private BluetoothDevice device;
private OutputStream mmOutStream =null;
// SPP UUID service - this should work for most devices
private static final UUID BTMODULEUUID = UUID.fromString("00001101-
0000-1000-8000-00805F9B34FB");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
on = (Button) findViewById(R.id.onbutton);
off = (Button) findViewById(R.id.offbutton);
device = getIntent().getExtras().getParcelable("Bluetooth");
//Bluetooth device information retrieved by an Intent.
Toast.makeText(ConnectionControl.this, device.getAddress(),
Toast.LENGTH_SHORT).show();
}
#Override
public void onResume() {
super.onResume();
try {
//Creation of the socket of the connection.
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(),"Socket connection failed.",
Toast.LENGTH_LONG).show();
}
// Establish the Bluetooth socket connection.
try {
btSocket.connect();
ConnectedThread(btSocket);
write("x");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {}
}
}
//Creates secure outgoing connecetion with BT device using UUID
private BluetoothSocket createBluetoothSocket(BluetoothDevice device)
throws IOException {
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
}
//Creates the OutputStream from the socket.
public void ConnectedThread(BluetoothSocket socket) {
OutputStream tmpOut = null;
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Connection Not
Established.", Toast.LENGTH_LONG).show();
}
Toast.makeText(getBaseContext(), "Connection Established.", Toast.LENGTH_LONG).show();
mmOutStream = tmpOut;
}
#Override
public void onPause()
{
super.onPause();
try
{
//Don't leave Bluetooth sockets open when leaving activity
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
//Transforms a String input into an array of bytes to send to the bluetooth device.
public void write(String input) {
byte[] msgBuffer = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream
} catch (IOException e) {
//if you cannot write, close the application
Toast.makeText(getBaseContext(), "Conection failed.", Toast.LENGTH_LONG).show();
}
}
public void onON(View view){
write("0");
}
public void onOFF(View view){
write("1");
}
}
And the Arduino code:
In the Arduino hardware I connected the 5V and already entered in AT mode to the Bluetooth to change its name before.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
}
void loop() { // run over and over
if (mySerial.available()) {
Serial.write(mySerial.read());
}
if (Serial.available()) {
mySerial.write(Serial.read());
}
}
What can I try next?
UPDATE:
If you have to use this code for a project feel free to use it.
I have managed to solve the issue, the Arduino code was the problem, this is the working code:
#include <SoftwareSerial.h>
SoftwareSerial BTserial(11, 10); // RX | TX
char c = ' ';
void setup()
{
Serial.begin(9600);
Serial.println("Arduino is ready");
// HC-05 default serial speed for commincation mode is 9600
BTserial.begin(9600);
}
void loop()
{
if (BTserial.available())
{
c = BTserial.read();
Serial.write(c);
}
// Keep reading from Arduino Serial Monitor and send to HC-05
if (Serial.available())
{
c = Serial.read();
BTserial.write(c);
}
}
I'm writing a program in android that comminicates with an arduino two ways. When communicating back to the android I'm using .print to write to the serial port back to the android. But what happens is that android registers two messages. If the first message is "message" the first message is "m" and the other is "essage" why is splitting the message?
Arduino code:
#include <SoftwareSerial.h>
int rx = 2;
int tx = 3;
SoftwareSerial bt(tx, rx);
int led1 = 10;
char data = 0;
bool room1on;
void setup() {
bt.begin(9600);
bool room1on = false;
pinMode(led1, OUTPUT);
}
void loop() {
if (bt.available() > 0) {
data = (char)bt.read();
if(data == '1'){
if(room1on){
digitalWrite(led1, LOW);
bt.print("room1;OFF");
}
else if(!room1on){
digitalWrite(led1, HIGH);
bt.print("room1;ON");
}
room1on = !room1on;
}
}
}
android code:
package com.example.beyu.benapp4;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.bluetooth.BluetoothSocket;
import java.io.IOException;
import java.util.Set;
import android.os.Handler;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private final BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
private final static int REQUEST_ENABLE_BT = 1;
private BluetoothDevice btDevice;
BluetoothSocket btSocket;
Handler btHandle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ba != null) {
if (!ba.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
Set<BluetoothDevice> pairedDevices = ba.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devicesUUID.randomUUID()
for (BluetoothDevice device : pairedDevices) {
if(device.getName().equals("HC-06")){
btDevice = device;
try {
btSocket = device.createInsecureRfcommSocketToServiceRecord(btDevice.getUuids()[0].getUuid());
btSocket.connect();
new ConnectedThread(btSocket).start();
}
catch (IOException e) { }
break;
}
}
}
}
btHandle = new Handler() {
public void handleMessage(android.os.Message msg) {
String m = (String) msg.obj;
//TextView tw = (TextView)findViewById(getResources().getIdentifier(textview, "id", getPackageName()));
//if(tw != null)
// tw.setText(message);
}
};
}
public class ConnectedThread extends Thread {
public ConnectedThread(BluetoothSocket socket) {
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = btSocket.getInputStream().read(buffer);
String readMessage = new String(buffer, 0, bytes);
btHandle.obtainMessage(0, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
}
protected void toogleRoomOne(View view){
try {
btSocket.getOutputStream().write('1');
}
catch (IOException e) {
e.printStackTrace();
}
}
}
When "1" is sent to the ardunio, android response like this:
Your messages come in fragmented. This is quite normal for TCP connections. You have to concatenate them together to get the original message.
For that you have to know the end of the message. One would use a message separater character for that.
You can make it yourself easy to send a newline char after every message string. For instance "lamp1;ON\n". You send a line then.
At receiving side you can wait for a \n to come in but much easier is to read a line with .readLine()
I am trying to connect the Bluetooth device (BT headphone) programmatically with my android app. The issue I am facing is in for first couple of attempts it fails to connect the device and says "Pairing Rejected". then after it connects successfully.
Here's my code:
package rockwellcollins.bluetooth_pairing_siu;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
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.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
public ServerSocket serverSocket;
public BluetoothA2dp btA2dp;
BluetoothAdapter mBluetoothAdapter;
private BluetoothSocket mSocket = null;
private UUID applicationUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public InetAddress serverAddr,serverAddrConnected;
public Socket socket,socketConnected;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() {
#Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
Log.i("oncreate","Bluetooth Service connected.\n");
btA2dp = (BluetoothA2dp) proxy;
}
#Override
public void onServiceDisconnected(int profile) {
Log.i("oncreate", "Bluetooth Service disconnected.\n");
}
}, BluetoothProfile.A2DP);
Log.i("oncreate", "going to start thread.\n");
Thread fst = new Thread(new ServerThread());
fst.start();
registerReceiver(mPairReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
}
public class ServerThread implements Runnable
{
String[] strLine;
#Override
public void run() {
try {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
serverSocket = new ServerSocket(4500);
while(true) {
Log.i("inrun","in run method");
Socket client = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line = in.readLine();
strLine = line.split(";");
Log.i("ServerThread", "Line is: " + strLine[1]);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(strLine[1]);
if(strLine[0].contains("connect")) {
pairDevice(device);
}
else if(strLine[0].contains("unpair"))
{
Log.i("run","Going to unpair device");
unpairDevice(device, strLine[2]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void pairDevice(BluetoothDevice device) {
try {
if(device.getBondState() == BluetoothDevice.BOND_NONE) {
Method method = device.getClass().getMethod("createBond", (Class[]) null);
method.invoke(device, (Object[]) null);
Log.d("pairdevice", String.valueOf(device.getBondState()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public class FinalThread implements Runnable{
String strMsg = "";
public FinalThread(String msg)
{
strMsg = msg;
}
#Override
public void run() {
try {
serverAddr = InetAddress.getByName("10.240.8.23");
socket = new Socket(serverAddr,5500);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(strMsg);
out.flush();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void unpairDevice(BluetoothDevice device, String seatInfo) {
try {
if(device.getBondState() == BluetoothDevice.BOND_BONDED) {
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
method.invoke(device, (Object[]) null);
}
Thread sThread = new Thread(new ConnectThread(seatInfo));
sThread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public class ConnectThread implements Runnable{
String strSeat = "";
public ConnectThread(String seat){
strSeat = seat;
}
#Override
public void run() {
try {
Log.i("ConnectThread","Going to connect");
serverAddr = InetAddress.getByName("10.240.8.23");
socket = new Socket(serverAddr,5500);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println("startpairconnect;" + strSeat);
out.flush();
socket.close();
Log.i("ConnectThread","Send message back for connect");
} catch (Exception e) {
e.printStackTrace();
}
}
}
private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice deviceBT = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
ShowToast("Paired");
connectA2dp(deviceBT);
} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
ShowToast("Unpaired");
} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDING){
ShowToast("Pairing rejected, trying again");
pairDevice(deviceBT);
}
}
}
};
private void connectA2dp(final BluetoothDevice btdevice) {
Method connect;
String strMessage = "";
try {
connect = BluetoothA2dp.class.getDeclaredMethod("connect", BluetoothDevice.class);
//Log.i("connecta2dp","get connect method " + connect);
} catch (NoSuchMethodException ex) {
Log.e("connectA2dp", "Unable to find connect(BluetoothDevice) method in BluetoothA2dp proxy.");
return;
}
connect.setAccessible(true);
try {
//Log.i("connecta2dp","before invoke" );
connect.invoke(btA2dp, btdevice);
if(btdevice.getBondState() == BluetoothDevice.BOND_BONDED)
strMessage = "success;" + btdevice.getAddress();
else
strMessage = "failure";
Thread fThread = new Thread(new FinalThread(strMessage));
fThread.start();
//Log.i("connecta2dp", "after invoke");
} catch (InvocationTargetException ex) {
Log.e("connectA2dp", "Unable to invoke connect(BluetoothDevice) method on proxy. " + ex.toString());
} catch (IllegalAccessException ex) {
Log.e("connectA2dp", "Illegal Access! " + ex.toString());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void ShowToast(String message)
{
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
Little explanation of the scenario which rejects the pairing for couple of times class will start a thread on it's onCreate method.Now this thread will continuously monitor the port for a incoming message and once it gets the message it'll extract the mac address of the headphones from it. Once it get the mac address it'll try to connect it programmatically where it fails for couple of attempts and then connects it successfully.
Thanks
I am implementing a simple app that sends and receives data between two devices via bluetooth.
I am following the android developer's blog's bluetoothchat example, but my application seems unable to read from the inputstream of a socket.
Writing to the socket is fine. The app does not throw an error nor update the textview as it is supposed to. Any help would be appreciated. Thank you!
Main activity.java(where list of devices are shown and selected) - probably not the errored file:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.bluetooth.*;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends ActionBarActivity {
private final static int REQUEST_ENABLE_BT = 22;
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static final String NAME = "Bluetooth!";
ListView listView;
ArrayList<BluetoothDevice> deviceList;
ArrayAdapter<String> arrayAdapter;
ScanReciever reciever;
BluetoothAdapter bluetooth_adapter;
Button onButton;
Button scanButton;
Button alreadyButton;
AcceptThread acceptThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
deviceList = new ArrayList<>();
//arrayAdapter = new ArrayAdapter<>(this, R.xml.table_item, android.R.id.text1, deviceList);
arrayAdapter = new ArrayAdapter<String>(this, R.layout.table_item);
// Set up Buttons
onButton = (Button) findViewById(R.id.onButton);
scanButton = (Button) findViewById(R.id.scanButton);
onButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
askAdapterOn();
}
});
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
scanForDevices();
}
});
// Set up listview
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
callButtons(deviceList.get(position));
}
});
// Bluetooth setup.
bluetooth_adapter = BluetoothAdapter.getDefaultAdapter();
// If device is incapable of using bluetooth:
if (bluetooth_adapter == null) {
onButton.setEnabled(false);
scanButton.setEnabled(false);
}
else if (!bluetooth_adapter.isEnabled()) { // If bluetooth is off:
//Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
onButton.setEnabled(true);
scanButton.setEnabled(false);
}
else { // Bluetooth is on and ready:
onButton.setEnabled(false);
scanButton.setEnabled(true);
alreadyButton = (Button) findViewById(R.id.alreadyButton);
alreadyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Collect current devices into a set.
Set<BluetoothDevice> pairedDevices = bluetooth_adapter.getBondedDevices();
// Pass the index of the paired device
if (pairedDevices.size() > 0) {
callButtons(pairedDevices.iterator().next()); // First element in set.
} else {
System.out.println("No paired Device!");
}
}
});
acceptThread = new AcceptThread();
acceptThread.start();
}
}
private class ScanReciever extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
System.out.println("Started");
//discovery starts, we can show progress dialog or perform other tasks
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
System.out.println("finished");
//discovery finishes, dismis progress dialog
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//bluetooth device found
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
System.out.println("FOUND: " + device.getName());
deviceList.add(device);
arrayAdapter.add(device.getName()+" - Click to pair");
arrayAdapter.notifyDataSetChanged();
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
System.out.println("Connected~!!!!!!!!!!!!!!");
callButtons(deviceList.get(deviceList.size()-1));
}
}
};
protected void askAdapterOn() {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
protected void scanForDevices() {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
reciever = new ScanReciever();
registerReceiver(reciever, filter);
bluetooth_adapter.startDiscovery();
}
protected void callButtons(BluetoothDevice bd) {
bluetooth_adapter.cancelDiscovery();
Intent toButton = new Intent(getApplicationContext(), buttons.class);
toButton.putExtra("selected",bd);
startActivity(toButton);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK){
if (bluetooth_adapter.isEnabled()){
onButton.setEnabled(false);
scanButton.setEnabled(true);
}
else {
onButton.setEnabled(true);
scanButton.setEnabled(false);
}
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onDestroy() {
unregisterReceiver(reciever);
super.onDestroy();
}
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_adapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
System.out.println("READY TO ACCEPT");
} 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)
//manageConnectedSocket(socket);
try {
mmServerSocket.close();
} catch (IOException e) { }
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
}
Buttons.java(where the app will initiate a connection and maintain communication) - probably the file with the error:
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.UUID;
public class buttons extends Activity {
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
BluetoothDevice selected;
BluetoothAdapter bluetoothAdapter;
TextView tv;
Button button1;
Button button2;
Button button3;
Button unpairB;
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
ConnectThread connectThread;
ConnectedThread connectedThread;
BluetoothSocket mmSocket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.buttons);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
selected = getIntent().getExtras().getParcelable("selected");
pair(selected);
connectedThread = null;
try {
connectedThread = new ConnectedThread(mmSocket);
connectedThread.start();
System.out.println("ConnectedThread started!");
} catch (Exception e) {
Log.e("unpair()", e.getMessage());
}
// Set up Buttons
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
unpairB = (Button) findViewById(R.id.unpairButton);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonPressed(1);
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonPressed(2);
}
});
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonPressed(3);
}
});
unpairB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
unpair(selected);
finish();
}
});
// Set up textview
tv = (TextView) findViewById(R.id.textView);
tv.setText("connected to: " + selected.getName());
}
protected void buttonPressed(int i) {
connectedThread.write(i);
tv.setText(Integer.toString(i));
}
private void pair(BluetoothDevice device) {
connectThread = new ConnectThread(device);
connectThread.start();
}
private void unpair(BluetoothDevice device) {
try {
Method m = device.getClass().getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
Log.e("unpair()", e.getMessage());
}
}
private class ConnectThread extends Thread {
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);
System.out.println("Socket was created in ConnectThread");
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
// bluetoothAdapter.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);
}
/** 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 bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public ConnectedThread(BluetoothSocket socket) {
this.bluetoothSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
System.out.println("Connected to " + socket.getRemoteDevice().getName());
try {
tmpIn = bluetoothSocket.getInputStream();
tmpOut = bluetoothSocket.getOutputStream();
} catch (IOException e) {
}
inputStream = tmpIn;
outputStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
if (inputStream == null) System.out.println("Inputstream is null");
else System.out.println("Inputstream is safe");
if (outputStream == null) System.out.println("outstream is null");
else System.out.println("Outputstream is safe");
while (true) {
try {
System.out.println("Blocking?");
bytes = inputStream.read(buffer);
System.out.println("NO");
handler.obtainMessage(MESSAGE_READ, bytes, -1,
buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(int i) {
try {
byte[] buffer = new byte[1024];
buffer[0] = (byte) i;
outputStream.write(buffer);
outputStream.flush();
handler.obtainMessage(MESSAGE_WRITE, -1, -1,
buffer).sendToTarget();
System.out.println("Write SUCCESS!!!!!!!!!!!!!!");
} catch (IOException e) {
System.out.println("write ERRORRRRRRRRRRRRRRRRR");
}
}
public void cancel() {
try {
bluetoothSocket.close();
} catch (IOException e) {
}
}
}
private final Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_WRITE:
System.out.println("Write was broadcasted");
byte[] writeBuf = (byte[]) msg.obj;
String writeMessage = new String(Integer.toString(writeBuf[0]));
///tv.setText(writeMessage);
break;
case MESSAGE_READ:
System.out.println("Read was broadcasted");
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(Integer.toString(readBuf[0]));
tv.setText(readMessage);
break;
}
}
};
}
I have 3 buttons to turn on a different led, using wifi. What am I trying to do is to start a thread when a button is pressed. The thread will do a networking stuff which is to send a String of instruction code. But when I pressed the button, it stops running. And I want to display the exception in the toast if there is an exception occured. Please help.
Here is the code:
This is the activity that will display 3 buttons.
package com.gfhz.appliancecontrol;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
public class LightsMenuActivity extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lights_menu);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.display_lights_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void checkLightsStatus() {
/*instructionID = "0400";
Intent intent = new Intent(this, ConnectionSocket.class);
intent.putExtra(INSTRUCTION, instructionID);
startActivity(intent);*/
}
public void powerLamp1 (View view) {
ConnectionSocket cs = new ConnectionSocket();
cs.sendInstruction("0401");
}
public void powerLamp2(View view) {
ConnectionSocket cs = new ConnectionSocket();
cs.sendInstruction("0402");
}
public void powerLamp3(View view){
ConnectionSocket cs = new ConnectionSocket();
cs.sendInstruction("0403");
}
}
And this is the activity that will execute the thread.
package com.gfhz.appliancecontrol;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.widget.Toast;
public class ConnectionSocket extends Activity{
Socket client;
ConnectionInfoActivity conInfo;
String instructionCode;
String serverAddr;
OutputStream os;
DataOutputStream dos;
String stoast;
public void sendInstruction (String instruction) {
// Get the DEVICE ID
String devId = conInfo.getDevId();
// Concatenate instruction message and device Id
instructionCode = devId.concat(instruction);
// Get the SERVER IP ADDRESS
serverAddr = "192.168.1.105";
// Initialize PORT
final int port = 2000;
new Thread (new Runnable() {
public void run() {
try{
// Open a socket
client = new Socket(serverAddr, port);
dos = new DataOutputStream(client.getOutputStream());
dos.writeBytes(instructionCode);
} catch (UnknownHostException e) {
//TODO Auto-generated catch block
e.printStackTrace();
stoast = "Unknown Host Exception" + e.toString();
} catch (IOException e) {
// TODO Auto-generated cach block
e.printStackTrace();
// Display in TOAST
stoast = "IO Exception" + e.toString();
} finally {
if (client != null) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
Toast.makeText(getApplicationContext(), stoast, Toast.LENGTH_SHORT).show();
}
}