Runtime Error using Timer - Android - java

I'm using Timer example as given here: https://stackoverflow.com/a/2535778/4549769
but I'm getting a runtime error when executing this line (I've commented all other for debugging):
intensityTextView.setText(String.valueOf(_intensity));
I understand that I need to pass the UI somehow but have no idea how.
here is the code
package hanan.smartlight;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Timer;
import java.util.TimerTask;
public class Main extends ActionBarActivity {
// private SeekBar intensitySeekBar;
private int _intensity=0;
private String _ServerResponse="";
private boolean led_state=false;
private int repeatTimeMs=1000;
private int delayStartingTimeMs = 5000; // 5 seconds by default, can be changed later
TextView intensityTextView;
SeekBar intensitySeekBar;
Switch ledSwitch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intensityTextView = (TextView) findViewById(R.id.intensityValue);
intensitySeekBar = (SeekBar) findViewById(R.id.intensitySeekBar);
ledSwitch = (Switch) findViewById(R.id.ledSwitch);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
setControl(); // display the data
}
}, delayStartingTimeMs, repeatTimeMs);
// Timer timer = new Timer();
// MyTimerTask myTimerTask = new MyTimerTask();
// timer.schedule(myTimerTask, delayStartingTimeMs, repeatTimeMs);
}
#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 SyncWithServer(){
}
public void setControl() {
String url = "http://smartlight.gear.host/getControlsFromDB.php"; //url for server
new UploadToServer().execute(url); //send the request
int ledS = 0;
int intS = 0;
String s1 = "";
String s2 = "";
if (_ServerResponse.length() > 3) {
try {
s1 = _ServerResponse.substring(3, 6);
} catch (Exception e) {
return;
}
try {
s2 = _ServerResponse.substring(9, _ServerResponse.length() - 2);
} catch (Exception e) {
return;
}
try {
ledS = Integer.parseInt(s1);
} catch (NumberFormatException e) {
return;
}
try {
intS = Integer.parseInt(s2);
} catch (NumberFormatException e) {
return;
}
if (ledS == 255)
led_state = true;
else if (ledS == 254)
led_state = false;
if (intS >= 0 && intS <= 100)
_intensity = intS;
}
intensityTextView.setText(String.valueOf(_intensity));
// intensityTextView.setText("Test");
// intensitySeekBar.setProgress(_intensity);
// ledSwitch.setChecked(led_state);
// setValuesToDB();
}
public class UploadToServer extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (!(response == null || response.equals(" ")))
_ServerResponse = response;
return response;
}
}
}
02-15 15:18:57.079 8345-8345/hanan.smartlight E/﹕ appName=hanan.smartlight, acAppName=/system/bin/surfaceflinger
02-15 15:18:57.079 8345-8345/hanan.smartlight E/﹕ 0
02-15 15:19:01.464 8345-8388/hanan.smartlight E/AndroidRuntime﹕ FATAL EXCEPTION: Timer-0
Process: hanan.smartlight, PID: 8345
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6669)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1005)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:4548)
at android.view.View.invalidate(View.java:11134)
at android.view.View.invalidate(View.java:11083)
at android.widget.TextView.checkForRelayout(TextView.java:7201)
at android.widget.TextView.setText(TextView.java:4283)
at android.widget.TextView.setText(TextView.java:3722)
at android.widget.TextView.setText(TextView.java:3697)
at hanan.smartlight.Main.setControl(Main.java:123)
at hanan.smartlight.Main$1.run(Main.java:48)
at java.util.Timer$TimerImpl.run(Timer.java:284)

Use post() method on textview. Runnable will be run on user interface thread.This is example how to update textview inside run method of TimerTask.
public class MainActivity extends ActionBarActivity {
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
textView.post(new Runnable() {
#Override
public void run() {
textView.setText("Arun");
}
});
}
}, 3000, 3000);
}
}
In your case you can add like
intensityTextView.post(new Runnable() {
#Override
public void run() {
intensityTextView.setText(String.valueOf(_intensity));
}
});

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
mHandler.obtainMessage(1).sendToTarget();
}
}, delayStartingTimeMs, repeatTimeMs);
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
setControl(); //this is where textView gets Updated
}
mHandler must be in the Main Thread!

Related

Attempt to invoke virtual method 'java.io.InputStream android.bluetooth.BluetoothSocket.getInputStream()'

I am trying to connect my android app with hc-06 for sending and receiving data purpose, below is the error occur and I've been stuck here from 3 days.
There error occured to me is
Attempt to invoke virtual method 'java.io.InputStreamandroid.bluetooth.BluetoothSocket.getInputStream()'
Kindly somebody solve it or provide me another working code for sending and receiving data through bluetoth hc-06 android app
package infoaryan.in.hc05_bluetooth;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
public class LedControl extends AppCompatActivity {
TextView textView;
Button btn1, btn2, btn3, btn4, btn5, btnDis;
String address = null;
TextView lumn;
private ProgressDialog progress;
BluetoothAdapter myBluetooth = null;
BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
int counter;
volatile boolean stopWorker;
InputStream mmInputStream;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_led_control2);
Intent intent = getIntent();
address = intent.getStringExtra(MainActivity.EXTRA_ADDRESS);
btn1 = findViewById(R.id.button2);
btn2 = findViewById(R.id.button3);
//For additional actions to be performed
btn3 = findViewById(R.id.button5);
btn4 = findViewById(R.id.button6);
btn5 = findViewById(R.id.button7);
btnDis = findViewById(R.id.button4);
lumn = findViewById(R.id.textView2);
textView = findViewById(R.id.textView3);
new LedControl.ConnectBT().execute();
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
sendSignal("1");
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
sendSignal("0");
}
});
btn3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
sendSignal("3");
}
});
btn4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
sendSignal("4");
}
});
btn5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
sendSignal("5");
}
});
btnDis.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
Disconnect();
}
});
beginListenForData();
}
private void sendSignal ( String givenumber ) {
if ( btSocket != null ) {
try {
btSocket.getOutputStream().write(givenumber.getBytes());
} catch (IOException e) {
msg("Error");
}
}
}
private void Disconnect () {
if ( btSocket!=null ) {
try {
btSocket.close();
} catch(IOException e) {
msg("Error");
}
}
finish();
}
private void msg (String s) {
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
private class ConnectBT extends AsyncTask<Void, Void, Void> {
private boolean ConnectSuccess = true;
#Override
protected void onPreExecute () {
progress = ProgressDialog.show(LedControl.this, "Connecting...", "Please Wait!!!");
}
#Override
protected Void doInBackground (Void... devices) {
try {
if ( btSocket==null || !isBtConnected ) {
myBluetooth = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);
btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();
}
} catch (IOException e) {
ConnectSuccess = false;
}
return null;
}
#Override
protected void onPostExecute (Void result) {
super.onPostExecute(result);
if (!ConnectSuccess) {
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
finish();
} else {
msg("Connected");
isBtConnected = true;
}
progress.dismiss();
}
}
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()
{
textView.setText(data);
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
stopWorker = true;
}
}
}
});
workerThread.start();
}
#Override
protected void onResume() {
super.onResume();
}
}

Changing String from buffer to int

So another one from the same code with another problem.
here is the code
package com.test.aplikasirevisi;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import static com.test.aplikasirevisi.Information.Highest;
import static com.test.aplikasirevisi.Information.Lowest;
import static com.test.aplikasirevisi.Information.mypreference;
public class MonitoringScreen extends Activity {
private static final String TAG = "BlueTest5-MainActivity";
private int mMaxChars = 50000;//Default
private UUID mDeviceUUID;
private BluetoothSocket mBTSocket;
private ReadInput mReadThread = null;
TextView highest;
TextView lowest;
private boolean mIsUserInitiatedDisconnect = false;
private TextView mTxtReceive;
private Button mBtnClearInput;
private Button mBtnGetBPM;
private ScrollView scrollView;
private CheckBox chkScroll;
private CheckBox chkReceiveText;
private boolean mIsBluetoothConnected = false;
private BluetoothDevice mDevice;
private ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_monitoring_screen);
ActivityHelper.initialize(this);
Intent intent = getIntent();
Bundle b = intent.getExtras();
mDevice = b.getParcelable(MainActivity.DEVICE_EXTRA);
mDeviceUUID = UUID.fromString(b.getString(MainActivity.DEVICE_UUID));
mMaxChars = b.getInt(MainActivity.BUFFER_SIZE);
Log.d(TAG, "Ready");
mTxtReceive = (TextView) findViewById(R.id.txtReceive);
chkScroll = (CheckBox) findViewById(R.id.chkScroll);
chkReceiveText = (CheckBox) findViewById(R.id.chkReceiveText);
scrollView = (ScrollView) findViewById(R.id.viewScroll);
mBtnClearInput = (Button) findViewById(R.id.btnClearInput);
mBtnGetBPM = (Button) findViewById(R.id.mBtnGetBPM);
mTxtReceive.setMovementMethod(new ScrollingMovementMethod());
highest = (TextView) findViewById(R.id.etHighest);
lowest = (TextView) findViewById(R.id.etLowest);
SharedPreferences sharedpreferences = getSharedPreferences(mypreference,
Context.MODE_PRIVATE);
if (sharedpreferences.contains(Highest)) {
highest.setText(sharedpreferences.getString(Highest, ""));
}
if (sharedpreferences.contains(Lowest)) {
lowest.setText(sharedpreferences.getString(Lowest, ""));
}
mBtnClearInput.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
mTxtReceive.setText("");
}
});
}
private class ReadInput implements Runnable{
private boolean bStop = false;
private Thread t;
public ReadInput() {
t = new Thread(this, "Input Thread");
t.start();
}
public boolean isRunning() {
return t.isAlive();
}
#Override
public void run() {
InputStream inputStream;
try {
inputStream = mBTSocket.getInputStream();
while (!bStop) {
byte[] buffer = new byte[256];
if (inputStream.available() > 0) {
inputStream.read(buffer);
int i;
/*
* This is needed because new String(buffer) is taking the entire buffer i.e. 256 chars on Android 2.3.4 http://stackoverflow.com/a/8843462/1287554
*/
for (i = 0; i < buffer.length && buffer[i] != 0; i++) {
}
final String strInput = new String(buffer, 0, i);
String getHi = null;
SharedPreferences sharedpreferences = getSharedPreferences(mypreference,
Context.MODE_PRIVATE);
if (sharedpreferences.contains(Highest)) {
highest.setText(sharedpreferences.getString(Highest, ""));
getHi=highest.getText().toString();
}
if (sharedpreferences.contains(Lowest)) {
lowest.setText(sharedpreferences.getString(Lowest, ""));
}
int hi = Integer.parseInt(getHi);
/*
* If checked then receive text, better design would probably be to stop thread if unchecked and free resources, but this is a quick fix
*/
if (chkReceiveText.isChecked()) {
mTxtReceive.post(new Runnable() {
#Override
public void run() {
mTxtReceive.append(strInput);
System.out.println(strInput);
if(data < hi){
Log.d(TAG, "succes");
}
int txtLength = mTxtReceive.getEditableText().length();
if(txtLength > mMaxChars){
mTxtReceive.getEditableText().delete(0, txtLength - mMaxChars);
Log.d(TAG, "text longer than allowed:" + mTxtReceive.getEditableText().delete(0, txtLength - mMaxChars));
}
if (chkScroll.isChecked()) { // Scroll only if this is checked
scrollView.post(new Runnable() { // Snippet from http://stackoverflow.com/a/4612082/1287554
#Override
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
}
});
}
}
Thread.sleep(500);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void stop() {
bStop = true;
}
}
private class DisConnectBT extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... params) {
if (mReadThread != null) {
mReadThread.stop();
while (mReadThread.isRunning())
; // Wait until it stops
mReadThread = null;
}
try {
mBTSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mIsBluetoothConnected = false;
if (mIsUserInitiatedDisconnect) {
finish();
}
}
}
private void msg(String s) {
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
if (mBTSocket != null && mIsBluetoothConnected) {
new DisConnectBT().execute();
}
Log.d(TAG, "Paused");
super.onPause();
}
#Override
protected void onResume() {
if (mBTSocket == null || !mIsBluetoothConnected) {
new ConnectBT().execute();
}
Log.d(TAG, "Resumed");
super.onResume();
}
#Override
protected void onStop() {
Log.d(TAG, "Stopped");
super.onStop();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}
private class ConnectBT extends AsyncTask<Void, Void, Void> {
private boolean mConnectSuccessful = true;
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(MonitoringScreen.this, "Hold on", "Connecting");// http://stackoverflow.com/a/11130220/1287554
}
#Override
protected Void doInBackground(Void... devices) {
try {
if (mBTSocket == null || !mIsBluetoothConnected) {
mBTSocket = mDevice.createInsecureRfcommSocketToServiceRecord(mDeviceUUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
mBTSocket.connect();
}
} catch (IOException e) {
// Unable to connect to device
e.printStackTrace();
mConnectSuccessful = false;
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (!mConnectSuccessful) {
Toast.makeText(getApplicationContext(), "Could not connect to device. Is it a Serial device? Also check if the UUID is correct in the settings", Toast.LENGTH_LONG).show();
finish();
} else {
msg("Connected to device");
mIsBluetoothConnected = true;
mReadThread = new ReadInput(); // Kick off input reader
}
progressDialog.dismiss();
}
}
}
i want to change the String to int from this part:
final String strInput = new String(buffer, 0, i);
so i can use it on this part :
if(data < hi){
Log.d(TAG, "succes");
}
i tried to use
int data = Integer.parseInt(strInput);
but well of course it span error because its string buffer and only the first one is changed
so how do i solve this prob?if any one can help
I already tried using arraylist but still error
Here is the error code :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.aplikasirevisi, PID: 21905
java.lang.NumberFormatException: For input string: "40
"
at java.lang.Integer.parseInt(Integer.java:615)
at java.lang.Integer.parseInt(Integer.java:650)
at com.test.aplikasirevisi.MonitoringScreen$ReadInput$1.run(MonitoringScreen.java:152)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
I/Process: Sending signal. PID: 21905 SIG: 9
The error message is telling you what is wrong. Your input appears to be "40 and " is not a numeric character. You need make sure your inputted strings are numeric OR you need to extract the numeric component from the string BEFORE attempting to convert it into an integer. You could try new String(buffer, 1, i) if the character at index 0 is always the double quote character.
UPDATE:
Based on your last comment posted here, you need to initialize your strInput as follows (This is an example):
byte[] bytes = new byte[5];
bytes[0] = 49; // this is the ASCII value of the number "1"
bytes[1] = '\u0000'; // These are null characters
bytes[2] = '\u0000';
bytes[3] = '\u0000';
bytes[4] = '\u0000';
String temp = new String(bytes); // convert the byte array to String
String str = temp.substring(0, temp.indexOf('\u0000')); // parse the numeric contents
System.out.println(str); // You should see "1" printed out
int number = Integer.parseInt(str); // Because I parsed the numeric contents, it is safe to convert the String to a number.

Getting the value from textview

Hello guys I got a code that I do for my project, the code is to get the value of the heartbeat sensor from Arduino to my android phone using Bluetooth. So far it's going well it can send the value to my app without a problem. but the problem now is I want to get the value of it so I can use my algorithm with it, but seems like I got in a pickle now.
Here is the code :
package com.test.aplikasirevisi;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
public class MonitoringScreen extends Activity {
private static final String TAG = "BlueTest5-MainActivity";
private int mMaxChars = 50000;//Default
private UUID mDeviceUUID;
private BluetoothSocket mBTSocket;
private ReadInput mReadThread = null;
private boolean mIsUserInitiatedDisconnect = false;
private TextView mTxtReceive;
private Button mBtnClearInput;
private ScrollView scrollView;
private CheckBox chkScroll;
private CheckBox chkReceiveText;
private boolean mIsBluetoothConnected = false;
private BluetoothDevice mDevice;
private ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_monitoring_screen);
ActivityHelper.initialize(this);
Intent intent = getIntent();
Bundle b = intent.getExtras();
mDevice = b.getParcelable(MainActivity.DEVICE_EXTRA);
mDeviceUUID = UUID.fromString(b.getString(MainActivity.DEVICE_UUID));
mMaxChars = b.getInt(MainActivity.BUFFER_SIZE);
Log.d(TAG, "Ready");
mTxtReceive = (TextView) findViewById(R.id.txtReceive);
chkScroll = (CheckBox) findViewById(R.id.chkScroll);
chkReceiveText = (CheckBox) findViewById(R.id.chkReceiveText);
scrollView = (ScrollView) findViewById(R.id.viewScroll);
mBtnClearInput = (Button) findViewById(R.id.btnClearInput);
mTxtReceive.setMovementMethod(new ScrollingMovementMethod());
mBtnClearInput.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
mTxtReceive.setText("");
}
});
}
private class ReadInput implements Runnable{
private boolean bStop = false;
private Thread t;
public ReadInput() {
t = new Thread(this, "Input Thread");
t.start();
}
public boolean isRunning() {
return t.isAlive();
}
#Override
public void run() {
InputStream inputStream;
try {
inputStream = mBTSocket.getInputStream();
while (!bStop) {
byte[] buffer = new byte[256];
if (inputStream.available() > 0) {
inputStream.read(buffer);
int i;
/*
* This is needed because new String(buffer) is taking the entire buffer i.e. 256 chars on Android 2.3.4 http://stackoverflow.com/a/8843462/1287554
*/
for (i = 0; i < buffer.length && buffer[i] != 0; i++) {
}
final String strInput = new String(buffer, 0, i);
/*
* If checked then receive text, better design would probably be to stop thread if unchecked and free resources, but this is a quick fix
*/
if (chkReceiveText.isChecked()) {
mTxtReceive.post(new Runnable() {
#Override
public void run() {
mTxtReceive.append(strInput);
int txtLength = mTxtReceive.getEditableText().length();
if(txtLength > mMaxChars){
mTxtReceive.getEditableText().delete(0, txtLength - mMaxChars);
System.out.println(mTxtReceive.getText().toString());
}
if (chkScroll.isChecked()) { // Scroll only if this is checked
scrollView.post(new Runnable() { // Snippet from http://stackoverflow.com/a/4612082/1287554
#Override
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
}
});
}
}
Thread.sleep(500);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void stop() {
bStop = true;
}
}
private class DisConnectBT extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... params) {
if (mReadThread != null) {
mReadThread.stop();
while (mReadThread.isRunning())
; // Wait until it stops
mReadThread = null;
}
try {
mBTSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mIsBluetoothConnected = false;
if (mIsUserInitiatedDisconnect) {
finish();
}
}
}
private void msg(String s) {
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
if (mBTSocket != null && mIsBluetoothConnected) {
new DisConnectBT().execute();
}
Log.d(TAG, "Paused");
super.onPause();
}
#Override
protected void onResume() {
if (mBTSocket == null || !mIsBluetoothConnected) {
new ConnectBT().execute();
}
Log.d(TAG, "Resumed");
super.onResume();
}
#Override
protected void onStop() {
Log.d(TAG, "Stopped");
super.onStop();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}
private class ConnectBT extends AsyncTask<Void, Void, Void> {
private boolean mConnectSuccessful = true;
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(MonitoringScreen.this, "Hold on", "Connecting");// http://stackoverflow.com/a/11130220/1287554
}
#Override
protected Void doInBackground(Void... devices) {
try {
if (mBTSocket == null || !mIsBluetoothConnected) {
mBTSocket = mDevice.createInsecureRfcommSocketToServiceRecord(mDeviceUUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
mBTSocket.connect();
}
} catch (IOException e) {
// Unable to connect to device
e.printStackTrace();
mConnectSuccessful = false;
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (!mConnectSuccessful) {
Toast.makeText(getApplicationContext(), "Could not connect to device. Is it a Serial device? Also check if the UUID is correct in the settings", Toast.LENGTH_LONG).show();
finish();
} else {
msg("Connected to device");
mIsBluetoothConnected = true;
mReadThread = new ReadInput(); // Kick off input reader
}
progressDialog.dismiss();
}
}
}
What i want is to get the value of mTxtReceive on this :
int txtLength = mTxtReceive.getEditableText().length();
if(txtLength > mMaxChars){
mTxtReceive.getEditableText().delete(0, txtLength - mMaxChars);
System.out.println(mTxtReceive.getText().toString());
}
I used System.out.println for seeing if i got the value but in the log it didn't show any thing.
So i need you guys wisdom for this any help?
Your view mTextReceive seems to be a TextView and therefore not editable:
private TextView mTxtReceive;
If it's not an EditText (editable) mTxtReceive.getEditableText will return null see docs
and getText should be called instead see docs.
Therefore your condition might always resolve from
if(txtLength > mMaxChars) into if(null > 50000) which is always false (or actually it might even crash before) and therefore your code inside the if-block is never executed
Try:
// recommended for debugging. Check if this is even called and if text length is really longer than max chars
Log.d(TAG, "text length:" + mTxtReceive.getText().length());
int txtLength = mTxtReceive.getText().length();
if(txtLength > mMaxChars){
// not sure what operation you want to do here but leave out for debugging
Log.d(TAG, "text longer than allowed:" + mTxtReceive.getText().toString());
}
Also use Log.d instead of System.out.println since your log might otherwise not be forwarded to Logcat. Also are you sure this block is executed at all? I'd put a Log.d(TAG, "text length:" + mTxtReceive.getText().length()); outside of the condition for debugging purposes. And finally the obvious question would be if the txtLength is even longer than max chars (and that would be quite a long text with 50000 chars). But you can verify that simply with the recommended log outside the block as well.

Getting int to UI thread

I am developing an Android application that brute-forces an MD5 sum created from an int.
The brute forcing part works fine. (I can sysout the final value and it's correct.)
I'm having problems getting the output value onto an alert dialog. Logcat says: Attempting to initialize hardware acceleration outside of the main thread, aborting
It's aborting on the last statement in my code, the one that actually shows the alert dialog;
builder.show();
Here's my MainActivity.java:
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MainActivity extends Activity {
String passwordToHash;
String result;
boolean goodPIN = false;
boolean startbruteforce = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#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);
}
//My stuff
public void doIt(View v) throws NoSuchAlgorithmException, UnsupportedEncodingException
{
RadioButton r2 = (RadioButton) findViewById(R.id.calculate);
RadioButton r1 = (RadioButton) findViewById(R.id.crack);
final EditText input = (EditText) findViewById(R.id.inputTextArea);
final EditText output = (EditText) findViewById(R.id.outputTextArea);
//Toast.makeText(this, "Working on it!", Toast.LENGTH_LONG).show();
if(r2.isChecked())
{
if(input.getText().toString().length() > 4)
{
goodPIN = false;
output.setText("");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle ("Uuuuuuhh....");
builder.setMessage("Hash not calculated because that PIN would take too long to brute force :(");
builder.setPositiveButton("Yeah, whatever...", null);
builder.show();
}
else
{
goodPIN = true;
}
if(goodPIN)
{
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
Toast.makeText(this, "Calculated MD5!", Toast.LENGTH_LONG).show();
passwordToHash = input.getText().toString();
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] inputBytes = passwordToHash.getBytes("UTF-8");
byte[] hashBytes = digest.digest(inputBytes);
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < hashBytes.length; i++)
{
stringBuffer.append(Integer.toString((hashBytes[i] & 0xff) + 0x100, 16)
.substring(1));
}
result = stringBuffer.toString();
output.setText(result);
}
}
else if(r1.isChecked())
{
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
final ProgressDialog dialog = ProgressDialog.show(MainActivity.this, "Working on it!", "Brute-forcing. Please wait...", true);
double starttime = System.currentTimeMillis();
final Thread thread = new Thread()
{
#Override
public void run()
{
String crackedPassword = "Hello";
String crackedPasswordHash = "a262";
int pinsTested = 1000;
int crackedPasswordInt = 1000;
String passwordToCrack;
//Get the password to crack
passwordToCrack = input.getText().toString();
long startTime = System.currentTimeMillis();
while (!crackedPasswordHash.equals(passwordToCrack))
{
pinsTested++;
crackedPasswordInt++;
crackedPassword = Integer.toString(crackedPasswordInt);
MessageDigest digest = null;
try
{
digest = MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
byte[] inputBytes = new byte[0];
try
{
inputBytes = crackedPassword.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
byte[] hashBytes = digest.digest(inputBytes);
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < hashBytes.length; i++)
{
stringBuffer.append(Integer.toString((hashBytes[i] & 0xff) + 0x100, 16)
.substring(1));
}
crackedPasswordHash = stringBuffer.toString();
//System.out.println(pinsTested + " PINs tested");
//System.out.println("Hash of: " + pinsTested + " is: " + crackedPasswordHash);
}
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Done! " + pinsTested);
updateUI(pinsTested);
//runOnUiThread(pinsTested);
}
};
Thread animation = new Thread()
{
#Override
public void run()
{
try
{
Thread.sleep(4000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
dialog.dismiss();
thread.start();
}
};
animation.start();
}
}
public void updateUI(final int pass) {
Looper.prepare();
final Handler myHandler = new Handler();
(new Thread(new Runnable() {
#Override
public void run() {
myHandler.post(new Runnable() {
#Override
public void run() {
test(pass);
}
});
}
})).start();
}
public void test(int pass)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle ("Done!");
builder.setMessage("PIN is: " + pass);
builder.setPositiveButton("Yeah, whatever...", null);
builder.show();
}
}
As the UI Thread says:to move data from a background thread to the UI thread, use a Handler that's running on the UI thread.
You create Handler in method updateUI ,but the updateUI is created in thread other than UI Thread,so you get the error.
You need to try like this:
public class MainActivity extends Activity {
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
test((int)msg.obj);
}
}
}
public void updateUI(final int pass) {
Message msg = Message.obtain();
msg.what=1;
msg.obj = pass;
mHandler.sendMessage(msg);
}
}
According to the documentation,
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
So you are creating the handler in the "updateUI" method and that method is called from a thread other than the UI thread, in this case you need to declare your Handler as a member variable and initialize the Handler in the onCreate method.
Handler
you can do everything u want in inside run method:
but its not very safe!
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});

Android App Crashes when no internet connection due to Can't create handler inside thread that has not called Looper.prepare()

I'm developing my android app for a conference. In, my login page I printed an error message when no internet connection. but, the app crashes when no internet connection and following error message display in logcat.
I followed many questions from stack overflow and may be I can't understand, I couldn't find my answer.
08-19 10:01:21.840
8931-9124/com.NICT.nict E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-691
java.lang.RuntimeException: Can't create handler inside thread that hasnot called Looper.prepare()
at android.os.Handler.<init>(Handler.java:205)
at android.os.Handler.<init>(Handler.java:119)
atandroid.widget.Toast$TN.<init>(Toast.java:325)
atandroid.widget.Toast.<init>(Toast.java:91)
atandroid.widget.Toast.makeText(Toast.java:239)
at com.NICT.nict.services.MessageHandler.showMessage(MessageHandler.java:9)
at com.NICT.nict.LoginActivity$1$1.run(LoginActivity.java:117)
at java.lang.Thread.run(Thread.java:838)
Here is my login activity
package com.NICT.nict;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import com.NICT.nict.WorkShopActivity.HttpAsyncTask;
import com.NICT.nict.services.EmailValidator;
import com.NICT.nict.services.MessageHandler;
import com.NICT.nict.services.ServiceHandler;
public class LoginActivity extends Activity {
public final static String URL = "http://demo.et.lk/nitcapi/api/login";
public static String Uid;
private Button loginBtn;
private EditText codeEdit;
private EditText nameEdit;
private EditText emailEdit;
private ServiceHandler sh = new ServiceHandler();
private boolean errorStatus;
private ProgressBar spinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginBtn = (Button) findViewById(R.id.loginBtn);
codeEdit = (EditText) findViewById(R.id.codeEdit);
nameEdit = (EditText) findViewById(R.id.nameEdit);
emailEdit = (EditText) findViewById(R.id.emailEdit);
spinner = (ProgressBar) findViewById(R.id.progressBar1);
spinner.setVisibility(View.GONE);
loginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!ServiceHandler.isOnline(getApplicationContext())) {
MessageHandler.showMessage("You are not online.",
getApplicationContext());
}
new Thread(new Runnable() {
public void run() {
String code = codeEdit.getText().toString();
String email = emailEdit.getText().toString();
String name = nameEdit.getText().toString();
if (code.length() == 0) {
runOnUiThread(new Runnable() {
public void run() {
MessageHandler.showMessage(
"Please Enter the app code",
getApplicationContext());
errorStatus = true;
}
});
;
} else if (name.length() == 0) {
runOnUiThread(new Runnable() {
public void run() {
MessageHandler.showMessage(
"Please Enter Your Name",
getApplicationContext());
errorStatus = true;
}
});
;
} else if (email.length() == 0) {
runOnUiThread(new Runnable() {
public void run() {
MessageHandler.showMessage(
"Please Enter Your Email",
getApplicationContext());
errorStatus = true;
}
});
;
}
EmailValidator emailValidator = new EmailValidator();
if(!emailValidator.validate(email)){
runOnUiThread(new Runnable() {
public void run() {
MessageHandler.showMessage(
"Invalid Email",
getApplicationContext());
errorStatus = true;
}
});
;
}
String jsonStr = null;
if (!errorStatus) {
if (!ServiceHandler.isOnline(getApplicationContext())) {
MessageHandler.showMessage("You are not online.",
getApplicationContext());
} else {
ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
// notify user you are online
try{
runOnUiThread(new Runnable() {
public void run() {
spinner.setVisibility(View.VISIBLE);
}
});
;
jsonStr = sh.makeServiceCall(URL + "/" + code + "/"
+ name + "/" + email, ServiceHandler.GET);
System.out.println(URL + "/" + code + "/" + name + "/"
+ email);
}
catch (Exception e){
spinner.setVisibility(View.GONE);
runOnUiThread(new Runnable() {
public void run() {
MessageHandler.showMessage("You are not online.",
getApplicationContext());
}
});
;
}
}
if (jsonStr != null) {
String status = "";
String msg = "";
try {
JSONObject jsonObj = new JSONObject(jsonStr);
runOnUiThread(new Runnable() {
public void run() {
spinner.setVisibility(View.GONE);
}
});
;
if (jsonObj != null
&& jsonObj.has("status")) {
status = jsonObj.getString("status");
msg = jsonObj.getString("message");
if(jsonObj.has("uid"))
Uid = jsonObj.getString("uid");
System.out.println(jsonObj);
if (status.equals("OK")) {
Intent myIntent = new Intent(
getBaseContext(),
MainMenuActivity.class);
startActivityForResult(myIntent, 0);
} else if (status.equals("ERROR")) {
final String errorMsg = msg;
runOnUiThread(new Runnable() {
public void run() {
MessageHandler
.showMessage(
errorMsg,
getApplicationContext());
}
});
;
} else {
runOnUiThread(new Runnable() {
public void run() {
MessageHandler
.showMessage(
"Oops..! something wrong with the service. Please try again Later.",
getApplicationContext());
}
});
;
}
}
} catch (Exception e) {
System.out
.println("Creation of json object failed");
}
}
}
}
}).start();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.login, menu);
return true;
}
}
Here is my serviceHandler.
package com.NICT.nict.services;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class ServiceHandler {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
public ServiceHandler() {
}
/**
* Making service call
*
* #url - url to make request
* #method - http request method
* */
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/**
* Making service call
*
* #url - url to make request
* #method - http request method
* #params - http request params
* */
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
public static boolean isOnline(Context ctx) {
ConnectivityManager cm;
NetworkInfo info = null;
try {
cm = (ConnectivityManager) ctx
.getSystemService(Context.CONNECTIVITY_SERVICE);
info = cm.getActiveNetworkInfo();
} catch (Exception e) {
e.printStackTrace();
}
return (info!=null&&!info.equals(null));
}
}
add this following snippet in your if condition::
if (!ServiceHandler.isOnline(getApplicationContext())) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(
new Runnable()
{
#Override
public void run()
{
MessageHandler.showMessage("You are not online.",
getApplicationContext());
}
}
);
}
Try this.when you see runtimeException due to Looper not prepared before handler.
Handler handler = new Handler(Looper.getMainLooper());
From Android Docs:
LOOPER
Class used to run a message loop for a thread. Threads by default do
not have a message loop associated with them; to create one, call
prepare() in the thread that is to run the loop, and then loop() to
have it process messages until the loop is stopped.
Looper.getMainLooper()
Returns the application's main looper, which
lives in the main thread of the application.
I hope it helps!
Android basically works on two thread types namely UI thread and background thread.
Try this,
activity.runOnUiThread(new Runnable() {
public void run() {
//run your code here.....
}
});

Categories