I have a app that connects by bluetooth with Arduino. The app is ok, but when I start an another activity my textview doesn't update.
I have a Thread that reads the data of bluetooth, and I have a timer that refreshes the textview.
If you start activity the first time and I return the main activity the textview refreshes ok, but if I start the activity again when I return the main the textview doesn't refresh.
HELP!!!
OnCreate:
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) {
String readMessage = (String) msg.obj;
MetrosRecorridos += ((Calibracion / Imanes / 1000) * readMessage.length()) * Sentido;
}
}
};
in button that connects with bluetooth:
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
The Thread:
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
//creation of the connect thread
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
//Create I/O streams for connection
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer); //read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
txtConectado = "Sonda: Desconectado";
//Toast.makeText(getBaseContext(), "Fallo de conexión", Toast.LENGTH_LONG).show();
break;
}
}
}
//write method
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(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();
}
}
}
The Timer that refreshes the textview:
public void startTimer(){
t = new Timer();
task = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView t;
t=(TextView)findViewById(R.id.txtA);
t.setText(""+MetrosRecorridos);
}
});
}
};
t.scheduleAtFixedRate(task, 0, 10);
}
And the code when I call another activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.opc_ajustes) {
bluetoothIn.removeCallbacksAndMessages(null);
Intent i = new Intent(getApplicationContext(), AjustesActivity.class);
i.putExtra("distancia", Math.floor(MetrosRecorridos / 10));
startActivityForResult(i, 3);
return true;
}
}
Thanks!!!
I can't understand the problem clearly. But i think thread stops when activity on pause. In that case you should create a singleton timer for that purpose or use timer into application class. In activity inside the onResume method , start another thread for refreshing Textview. I hope this helps
Global Timer in android
Related
I am working with my diploma thesis and I have problem with communication Arduino -> Android using bluetooth.
This is my app:
Activity where I want to display distance to obstruction
In the TextView, I want to put data from Arduino with the distance and I need idea, I can't find something, how sending data from different sensors to different Views (for example front , back bumper, left and right).
Here you have arduino code:
#include <SoftwareSerial.h>
// Mid-back sensor
#define trigPinLeft 11
#define echoPinLeft 10
// Right-back sensor (looking from back)
#define trigPinRight 7
#define echoPinRight 6
SoftwareSerial btSerial = SoftwareSerial(0,1);
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
btSerial.begin(115200);
// Mid-back sensor
pinMode(trigPinLeft, OUTPUT);
pinMode(echoPinLeft, INPUT);
// Right-back sensor
pinMode(trigPinRight, OUTPUT);
pinMode(echoPinRight, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
long durationLeft, distanceLeft;
digitalWrite(trigPinLeft, LOW);
delayMicroseconds(5);
digitalWrite(trigPinLeft, HIGH);
delayMicroseconds(5);
digitalWrite(trigPinLeft, LOW);
durationLeft = pulseIn(echoPinLeft, HIGH);
distanceLeft = (durationLeft *0.034 / 2);
if (distanceLeft>=400 || distanceLeft<=18){
Serial.println("Out of range");
btSerial.println("Out of range");
}
else{
Serial.print("BACK LEFT: ");
Serial.print(distanceLeft);
Serial.println(" cm");
btSerial.println(distanceLeft + "cm");
}
//delayMicroseconds(1);
long durationRight, distanceRight;
digitalWrite(trigPinRight, LOW);
delayMicroseconds(5);
digitalWrite(trigPinRight, HIGH);
delayMicroseconds(10);
digitalWrite(trigPinRight, LOW);
durationRight = pulseIn(echoPinRight, HIGH);
distanceRight = (durationRight *0.034 / 2);
if (distanceRight>=400 || distanceRight<=18){
Serial.println("Out of range");
btSerial.println("Out of range");
}
else{
Serial.print("BACK RIGHT: ");
Serial.print(distanceRight);
Serial.println(" cm");
btSerial.println(distanceRight + "cm");
}
delay(10000);
}
This is Android-Studio code where I want one time get data from Arduino to one textView (not working):
public class HomeActivity extends AppCompatActivity {
ImageView imageView;
TextView rearLeft,rearMid,rearRight,frontLeft,frontMid,frontRight;
public static final String PREFS_NAME = "ParkingPrefsFile";
public static final String FIRST_TIME = "firstTime";
public static final String IMAGE_VAL = "imageValue";
private BluetoothServerSocket mmServerSocket;
private BluetoothAdapter mAdapter;
private BluetoothDevice mDevice;
private static final UUID MY_UUID = UUID.fromString("5951c386-e2e7-485d-aebe-a32eec769f7b");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
imageView = (ImageView) findViewById(R.id.carView);
rearLeft = (TextView) findViewById(R.id.rearLeftText);
rearMid = (TextView) findViewById(R.id.rearMidText);
rearRight = (TextView) findViewById(R.id.rearRightText);
frontLeft = (TextView) findViewById(R.id.frontLeftText);
frontMid = (TextView) findViewById(R.id.frontMidText);
frontRight = (TextView) findViewById(R.id.frontRightText);
BluetoothSocket socket = null;
mAdapter = BluetoothAdapter.getDefaultAdapter();
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
boolean firstTime = sharedPreferences.getBoolean(FIRST_TIME,false);
if(!firstTime){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(FIRST_TIME,true);
int image = getIntent().getIntExtra("image", R.drawable.ic_default);
imageView.setImageResource(image);
editor.putString(IMAGE_VAL, String.valueOf(getIntent().getIntExtra("image",R.drawable.ic_default)));
editor.commit();
}
else {
SharedPreferences.Editor editor = sharedPreferences.edit();
int image = getIntent().getIntExtra("image", Integer.parseInt(sharedPreferences.getString(IMAGE_VAL,null )));
imageView.setImageResource(image);
editor.putString(IMAGE_VAL, String.valueOf(getIntent().getIntExtra("image",image)));
editor.commit();
}
/*try{
//mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord("My Adapter", MY_UUID);
mmServerSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}*/
/*byte[] buffer = new byte[256];
int bytes;
try{
mmServerSocket.close();
InputStream inputStream = null;
OutputStream outputStream = null;
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
DataInputStream mmInputStream = new DataInputStream(inputStream);
DataOutputStream mmOutputStream = new DataOutputStream(outputStream);
bytes = mmInputStream.read(buffer);
String readMessage = new String(buffer, 0 , bytes);
rearLeft.setText(readMessage);
} catch (IOException e) {
e.printStackTrace();
}*/
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.home_activity_menu,menu);
return true;
}
}
I compiled and runed app, but after I saw splashscreen, I had white screen and lag on the phone.
I hadn't errors in Android-Studio.
Thanks for help.
You clearly seem to have threading issue.
In your HomeActivity you have commented out the code that allows to open a Bluetooth Server on your Phone so that your Arduino device may connect to it, supplying the relevant UUID and other relevant parameters in RFCOM mode.
That code, however, is network-related and blocking and therefore should never be executed on the app UI Thread which is responsible to handle all UI tasks such as displaying views, monitoring user interactions (touch events) etc.
This is the reason why your phone displays a white screen with lag.
So you should definitely execute the Bluetooth logic on a separate thread.
I'd propose the following class to handle all bluetooth-related logic. It's very straightforward.
public class BluetoothHandler {
private final Handler handler;
private final BluetoothAdapter bluetoothAdapter;
#Nullable
private BluetoothServerSocket serverSocket;
private BluetoothSocket bluetoothSocket;
public BluetoothHandler(Context context) {
final HandlerThread ht = new HandlerThread("Bluetooth Handler Thread", Thread.NORM_PRIORITY);
ht.start(); // starting thread
this.handler = new Handler(ht.getLooper());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
this.bluetoothAdapter = ((BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
} else {
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
}
public void startBluetoothServer() {
// execute code in our background worker thread
this.handler.post(new Runnable() {
#Override
public void run() {
try {
serverSocket = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("name", "your UUID");
bluetoothSocket = serverSocket.accept(); // will wait as long as possible (no timeout) so there is blocking
// do your logic to retrieve in and out put streams to read / write data from / to your Arduino device
} catch (IOException ioe) {
}
}
});
}
#AnyThread
public void writeData(byte[] data) {
// remember, all network operation are to be executed in a background thread
this.handler.post(new Runnable() {
#Override
public void run() {
// write data in output stream
}
});
}
#AnyThread
public void readData(OnDataReadCallback callback) {
// remember, all network operation are to be executed in a background thread
this.handler.post(new Runnable() {
#Override
public void run() {
// read data and notify via callback.
}
});
}
#AnyThread // should be call from your Activity onDestroy() to clear resources and avoid memory leaks.
public void termainte() {
try {
if (serverSocket != null) {
serverSocket.close();
}
if (bluetoothSocket != null) {
bluetoothSocket.close();
}
} catch (IOException ioe) {
}
this.handler.getLooper().quit(); // will no longer be usable. Basically, this class instance is now trash.
}
public interface OnDataReadCallback {
#WorkerThread // watch out if you need to update some view, user your Activity#runOnUiThread method !
void onDataRead(byte[] data);
}
}
I'm making a OBDII Bluetooth Android app and i'm having some issues sending out commands. I've already made a successfully connection between my mobile device and my OBDII adapter, but when I click on another activity, the Bluetooth connection seems to quit?
When you open up the app you'll see a button that says "Connect Device". When you press that, a ListAdapter will show up with paired Bluetooth devices. Then when you have succesfully connected to the device (OBDII Adapter) it will take you to another layout where there is 3 activities that are 3 different powerplatforms for cars. This is where the problem occurs. For now, I just want to be able to read the voltage from the OBDII. But when I click my button getValue inside one of the 3 activities. I get an logcat error. And I think it's because I haven't initiated my BluetoothHandler properly. I have no idea how to do this.
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button b1;
BluetoothAdapter mAdapter;
FragmentHostCallback mHost;
BTHandler btHandler;
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BTHandler.STATE_CONNECTED:
//setContentView(R.layout.activity_connected);
Intent intent = new Intent(MainActivity.this, Connected.class);
startActivity(intent);
Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
Log.v("Log", "Connected");
break;
case BTHandler.STATE_NONE:
Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btHandler = new BTHandler(MainActivity.this, mHandler);
b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
//init();
if (mAdapter == null) {
Toast.makeText(getApplicationContext(), R.string.device_not_supported, Toast.LENGTH_LONG).show();
finish();
} else {
if (!mAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
}
//BTHandler btHandler = new BTHandler(MainActivity.this, mHandler);
//btHandler.connect("");
}
public void onClick(View v) {
int id = v.getId();
//String voltage = ("ATRV");
switch (id) {
case R.id.connect:
onConnect(); //Operation
Log.v("Log", "Pressed onClick");
break;
/*case R.id.getValue:
btHandler.write(voltage);
Log.v("Log", "getValue" + voltage);
break;*/
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), R.string.enable_bluetooth, Toast.LENGTH_SHORT).show();
finish();
}
}
private void onConnect() {
ArrayList deviceStrs = new ArrayList();
final ArrayList<String> devices = new ArrayList();
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
Set pairedDevices = mAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (Object device : pairedDevices) {
BluetoothDevice bdevice = (BluetoothDevice) device;
deviceStrs.add(bdevice.getName() + "\n" + bdevice.getAddress());
devices.add(bdevice.getAddress());
}
}
// show list
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.select_dialog_singlechoice,
deviceStrs.toArray(new String[deviceStrs.size()]));
alertDialog.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
String deviceAddress = devices.get(position);
btHandler.connect(deviceAddress);
//btHandler.write();
}
});
alertDialog.setTitle("Paired devices");
alertDialog.show();
}
BTHandler:
public class BTHandler {
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
final ArrayList<String> devices = new ArrayList();
private final Handler mHandler;
private BluetoothAdapter mAdapter;
private BluetoothDevice device;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private BluetoothSocket socket;
private String status;
private int mState;
private boolean connectionStatus = false;
public BTHandler(Context context, Handler handler) { // Konstruktor
mAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = handler;
}
public void write(String s) {
mConnectedThread.sendRawCommand(s);
Log.v("write", "write");
}
/*
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
public void connect(String deviceAddress) {
mConnectThread = new ConnectThread(deviceAddress);
mConnectThread.start();
}
private void guiHandler(int what, int arg1, String obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.sendToTarget();
}
private class ConnectThread extends Thread {
BluetoothSocket tmp = null;
private BluetoothSocket mmSocket;
public ConnectThread(String deviceAddress) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
device = mAdapter.getRemoteDevice(deviceAddress);
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
//socket.connect();
//Log.v("connect", "connect");
} catch (IOException e) {
//e.printStackTrace();
//Log.v("exception", "e");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mAdapter.cancelDiscovery();
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes;
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.v("connect", "connect");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
Log.v("close", "close");
} catch (IOException closeException) {
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
try {
//RPMCommand engineRpmCommand = new RPMCommand();
//SpeedCommand speedCommand = new SpeedCommand();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
//engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
//speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
voltageCommand.run(socket.getInputStream(), socket.getOutputStream());
// TODO handle commands result
//Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
//Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
Log.v("Log", "Voltage: " + voltageCommand.getFormattedResult());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
OBDcmds();
// Keep listening to the InputStream until an exception occurs
while (connectionStatus) {
sendMultiCommand();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// CALL this to MainActivity
public void sendRawCommand(String command) {
try {
new OdbRawCommand(command);
} catch (Exception e) {
Log.v("sendRawCommand", "e");
}
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new TimeoutCommand(100).run(socket.getInputStream(), socket.getOutputStream());
new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN
} catch (Exception e) {
Log.v("OBDcmds", "e");
// handle errors
}
}
/*
// 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) {
}
}
public void sendMultiCommand() {
try {
// RUN some code here
} catch (Exception e) {
}
}
}
}
SPA: One of the power platforms mentioned before.
public class SPA extends AppCompatActivity implements View.OnClickListener {
Button b2;
BTHandler btHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sp);
b2 = (Button) findViewById(R.id.getValue);
b2.setOnClickListener(this);
}
public void onClick(View v) {
int id = v.getId();
String voltage = ("AT RV");
switch (id) {
case R.id.getValue:
btHandler.write(voltage);
Log.v("Log", "getValue" + voltage);
break;
}
}
}
Logcat:
The reason of the error is here:
BTHandler btHandler;
and you are doing this:
btHandler.write(voltage);
but the object is null referenced....
you need to initialize the BTHandler in the oncreate...
or maybe better:
use a service so you can Bind all the activities to that...
PS:
Note that the BTHandler of the MainActivity is not the same as the one declared in the SPA Class... so although that btHandler is constructed and works in MainActivity doesnt mean it will work in other activities/classes
I have a Handler called 'bluetoothIn' and I want to pass it to a separate looper using the HandlerThread class which will provide the looper. However I need to post the results back to the UI thread from 'handleMessage(Message msg)' since I can't modify UI elements from threads other than the main thread.
Here is my code :
package com.uniproj.senseplate;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
#SuppressWarnings("unused")
public class MainActivity extends Activity {
Button btnscan;
TextView txtArduino, txtString, txtStringLength, calorie;
Handler bluetoothIn;
final int handlerState = 0; //used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket; //= null;
private StringBuilder recDataString = new StringBuilder();
private ConnectedThread mConnectedThread;
// SPP UUID service - this should work for most devices
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// String for MAC address
private static String address;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Link the buttons and textViews to respective views
btnscan = (Button) findViewById(R.id.scanBtn);
txtString = (TextView) findViewById(R.id.txtString);
txtStringLength = (TextView) findViewById(R.id.testView1);
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) {
String readMessage = (String) msg.obj;
recDataString.append(readMessage);
int endOfLineIndex = recDataString.indexOf("~");
if (endOfLineIndex > 0) {
String dataInPrint = recDataString.substring(0, endOfLineIndex);
txtString.setText("Data Received = " + dataInPrint);
int dataLength = dataInPrint.length();
txtStringLength.setText("String Length = " + String.valueOf(dataLength));
if (recDataString.charAt(0) == '#')
{
//get sensor value from string between indices 1-20
String weight = recDataString.substring(1, 20);
//update the textviews with sensor values
calorie.setText(weight + "kg");
}
recDataString.delete(0, recDataString.length());
// strIncom =" ";
dataInPrint = " ";
}
}
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
// Set up onClick listeners for button to scan for data
btnscan.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("0");
}
});
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
//creates secure outgoing connecetion with BT device using UUID
}
#Override
public void onResume() {
super.onResume();
//Get MAC address from DeviceListActivity via intent
Intent intent = getIntent();
//Get the MAC address from the DeviceListActivty via EXTRA
address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
//create device and set the MAC address
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
}
// Establish the Bluetooth socket connection.
try
{
btSocket.connect();
} catch (IOException e) {
try
{
btSocket.close();
} catch (IOException e2)
{
//insert code to deal with this
}
}
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
//I send a character when resuming.beginning transmission to check device is connected
//If it is not an exception will be thrown in the write method and finish() will be called
mConnectedThread.write("x");
}
#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
}
}
//Checks that the Android device Bluetooth is available and prompts to be turned on if off
private void checkBTState() {
if(btAdapter==null) {
Toast.makeText(getBaseContext(), "Device does not support bluetooth", Toast.LENGTH_LONG).show();
} else {
if (btAdapter.isEnabled()) {
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
//create new class for connect thread
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
//creation of the connect thread
public ConnectedThread(BluetoothSocket socket) {
btSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
//Create I/O streams for connection
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer);
bluetoothIn.obtainMessage(handlerState, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
//write method
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(), "Connection Failed", Toast.LENGTH_LONG).show();
finish();
}
}
public class BluetoothInHandler extends Handler{
private Looper sLooper = null;
private Handler mWorkerThreadHandler;
final int handlerState = 0; //used to identify handler message
protected class WorkerArgs {
Handler handler;
String input;
String output;
}
public BluetoothInHandler() {
super();
synchronized (BluetoothInHandler.class) {
if (sLooper == null) {
HandlerThread thread = new HandlerThread("AsyncWorker");
thread.start();
sLooper = thread.getLooper();
}
}
mWorkerThreadHandler = new WorkerHandler(sLooper);
}
#Override
public void handleMessage(Message msg) {
if (msg.what == handlerState) {
WorkerArgs args = (WorkerArgs) msg.obj;
String readMessage = args.output;
//your job;
} else {
super.handleMessage(msg);
}
}
public void write(String input) {
WorkerArgs args = new WorkerArgs();
args.handler = this;
args.input = input;
Message message = mWorkerThreadHandler.obtainMessage(handlerState);
message.obj = args;
mWorkerThreadHandler.sendMessage(message);
}
protected class WorkerHandler extends Handler {
public WorkerHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
if (msg.what == handlerState) {
WorkerArgs args = (WorkerArgs) msg.obj;
//the code here run in a thread, not in the ui thread
//do your job like:
byte[] bytes = mmInStream.read(buffer);
args.output = new String(bytes);
Message message = args.handler.obtainMessage(handlerState);
message.obj = args;
message.sendToTarget();
}
}
}
}
}//ConnectedThread End
}
runOnUi might be a good choice for this
runOnUiThread(new Runnable() {
#Override
public void run() {
// Do whatever you need to do on the UI here
}
});
Sorry, I made a mistake. I think the error is causing by the code bluetoothIn.obtainMessage(handlerState, bytes, -1, buffer).sendToTarget();
change to
bluetoothIn.obtainMessage(handlerState, bytes, -1, new String(buffer)).sendToTarget();
Remove the code I wrote. It is no use.
I'm an absolute beginner in android. Currently, I'm trying to make an app that sends output data to arduino via bluetooth. For that purpose, I have created a class as follows.
private class SendReceiveBytes implements Runnable {
private BluetoothSocket btSocket;
private InputStream inputStream;
private OutputStream outputStream;
String TAG = "SendReceiveBytes";
public SendReceiveBytes(BluetoothSocket socket) {
btSocket = socket;
try {
inputStream = btSocket.getInputStream();
outputStream = btSocket.getOutputStream();
}
catch (IOException streamError) {
Log.e(TAG, "Error when getting input or output Stream");
}
}
#Override
public void run() {
// buffer store for the stream.
byte[] buffer = new byte[1024];
// bytes returned from the stream.
int bytes;
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = inputStream.read(buffer);
// Send the obtained bytes to the UI activity
socketHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
}
catch (IOException e) {
Log.e(TAG, "Error reading from inputStream");
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(String outputData) {
try {
outputStream.write(outputData.getBytes(Charset.forName("UTF-8")));
}
catch (IOException e) {
Log.e(TAG, "Error when writing to outputStream");
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
btSocket.close();
}
catch (IOException e) {
Log.e(TAG, "Error when closing the btSocket");
}
}
}
In my OnCreate() method, I'm doing as follows.
final SendReceiveBytes sendBytes = new SendReceiveBytes(bluetoothSocket);
final Handler moveHandler = new Handler();
View.OnLongClickListener longClickListener = new View.OnLongClickListener() {
public boolean onLongClick(View view) {
switch (view.getId()) {
case R.id.driveFwd:
moveHandler.postDelayed(sendBytes.write("MOVE_FORWARD"), 250);
sendBytes.write("MOVE_FORWARD");
break;
The problem I'm currently having is with the right procedure for invoking method write(). What would be the right way to go on with that?
I am working with the Bluetooth chat example and I am trying to send "dummy" data in specific intervals from a thread that's active when the Bluetooth device is connected. Is it a good idea to start/stop another service to call a method in the original service every so often? How would I implement this?
private class ConnectedThread extends Thread {
static private final String TAG = "PhoneInfoConnectedThread";
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
Log.d(TAG, "In and out streams created");
} catch (IOException e) {
Log.e(TAG, "temp sockets not created " + e.getMessage());
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
// this is where we will spend out time when connected to the accessory.
public void run() {
// Keep listening to the InputStream while connected
while (true) {
// do whatever
}
}
// Write to the connected OutStream.
public void write(byte[] buffer) {
if (mmOutStream == null) {
Log.e(TAG, "ConnectedThread.write: no OutStream");
return;
}
try {
Log.d(TAG, "ConnectedThread.write: writing " + buffer.length
+ " bytes");
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
// mHandler.obtainMessage(PhoneInfoActivity.MESSAGE_WRITE, -1,
// -1, buffer).sendToTarget();
Log.d(TAG, "ConnectedThread.write: sent to calling activity");
} catch (IOException e) {
Log.e(TAG, "Exception during write" + e.getMessage());
}
}
public void cancel() {
try {
Log.d(TAG, "ConnectedThread.cancel: closing socket");
if (mmSocket != null)
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "ConnectedThread.cancel: socket.close() failed"
+ e.getMessage());
}
}
}
May this example help you.
MyTimerTask myTask = new MyTimerTask();
Timer myTimer = new Timer();
myTimer.schedule(myTask, 2000, 1000);
class MyTimerTask extends TimerTask {
public void run() {
Log.v("TAG","Message");
}
}
for more information see this