registerreceiver - Servicios de Android: START_STICKY no funciona en Kitkat
send broadcast android (5)
Estoy usando los servicios en una aplicación para escuchar cuántas veces el usuario presiona su botón de encendido. La implementación estaba funcionando bien en todos los dispositivos. Pero cuando probé la aplicación en el Android Kitkat, noté que algo andaba mal.
Tan pronto como deslizo la aplicación fuera de las aplicaciones recientes, la aplicación ya no escucha el botón de encendido.
Aquí está el código con el que estoy trabajando:
public class Receiver extends Service {
Notification notification;
private static final int NOTIFICATION_ID = 0;
NotificationManager manager;
PendingIntent toOpen;
Intent intent;
private BroadcastReceiver POWER_BUTTON = new Powerbuttonrecceiver();
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(POWER_BUTTON, filter);
startNotify();
return START_STICKY;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
unregisterReceiver(POWER_BUTTON);
dismissNotification();
super.onDestroy();
}
public void startNotify(){
manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.ic_launcher_drop;
CharSequence tickerText = "Service activated";
CharSequence tickerContent = "Service is now on. You can press your power button and the app will listen to it. Tap to turn this feature off";
intent = new Intent(Receiver.this, Options.class);
toOpen = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
notification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle(tickerText)
.setContentText(tickerContent)
.setSmallIcon(icon)
.setOngoing(true)
.setContentIntent(toOpen)
.build();
manager.notify(NOTIFICATION_ID, notification);
}
public void dismissNotification(){
manager.cancel(NOTIFICATION_ID);
}
}
Como se puede observar, estoy usando una notificación para indicar que el servicio está activo. Lo que me confunde es que después de pasar de la aplicación Recents la notificación sigue siendo válida, ¿qué está inactivo es BroadcastReceiver
? o eso es falso
En la aplicación onDestroy
no he llamado a ninguna función para registrar o onDestroy
registro, así como para detener el servicio. Una vez más, este problema solo se ve en Android KitKat. Por favor, si ustedes saben qué está pasando. Hacer ayuda :)
ACTUALIZACIÓN : También noté que con Play Music
en Kitkat, cuando lo aparto de la aplicación de los últimos momentos, la música se detiene. ¿Es esto un error en Kitkat? Pero los servicios de sound / mediaplayer en SoundCloud
funcionan incluso cuando se los quita de la aplicación Recents.
ACTUALIZACIÓN: registrado como Issue 63618 en el rastreador de problemas de Android. Lea los comentarios de la edición para más detalles.
Esto sigue siendo un error abierto para KK,
Parece que este es un error presente en Android 4.4
, lo solucioné con lo siguiente:
@Override
public void onTaskRemoved(Intent rootIntent) {
// TODO Auto-generated method stub
Intent restartService = new Intent(getApplicationContext(),
this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +1000, restartServicePI);
}
Por lo tanto, este es un método que se invalida en la propia clase de Service
. La razón por la que estoy usando el AlarmManager
es para que Kitkat
no AlarmManager
mi servicio.
Si no puede reiniciar el servicio, llame a un administrador de alambres para iniciar el receptor de esta manera.
Manifiesto es,
<service
android:name=".BackgroundService"
android:description="@string/app_name"
android:enabled="true"
android:label="Notification" />
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="REFRESH_THIS" />
</intent-filter>
</receiver>
IN Activity principal iniciar el pesebre de alarma de esta manera
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) getSystemService(alarm);
Intent intent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);
int type = AlarmManager.RTC_WAKEUP;
long interval = 1000 * 50;
am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);
Esto llamará Reciver y Reciver es,
public class AlarmReceiver extends BroadcastReceiver {
Context context;
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
System.out.println("Alarma Reciver Called");
if (isMyServiceRunning(this.context, BackgroundService.class)) {
System.out.println("alredy running no need to start again");
} else {
Intent background = new Intent(context, BackgroundService.class);
context.startService(background);
}
}
public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
if (services != null) {
for (int i = 0; i < services.size(); i++) {
if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
return true;
}
}
}
return false;
}
}
Y este receptor de Alaram llama una vez cuando se abre la aplicación de Android y cuando se cierra la aplicación. El servicio es así,
public class BackgroundService extends Service {
private String LOG_TAG = null;
@Override
public void onCreate() {
super.onCreate();
LOG_TAG = "app_name";
Log.i(LOG_TAG, "service created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "In onStartCommand");
//ur actual code
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// Wont be called as service is not bound
Log.i(LOG_TAG, "In onBind");
return null;
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(LOG_TAG, "In onTaskRemoved");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "In onDestroyed");
}
}
Tengo esta solución que funciona perfectamente.
@Override
public void onDestroy() {
startService(new Intent(yourcontext, YourService.class));
}
prueba mi solución: this
Este truco reiniciará su servicio cada vez que el usuario cierre el servicio desde el administrador de tareas y forzará el cierre de la configuración. Espero que esto también lo ayude.