web-dev-qa-db-fra.com

Gardez le récepteur de diffusion en marche après la fermeture de l'application

Je dois garder le récepteur de diffusion en marche tout le temps après le démarrage de l'application.

Voici le code qui enregistre ce récepteur dans l'application

    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
    filter.addAction(Intent.ACTION_SCREEN_OFF);
    BroadcastReceiver mReceiver = new ScreenEventsReceiver();
    registerReceiver(mReceiver, filter);

Et le code du récepteur

public class ScreenEventsReceiver extends BroadcastReceiver {
     public static boolean wasScreenOn = true;

     @Override
     public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            wasScreenOn = false;
            Log.d("ScreenEventReceiver", "ON");
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            wasScreenOn = true;
            Log.d("ScreenEventReceiver", "ON");
        }
     }
}
28
Sergey Pekar

Vous pouvez utiliser un service

Dans l'application principale, démarrez/arrêtez le service

Intent service = new Intent(context, MyService.class);
context.startService(service);
...
Intent service = new Intent(context, MyService.class);
context.stopService(service);

un service

public class MyService extends Service
{
 private static BroadcastReceiver m_ScreenOffReceiver;

 @Override
 public IBinder onBind(Intent arg0)
 {
  return null;
 }

 @Override
 public void onCreate()
 {
  registerScreenOffReceiver();
 }

 @Override
 public void onDestroy()
 {
  unregisterReceiver(m_ScreenOffReceiver);
  m_ScreenOffReceiver = null;
 }

 private void registerScreenOffReceiver()
 {
  m_ScreenOffReceiver = new BroadcastReceiver()
  {
   @Override
   public void onReceive(Context context, Intent intent)
   {
     Log.d(TAG, "ACTION_SCREEN_OFF");
     // do something, e.g. send Intent to main app
   }
  };
  IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
  registerReceiver(m_ScreenOffReceiver, filter);
 }
}
27
j.holetzeck

La réponse acceptée n'est pas une réponse réelle, je pense. Je vais vous expliquer quel est le problème. Je pense que vous testez votre application dans le Huawie, Oppo, Vivo, Xiomi, asus ....... ou certains appareils. Avec ces appareils, si nous fermons l'application, ils fermeront également nos récepteurs de diffusion. C'est donc le problème. (Pour vérifier que vous utilisez un émulateur nexus avec pixel). Je vais vous expliquer comment résoudre ce problème. ''

  • nous ajouterions notre application à la liste des applications protégées. Le système d'exploitation ne leur permet que de poursuivre les activités de diffusion du récepteur. (Copiez cette déclaration de tableau dans votre code)

    private static final Intent[] POWERMANAGER_INTENTS = {
        new Intent().setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")),
        new Intent().setComponent(new ComponentName("com.letv.Android.letvsafe", "com.letv.Android.letvsafe.AutobootManageActivity")),
        new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
        new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
        new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
        new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")),
        new Intent().setComponent(new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity")),
        new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")),
        new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")),
        new Intent().setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")),
        new Intent().setComponent(new ComponentName("com.samsung.Android.lool", "com.samsung.Android.sm.ui.battery.BatteryActivity")),
        new Intent().setComponent(new ComponentName("com.htc.pitroad", "com.htc.pitroad.landingpage.activity.LandingPageActivity")),
        new Intent().setComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.MainActivity"))};
    
  • Mettez ces codes dans votre méthode onCreate. Ici, j'ai utilisé la préférence partagée pour le vérifier uniquement la première fois que l'application est ouverte.

final SharedPreferences.Editor pref = getSharedPreferences("allow_notify", MODE_PRIVATE).edit(); pref.apply(); final SharedPreferences sp = getSharedPreferences("allow_notify", MODE_PRIVATE);

if(!sp.getBoolean("protected",false)) {
    for (final Intent intent : POWERMANAGER_INTENTS)
        if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {

        AlertDialog.Builder builder  = new AlertDialog.Builder(this);
        builder.setTitle("Alert Title").setMessage("Alert Body")
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        startActivity(intent);
                        sp.edit().putBoolean("protected",true).apply();

                    }
                })
                .setCancelable(false)
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                })
                .create().show();
        break;
8
Tharuka Lakshan

Si vous déclarez BroadcastReceiver dans le manifeste, il sera toujours actif et sera appelé même si l'application est fermée/arrêtée

4
Abraham

Vous ne pouvez pas recevoir certains événements de diffusion via les composants déclarés dans le manifeste.

Ces événements sont

  • ACTION_BATTERY_CHANGED
  • ACTION_CONFIGURATION_CHANGED
  • ACTION_SCREEN_OFF (Vous jouez avec cet événement)
  • ACTION_SCREEN_ON (Vous jouez avec cet événement)
  • ACTION_TIME_TICK

Référence https://developer.Android.com/reference/Android/content/Intent.html#ACTION_SCREEN_ON

Donc, dans vos événements spécifiques , vous devrez créer un service et vous devrez enregistrer votre événement explicitement dans le service onCreate () avec avec Context.registerReceiver ().

Pour les autres événements , l'entrée dans le manifeste est suffisante.

2
Vivek A Naik

Soyez prudent si vous utilisez Android 4.4.x car il y a un bogue qui tue les services d'arrière-plan lors de la fermeture de l'application. Je testais mon application dans Android 4.4 .2 et j'ai eu le même problème. Voici une explication détaillée:

http://www.androidpolice.com/2014/03/07/bug-watch-stopping-apps-on-Android-4-4-2-can-silently-kill-related-background-services- a-fix-is-on-the-way /

Vous pouvez démarrer un service qui s'exécute au premier plan. C'est le seul moyen de garantir (principalement) que votre application recevra les événements. Il y a toujours une chance que votre service de premier plan soit tué en période de pression folle sur la mémoire du système d'exploitation (donc ce n'est pas infaillible). Si vous démarrez un service au premier plan, l'utilisateur verra une notification persistante pour savoir qu'il est toujours en cours d'exécution, cependant.

Donc, la morale de l'histoire est la suivante: avez-vous vraiment besoin de surveiller les événements de mise sous/hors tension de l'écran à tout moment? La raison pour laquelle ils vous obligent à enregistrer un récepteur ne figurant pas dans le manifeste est qu'ils ne veulent pas que les gens surveillent toujours ces événements et ralentissent l'appareil. Qu'est-ce que vous essayez d'accomplir?

1
natez0r