title: Android - Calculating Battery Charging or Discharging rate
body: <p>I am trying to calculate battery charging or discharging rate. I use ACTION_BATTERY_CHANGED to receive the event and I wait for minimum 1% change. Then I divide difference in battery level by difference in time (milliseconds). I multiply the result by 1000 * 60 * 60 to show the rate in "% per hour unit". But I am not sure if I am doing it right or there's some mistake. Because, sometimes it shows charging or discharging at around 6% or 15% which seems right. But sometimes it shows around 15000%.</p>
  
  <p>So can anyone please tell me what's wrong with this code.</p>
  
  <p>Here's my code:</p>
  
  <p>Registering:</p>
  
  <pre><code>IntentFilter batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
  registerReceiver(new EnReceiverOnBatteryChange(), batteryLevelFilter)
  </code></pre>
  
  <p>Receiver:</p>
  
  <pre><code>public class EnReceiverOnBatteryChange extends BroadcastReceiver
  {
      @Override
      public void onReceive(Context context, Intent intent)
      {
          Utils.recordChargeOrDischargeRate(context);
          ActivityHome.updateBatteryInfo(context);
      }
  }
  </code></pre>
  
  <p>Calculation:</p>
  
  <pre><code>public static void recordChargeOrDischargeRate(Context context)
  {
      long lCurrentTime = System.currentTimeMillis();
      float fCurrentBatteryLevel = 0;
  
      float fRate = 0;
      if ((mfLastBatteryLevel != -1) &amp;&amp; (mlLastTime != -1))
      {
          SharedPreferences preferences = context.getSharedPreferences(Konstant.PREFERENCES_FILE_NAME, Context.MODE_PRIVATE);
          SharedPreferences.Editor prefEditor = preferences.edit();
  
          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);
  
          if (level != -1 &amp;&amp; scale != -1)
          {
              fCurrentBatteryLevel = 100 * level / (float) scale;
          }
  
          float fBatteryLevelDifference = Math.abs(fCurrentBatteryLevel - mfLastBatteryLevel);
          if (fBatteryLevelDifference &gt; 0.99)
          {
              fRate = (fBatteryLevelDifference / (lCurrentTime - mlLastTime)) * 1000 * 60;
  
              prefEditor.putString(Konstant.KEY_PREF_CHARGING_START_RATE, String.format("%.2f", (fRate * 60)) + "%");
              prefEditor.commit();
  
              int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
              boolean isCharging = (status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL);
  
              if (isCharging)
              {
                  int nMinutes = Math.round((100 - fCurrentBatteryLevel) / fRate);
                  int nHour = nMinutes / 60;
                  nMinutes = nMinutes % 60;
                  prefEditor.putString(Konstant.KEY_PREF_FULL_CHARGE_IN, nHour + "h " + nMinutes + "m");
                  prefEditor.commit();
              }
              else
              {
                  int nMinutes = Math.round(fCurrentBatteryLevel / fRate);
                  int nHour = nMinutes / 60;
                  nMinutes = nMinutes % 60;
                  prefEditor.putString(Konstant.KEY_PREF_FULL_CHARGE_IN, nHour + "h " + nMinutes + "m");
                  prefEditor.commit();
              }
  
              mlLastTime = lCurrentTime;
              mfLastBatteryLevel = fCurrentBatteryLevel;
          }
      }
      else
      {
          mlLastTime = lCurrentTime;
          mfLastBatteryLevel = fCurrentBatteryLevel;
      }
  }
  </code></pre>