I'm creating a battery monitor application, and I'm trying to display the current battery percentage. I have a broadcastreceiver, that is listening for...
<action android:name="android.intent.action.BATTERY_CHANGED" />
In the receiver I have the following code.
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
currentBatteryLevel = level / (float) scale;
Toast.makeText(context, "Current battery level: " + Float.toString(currentBatteryLevel) + "%", Toast.LENGTH_SHORT).show();
For some reason, the result is always Current battery level: 1.0%...Where am I going wrong?
Edit:
Reciever is registered in the manifest as...
<receiver android:name=".PowerMonitorReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
<action android:name="android.intent.action.BATTERY_LOW" />
<action android:name="android.intent.action.BATTERY_OKAY" />
<action android:name="android.intent.action.BATTERY_CHANGED" />
</intent-filter>
</receiver>
and my receiver is...
package com.garciaericn.t2d;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.BatteryManager;
import android.util.Log;
import android.widget.Toast;
public class PowerMonitorReceiver extends BroadcastReceiver {
private static final String TAG = "PowerMonitorReceiver.TAG";
private float currentBatteryLevel;
#Override
public void onReceive(Context context, Intent intent) {
// Obtain action from intent to check which broadcast is being received
String action = intent.getAction();
// Perform action according to type
switch (action) {
case (Intent.ACTION_BATTERY_CHANGED): {
Log.i(TAG, "Battery has changed");
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
currentBatteryLevel = (level * 100) / (float) scale;
Toast.makeText(context, "Current battery level: " + Float.toString(currentBatteryLevel) + "%" + " level: " + level + " scale: " + scale, Toast.LENGTH_LONG).show();
break;
}
case (Intent.ACTION_POWER_CONNECTED): {
Log.i(TAG, "Power connected");
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
String chargingType = null;
if (usbCharge) {
chargingType = "USB";
} else if (acCharge) {
chargingType = "AC Power";
}
if (isCharging && chargingType != null) {
Toast.makeText(context, "Device is charging via: " + chargingType, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Device is charging.", Toast.LENGTH_SHORT).show();
}
break;
}
case (Intent.ACTION_POWER_DISCONNECTED): {
Log.i(TAG, "Power disconnected");
Toast.makeText(context, "Power Disconnected", Toast.LENGTH_SHORT).show();
break;
}
case (Intent.ACTION_BATTERY_LOW): {
Log.i(TAG, "Battery low");
Toast.makeText(context, "Battery low", Toast.LENGTH_SHORT).show();
break;
}
case (Intent.ACTION_BATTERY_OKAY): {
Log.i(TAG, "Battery Okay");
Toast.makeText(context, "Battery Okay", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
I think it's pretty late but the solution is quite simple. According to this link, you will not receive updates for BATTERY_CHANGED if you have registered the broadcast receiver in xml since it's a sticky broadcast.
You need to register Broadcastreceivers in your java program as below.
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = (level * 100) / (float)scale;
NOTE: Even though you pass "null" as the receiver you can still receive all the required battery data. You can also pass a Receiver class instead of "null" for continuous monitoring but beware this will drain your device battery as these broadcasts are thrown very often.
Since you are listening for multiple broadcasts, you need to determine which type of broadcast it is.
String action = intent.getAction();
if(action.equals(Intent.ACTION_BATTERY_CHANGED)){
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = (level*100)/scale;
Toast.makeText(context, "Current battery level: " + percent + "%", Toast.LENGTH_SHORT).show();
}
boolean acCharge = false;
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
if(isCharging){
chargePercentage =
batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
}
The chargePercentage variable will give you the current charge percentage.
Related
I have register battery low broadcast receiver.
Like this
import com.save.sharedpreference.SharedPreference;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsManager;
import android.widget.Toast;
public class BootReceiver extends BroadcastReceiver {
String user_phone_key = "phone_number";
int last_level = 0;
#Override
public void onReceive(Context context, Intent intent) {
int rlevel = intent.getIntExtra("level", -1);
int scale = intent.getIntExtra("scale", -1);
int level = -1;
if (rlevel >= 0 && scale > 0) {
level = (rlevel * 100) / scale;
}
if (level == 48 && last_level == level + 1) {
SharedPreference save_data = new SharedPreference(
context.getApplicationContext());
String phone = save_data.get_string(user_phone_key, null);
Toast.makeText(context, "Level Decrease", Toast.LENGTH_SHORT)
.show();
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone, null,
"Your Battery level is less ", null, null);
} catch (Exception e) {
Toast.makeText(context.getApplicationContext(),
"SMS faild, please try again later!", Toast.LENGTH_LONG)
.show();
e.printStackTrace();
}
}
last_level = level + 1;
}
}
Its working fine but the problem is when my battery level is reach 45% it start sending me sms until battery level change from 45%.
I want that when my battery level is reach 45% it just send me sms only one time and again waiting when battery level is 45%.
Is it possible?
Any help please.
Can you just use a local variable, like this?
public class BootReceiver extends BroadcastReceiver {
String user_phone_key = "phone_number";
int last_level = 0;
#Override
public void onReceive(Context context, Intent intent) {
int rlevel = intent.getIntExtra("level", -1);
int scale = intent.getIntExtra("scale", -1);
int level = -1;
if (rlevel >= 0 && scale > 0) {
level = (rlevel * 100) / scale;
}
if (level == 45 && last_level == 46) {
...
last_level = level;
}
}
I know it's not the most elegant solution, but it should work.
The more "official" solution is to use the ACTION_BATTERY_LOW intent to detect charge decreases, which IIRC only fires once, when the device hits low battery. Is there a reason you need to detect the battery level hitting 45%, in particular?
Create a boolean variable to send message only once.Like-
boolean isMsgSent=false;
and modify if loop as-
if(level==45 && !isMsgSent){
// send Msg
isMsgSent=true;
}
else{
isMsgSent=false;
}
It will send message only once when battery level is 45.
I am using this code to show battery level in my app. It works fine but doesn't update battery level automatically.
What should I do to update the battery level automatically.
public class MainActivity extends Activity {
private TextView txtBattery;
private BroadcastReceiver mBatteryLevelReciver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
context.unregisterReceiver(this);
//int rawLevel = intent.getIntExtra("level", -1);
int rawLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
//int scale = intent.getIntExtra("scale", -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
int level = -1;
if (rawLevel >= 0 && scale > 0) {
level = (rawLevel * 100) / scale;
}
txtBattery.setText("Battery3 Level Remaining :" + level + "%");
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtBattery = (TextView) findViewById(R.id.batterymeter_txt);
batteryLevel();
}
private void batteryLevel() {
IntentFilter batteryLevelFliter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(mBatteryLevelReciver, batteryLevelFliter);
}
}
Move the receiver variable to be a class attribute so it will be in memory when the intent is received:
public class Main extends Activity {
private TextView txtBattery;
private BroadcastReceiver mBatteryLevelReciver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//int rawLevel = intent.getIntExtra("level", -1);
int rawLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
//int scale = intent.getIntExtra("scale", -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
int level = -1;
if (rawLevel >= 0 && scale > 0) {
level = (rawLevel * 100) / scale;
}
txtBattery.setText("Battery Level Remaining :" + level + "%");
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtBattery = (TextView) findViewById(R.id.batterymeter_txt);
batteryLevel();
}
private void batteryLevel() {
IntentFilter batteryLevelFliter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryLevelReciver, batteryLevelFliter);
}
Why do you unregister your BroadcastReceiver in your onReceive() method?
context.unregisterReceiver(this);
Remove that.
try this code..
public class AndroidBattery extends Activity {
private TextView batteryLevel, batteryVoltage, batteryTemperature,
batteryTechnology, batteryStatus, batteryHealth;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
batteryLevel = (TextView)findViewById(R.id.batterylevel);
batteryVoltage = (TextView)findViewById(R.id.batteryvoltage);
batteryTemperature = (TextView)findViewById(R.id.batterytemperature);
batteryTechnology = (TextView)findViewById(R.id.batterytechology);
batteryStatus = (TextView)findViewById(R.id.batterystatus);
batteryHealth = (TextView)findViewById(R.id.batteryhealth);
this.registerReceiver(this.myBatteryReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
private BroadcastReceiver myBatteryReceiver
= new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
if (arg1.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){
batteryLevel.setText("Level: "
+ String.valueOf(arg1.getIntExtra("level", 0)) + "%");
batteryVoltage.setText("Voltage: "
+ String.valueOf((float)arg1.getIntExtra("voltage", 0)/1000) + "V");
batteryTemperature.setText("Temperature: "
+ String.valueOf((float)arg1.getIntExtra("temperature", 0)/10) + "c");
batteryTechnology.setText("Technology: " + arg1.getStringExtra("technology"));
int status = arg1.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
String strStatus;
if (status == BatteryManager.BATTERY_STATUS_CHARGING){
strStatus = "Charging";
} else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING){
strStatus = "Dis-charging";
} else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING){
strStatus = "Not charging";
} else if (status == BatteryManager.BATTERY_STATUS_FULL){
strStatus = "Full";
} else {
strStatus = "Unknown";
}
batteryStatus.setText("Status: " + strStatus);
int health = arg1.getIntExtra("health", BatteryManager.BATTERY_HEALTH_UNKNOWN);
String strHealth;
if (health == BatteryManager.BATTERY_HEALTH_GOOD){
strHealth = "Good";
} else if (health == BatteryManager.BATTERY_HEALTH_OVERHEAT){
strHealth = "Over Heat";
} else if (health == BatteryManager.BATTERY_HEALTH_DEAD){
strHealth = "Dead";
} else if (health == BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE){
strHealth = "Over Voltage";
} else if (health == BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE){
strHealth = "Unspecified Failure";
} else{
strHealth = "Unknown";
}
batteryHealth.setText("Health: " + strHealth);
}
}
};
}
I have a battery widget, and for some reason it does not receive the BATTERY_PLIGGED_AC integer when the phone is plugged into AC.
I have another widget for the BATTERY_PLUGGED_USB which works just fine.
I can't see anything wrong with my code:
public void onReceive(Context context, Intent intent) {
status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
batterylevel = intent.getIntExtra("level", 0);
updateAppWidget(context);
}
public void updateAppWidget(Context context){
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.androidbatterywidget_layout);
updateViews.setTextViewText(R.id.textView1, " " + batterylevel + "%");
if (status == BatteryManager.BATTERY_PLUGGED_USB)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.usb);
else if (status == BatteryManager.BATTERY_PLUGGED_AC)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.bolt);
else
updateViews.setImageViewResource(R.id.imageView2, R.drawable.empty);
Hopefully someone will be able to spot what I have done wrong. Thanks!
Figured a way around. Sorry for this post I should have looked at it for a little longer myself. For future reference if people seem to have the same problem, it seems to me that the USB value is bundled with the BatteryManager.BATTERY_STATUS_UNKNOWN, but not the AC. So instead all i did was assign a new private int charging, to the value of the BatteryManager.BATTERY_PLUGGED_AC variable. If this is true (and the device is charging throygh AC), then the value is 1, so I simply replaced my previous if statement with
if (charging == 1)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.bolt);
Now the code reads;
private int batterylevel = 0;
private int status;
private int charging;
private BroadcastReceiver myReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
status = intent.getIntExtra("status", BatteryManager.BATTERY_HEALTH_UNKNOWN);
charging = intent.getIntExtra("plugged", BatteryManager.BATTERY_PLUGGED_AC);
batterylevel = intent.getIntExtra("level", 0);
updateAppWidget(context);
}
public void updateAppWidget(Context context){
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.androidbatterywidget_layout);
updateViews.setTextViewText(R.id.textView1, " " + batterylevel + "%");
if (charging == 1)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.bolt);
else if (status == BatteryManager.BATTERY_PLUGGED_USB)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.usb);
else
updateViews.setImageViewResource(R.id.imageView2, R.drawable.empty);
Im sure that there is a far more "majestic" way to do this, but i was just puzzled at why the USB int was passed if it was plugged into USB (2), but not the AC (1).
Thanks!
I want more information about android.permission.BATTERY_STATS . what possibilities grants the permission android.permission.BATTERY_STATS. I know how to use it if I can read the android.intent.action.BATTERY_CHANGED intent for the battery levels without declare such permission.
use this code that will get you the amount of battery used, the battery voltage, and its temperature.
#Override
public void onCreate() {
BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
int scale = -1;
int level = -1;
int voltage = -1;
int temp = -1;
#Override
public void onReceive(Context context, Intent intent) {
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
Log.e("BatteryManager", "level is "+level+"/"+scale+", temp is "+temp+", voltage is "+voltage);
}
};
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryReceiver, filter);
}
I've been searching for this and only find really messed up things.
Isn't there a easy way to show the battery level like 21% on a toast or Textview?
Or how can i achieve this?
//Simon
To get the battery level right now, call:
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
(note: typing that in from memory, please adjust if needed)
This will return an Intent with various extras documented on the BatteryManager class. Use BatteryManager.EXTRA_LEVEL and BatteryManager.EXTRA_SCALE to determine the percentage remaining.
If you need to know over a period of time as the battery changes, use the BroadcastReceiver approach #Augusto outlined in his answer.
if you mean changing the battery status on the emulator do the following. Connect to the emulator via telnet and change the status and capacity
> telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
power ac off
OK
power discharging
OK
power capacity 21
OK
exit
>
Ahh, well you can do what it says on the page Ted mentioned, and then use a handler to show a toast. This is the code you need to add to your activity.
private Handler handler = new Handler;
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
Log.i(TAG, "level: " + level + "; scale: " + scale);
int percent = (level*100)/scale;
final String text = String.valueOf(percent) + "%";
handler.post( new Runnable() {
public void run() {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
});
}
};
public static String batteryLevel(Context context)
{
Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = (level*100)/scale;
return String.valueOf(percent) + "%";
}
You can use this.
private void batteryLevel() {
BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//context.unregisterReceiver(this);
int rawlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
int level = -1;
if (rawlevel >= 0 && scale > 0) {
level = (rawlevel * 100) / scale;
}
batterLevel.setText("Battery Level Remaining: " + level + "%");
}
};
IntentFilter batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryLevelReceiver, batteryLevelFilter);
}
I used a combination like that:
BatteryManager bm = (BatteryManager) getActivity().getSystemService(BATTERY_SERVICE);
int batLevel = 100;
int level;
int scale;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
}
if(batLevel == 0){
Intent intent = getActivity().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
batLevel = (level*100)/scale;
}
I did it like that because on a Nexus 5 device with Marshmallow "batLevel" returned 0 always. That solved it completely!
Good luck