3

Right now, I just want some sort of indication of battery status when the user access the apps. For example, if the device is plugged in, then the device should say charging and the level it's at. If the device is unplugged, nothing should be displayed. If the device is not charging and low battery, low battery indication should appear.

I've setup most of the code but the problem is, e.g., if I run the app and the device is plugged in, charging indication is shown on screen. If I unplug the device, charging is no longer visible but if I replug the device, charging is still no longer visible. The battery alerts should always display when the device is plugged or unplugged, high or low battery. Change in information should always be displayed.

So here's my broadcast receiver:

  private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver()  {

        @Override
        public void onReceive(Context arg0, Intent intent) {

            //Battery level
            int level = intent.getIntExtra("level", 0);

            //Plugged in Status
            int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);

            //Battery Status
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);

            //If the device is charging or contains a full status, it's charging
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                    status == BatteryManager.BATTERY_STATUS_FULL;

            //If the device isCharging and plugged in, then show that the battery is charging
            TextView batteryTextView = ((TextView) findViewById(R.id.charging));
            TextView batteryLowTextView = ((TextView) findViewById(R.id.low_battery));
            ImageView batteryLowImageView= ((ImageView) findViewById(R.id.low_battery_icon));
            ImageView batteryImageView =((ImageView) findViewById(R.id.charging_battery_icon));

            if (isCharging && plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB) {


                //Gets the 'last synced' string and sets to datetime of the last sync
                Resources resources = context.getResources();
                String chargingString = String.format(resources.getString(R.string.charging), level);

                //Dynamically sets the value of the battery level
                batteryLowTextView.setVisibility(TextView.INVISIBLE);
                batteryLowImageView.setVisibility(ImageView.INVISIBLE);
                batteryTextView.setText(chargingString + "%");

            } else if (level < LOW_BATTERY_LEVEL && !isCharging) {

                Resources resources = context.getResources();
                String lowBatteryString = String.format(resources.getString(R.string.low_battery));

                batteryTextView.setVisibility(TextView.INVISIBLE);
                batteryImageView.setVisibility(ImageView.INVISIBLE);
                batteryLowTextView.setText(lowBatteryString);

            } else if (!isCharging && level > LOW_BATTERY_LEVEL) {

                //do nothing
                batteryTextView.setVisibility(TextView.GONE);
                batteryImageView.setVisibility(ImageView.GONE);

            }

        }

    };

In my OnCreate method, I call

 //calls registerReceiver to receive the broadcast for the state of battery
            this.registerReceiver(this.mBatInfoReceiver,new
                    IntentFilter(Intent.ACTION_BATTERY_CHANGED));

So, I am wondering what I am doing wrong? Is it the bools?

Kala J
  • 2,040
  • 4
  • 45
  • 85
  • 5
    Shouldn't it be `if (isCharging && (plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB))`? Your `if` fails if `plugged == BatteryManager.BATTERY_PLUGGED_AC` evaluates to `false`. It will not even check if `plugged == BatteryManager.BATTERY_PLUGGED_USB`. So, place a bracket around the OR operands and see if that helps your problem. – Vikram Oct 03 '14 at 04:39

2 Answers2

5
  1. Your if-then-else logic has a lot of holes (and has the issue mentioned by @Vikram). That can cause the receiver to end up doing nothing. Try simplifying the logic to remove all the holes.
  2. When you update a text view, you also have to remember to make it (and its image view) visible first.

Here is a replacement for your if-then-else logic:

        if (isCharging) {

            //Gets the 'last synced' string and sets to datetime of the last sync
            Resources resources = context.getResources();
            String chargingString = String.format(resources.getString(R.string.charging), level);

            //Dynamically sets the value of the battery level
            batteryLowTextView.setVisibility(TextView.INVISIBLE);
            batteryLowImageView.setVisibility(ImageView.INVISIBLE);
            batteryTextView.setText(chargingString + "%");
            batteryTextView.setVisibility(TextView.VISIBLE);
            batteryImageView.setVisibility(ImageView.VISIBLE);

        } else if (level <= LOW_BATTERY_LEVEL) {

            Resources resources = context.getResources();
            String lowBatteryString = String.format(resources.getString(R.string.low_battery));

            batteryTextView.setVisibility(TextView.INVISIBLE);
            batteryImageView.setVisibility(ImageView.INVISIBLE);
            batteryLowTextView.setText(lowBatteryString);
            batteryLowTextView.setVisibility(TextView.VISIBLE);
            batteryLowImageView.setVisibility(ImageView.VISIBLE);

        } else {

            //show nothing
            batteryTextView.setVisibility(TextView.GONE);
            batteryImageView.setVisibility(ImageView.GONE);
            batteryLowTextView.setVisibility(TextView.GONE);
            batteryLowImageView.setVisibility(ImageView.GONE);
        }
cybersam
  • 63,203
  • 6
  • 53
  • 76
  • Thanks for your help. I didn't realize the missing parenthesis and thanks for clarifying the visibility bools. I am curious about one thing though, does if I turn the ac power on the AVD off, does the device automatically go to wireless charging? It seems to be the case but just want to be sure. Thanks. – Kala J Oct 03 '14 at 15:21
2

You AND isCharging with BatteryManager.BATTERY_PLUGGED_AC here:

if (isCharging && plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB) 

You need to OR the BatteryManager controls and AND the result with isCharging like:

if (isCharging && 
   (plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB))

If you need to know if the device is plugged essentially to AC or USB, you can use this method. However, the device could be plugged to BATTERY_PLUGGED_WIRELESS. Another thing is, isn't your isCharging variable already covers what you're trying to find out by:

(plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB)

I highly recommend reading this page and debug to control the values of the variables you operate with.

İsmet Alkan
  • 5,361
  • 3
  • 41
  • 64
  • No, it doesn't already cover the plugged in state. I tested this out by running the AVD and using "power ac off" in AVD and charging display was still showing. I need to add the plugged status to the if statement in order to cover all necessary cases. I can add the plugged wirelessly to the use case to cover wireless charging. Thanks for the tip! – Kala J Oct 03 '14 at 13:27