Reputation: 739
Hi guys i'm trying to make an app gets me battery status in real time through Toast message. So, if i plug battery charger it should me show "battery is charging", if i unplug charger it should me show "battery is discharging", etc...For this i'm using a new thread but on runtime my app crash and i get error in logcat
Here there are my code and logcat:
public class MainActivity extends Activity {
Context cxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bn = (Button) findViewById(R.id.button);
cxt = this;
Runnable myRunnable = new Runnable() {
@Override
public void run() {
IntentFilter IF = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent BatteryStatus = cxt.registerReceiver(null, IF);
int status = BatteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING;
boolean disCharging = status == BatteryManager.BATTERY_STATUS_DISCHARGING;
boolean usbCharge = status == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharging = status == BatteryManager.BATTERY_PLUGGED_AC;
if (isCharging) {
Toast.makeText(getBaseContext(), "La batteria è in carica", Toast.LENGTH_SHORT).show();
}
if (disCharging) {
Toast.makeText(getBaseContext(), "La batteria è in scarica", Toast.LENGTH_SHORT).show();
}
if (usbCharge) {
Toast.makeText(getBaseContext(), "La batteria è in carica tramite USB", Toast.LENGTH_SHORT).show();
}
if (acCharging) {
Toast.makeText(getBaseContext(), "La batteria è in carica tramite AC", Toast.LENGTH_SHORT).show();
}
}
};
Thread myThread = new Thread(myRunnable);
myThread.start();
}
This is the error i get in my logcat:
01-04 11:10:10.696 7706-7723/com.example.matteo.battery E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-4343
Process: com.example.matteo.battery, PID: 7706
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:336)
at android.widget.Toast.<init>(Toast.java:100)
at android.widget.Toast.makeText(Toast.java:250)
at com.example.matteo.battery.MainActivity$1.run(MainActivity.java:43)
at java.lang.Thread.run(Thread.java:818)
I think i wrong something when try to start the new Thread.
Thanks everybody!
Upvotes: 0
Views: 126
Reputation: 1181
try this
if (isCharging) {
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "La batteria è in carica", Toast.LENGTH_SHORT).show();
}
});
}
Apply to all Toast
not use thread. create a BroadcastReceiver
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING;
boolean disCharging = status == BatteryManager.BATTERY_STATUS_DISCHARGING;
boolean usbCharge = status == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharging = status == BatteryManager.BATTERY_PLUGGED_AC;
//your code
}
};
IntentFilter IF = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(receiver, IF);
or
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
};
IntentFilter IF = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(receiver, IF);
Upvotes: 3
Reputation: 2737
Use runOnUiThread to run a specified action on the UI thread.
public class MainActivity extends Activity {
Context cxt;
Button bn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bn = (Button) findViewById(R.id.button);
cxt = this;
Runnable myRunnable = new Runnable() {
@Override
public void run() {
IntentFilter IF = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent BatteryStatus = cxt.registerReceiver(null, IF);
int status = BatteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING;
boolean disCharging = status == BatteryManager.BATTERY_STATUS_DISCHARGING;
boolean usbCharge = status == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharging = status == BatteryManager.BATTERY_PLUGGED_AC;
if (isCharging) {
showMessage("La batteria è in carica");
}
if (disCharging) {
showMessage("La batteria è in scarica");
}
if (usbCharge) {
showMessage("La batteria è in carica tramite USB");
}
if (acCharging) {
showMessage("La batteria è in carica tramite AC");
}
}
};
Thread myThread = new Thread(myRunnable);
myThread.start();
}
private void showMessage(final String msg) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
}
});
}
}
Upvotes: 1
Reputation: 5227
The Result you are trying to achieve can be done more easily using the Broadcast Receivers. Have a look on the following official Documentation of android developer site.
Upvotes: 1
Reputation: 11948
you can't update your UI in non UI thread,
you get an error in Toast
message,
if you want do some code in new thread and after that updated UI you can use AsyncTask
, for more info about updating ui in new thread you can see Update UI from Thread or see Documentation
Upvotes: 4