title: Android BroadcastReceiver android.intent.action.BATTERY_CHANGED
body: <p>I am able to listen for the Intent <code>Intent.ACTION_BATTERY_CHANGED</code> within my activity and it works great. I tried defining the receiver in the manifest:</p>
  
  <pre><code>&lt;receiver android:name="com.beargreaves.battery.BatteryReceiver"&gt; 
      &lt;intent-filter&gt; 
          &lt;action android:name="android.intent.action.BATTERY_CHANGED" /&gt;
      &lt;/intent-filter&gt; 
  &lt;/receiver&gt;
  </code></pre>
  
  <p>but it didn't work, I read a post on here saying that it must be defined programmatically. Rather than registering for the receiver in my Activity, I wanted to achieve this in a Service so that it continually monitors. I have successfully achieved this, and it works, but I wanted to check my working to see if it is the correct approach.</p>
  
  <p>I started by extending BroadcastReceiver:</p>
  
  <pre><code>public class BatteryReceiver extends BroadcastReceiver{
      @Override
      public void onReceive(Context context, Intent intent) {
          Bundle bundle = intent.getExtras();
  
          if(null == bundle)
              return;
  
          boolean isPresent = intent.getBooleanExtra("present", false);
          String technology = intent.getStringExtra("technology");
          int plugged = intent.getIntExtra("plugged", -1);
          int scale = intent.getIntExtra("scale", -1);
          int health = intent.getIntExtra("health", 0);
          int status = intent.getIntExtra("status", 0);
          int rawlevel = intent.getIntExtra("level", -1);
          int level = 0;
  
          Log.d("Debug","Battery Receiver OnReceive");
  
          if(isPresent) {
              if (rawlevel &gt;= 0 &amp;&amp; scale &gt; 0) {
                  level = (rawlevel * 100) / scale;
  
                  Log.d("Debug","BatterReceiver: " + level);
  
                  Toast.makeText(context,"Battery Receiver: " + level + "\t" + status + "Raw: " + rawlevel,Toast.LENGTH_LONG).show();
  
                  if(level &lt;60) {
                      /*
                       * Only invoke the service when level below threshold
                       */
                      Intent i = new Intent(context, BatteryService.class);
                      i.putExtra("level", level);
                      context.startService(i);
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>And then I use a Service to first register the receiver in <code>onCreate()</code> and then handle the events in <code>onStart()</code>. My BroadcastReceiver starts the Service if the level is below a threshold.</p>
  
  <pre><code>public class BatteryService extends Service {
      /*
       * First Call to onStart we don't want to do anything
       */
      boolean avoidFirst = false;
      private BroadcastReceiver receiver;
  
      @Override
      public IBinder onBind(Intent intent) {
          // TODO Auto-generated method stub
          return null;
      }
  
      @Override
      public void onCreate() {
          super.onCreate();
  
          IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
          receiver = new BatteryReceiver();
          registerReceiver(receiver, filter);
      }
  
      @Override
      public void onStart(Intent intent, int startId) {
          Log.d("Debug","Battery Service On Start");
          int level = intent.getIntExtra("level", -1);
  
          if(avoidFirst) {
              if(level != -1) {
                  Log.d("Debug","Battery Alert Notifying..... " + level);
                  SMSManager.sendSMS(BatteryService.this, "&lt;number redacted&gt;", "Battery Level Aleart: " + level);
                  stopSelf();
              }
          } else {
              avoidFirst = true;
          }
      }
  
      @Override
      public void onDestroy() {
          // TODO Auto-generated method stub
          super.onDestroy();
          PreferenceUtil.updatePreference(BatteryService.this, "battery_monitor_on", false);
          unregisterReceiver(receiver);
      }
  }
  </code></pre>
  
  <p>Is this the correct approach? Be that register the receiver in <code>onCreate()</code> and then start the Service when an event is received. First I tried not using a Service but then I have no way of registering the receiver since it can't be achieved in the manifest. Secondly an exception was thrown when I tried to send a text message in the <code>onReceive()</code>. I read that <code>onReceive()</code> shouldn't be starting any threads. </p>
  
  <p>Thanks in advance</p>