soy capaz de escuchar la Intención Intent.ACTION_BATTERY_CHANGED
dentro de mi actividad y funciona muy bien. He intentado definir el receptor en el manifiesto:Android BroadcastReceiver android.intent.action.BATTERY_CHANGED
<receiver android:name="com.beargreaves.battery.BatteryReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
</intent-filter>
</receiver>
pero no funcionó, leí un post aquí diciendo que se debe definir mediante programación. En lugar de registrarme para el receptor en mi actividad, quería lograr esto en un servicio para que supervise continuamente. Lo logré con éxito y funciona, pero quería verificar mi funcionamiento para ver si es el enfoque correcto.
empecé extendiendo BroadcastReceiver:
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 >= 0 && scale > 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 <60) {
/*
* Only invoke the service when level below threshold
*/
Intent i = new Intent(context, BatteryService.class);
i.putExtra("level", level);
context.startService(i);
}
}
}
}
}
Y entonces utilizar un servicio que registrarse primero en el receptor onCreate()
y luego controlar los eventos en onStart()
. My BroadcastReceiver inicia el servicio si el nivel está por debajo de un umbral.
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, "<number redacted>", "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);
}
}
¿Es este el enfoque correcto? Sea que registra el receptor en onCreate()
y luego inicie el Servicio cuando se recibe un evento. Primero intenté no usar un servicio, pero luego no tengo manera de registrar el receptor, ya que no se puede lograr en el manifiesto. En segundo lugar, se produjo una excepción cuando traté de enviar un mensaje de texto en el onReceive()
. Leí que onReceive()
no debería estar iniciando ningún subproceso.
Gracias de antemano
+1 por poner mi respuesta en su pregunta: D –