web-dev-qa-db-fra.com

Android BOOT_COMPLETED non reçu à la fermeture de l'application

Je suis conscient que cette question a été beaucoup posée sur le site, cependant, je ne semble pas pouvoir trouver une solution. Mon destinataire BOOT_COMPLETED n'est pas appelé lorsque l'application n'est pas en cours d'exécution.

Manifeste:

<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
    package="com.example.startuptest"
    Android:versionCode="1"
    Android:versionName="1.0"
    Android:installLocation="internalOnly">
    <uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-sdk Android:minSdkVersion="8" Android:targetSdkVersion="17" />

    <application
        Android:allowBackup="true"
        Android:icon="@drawable/ic_launcher"
        Android:label="@string/app_name"
        Android:theme="@style/AppTheme" >
        <activity
            Android:name="com.example.startuptest.MainActivity"
            Android:label="@string/app_name" >
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />
                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver Android:name="com.example.startuptest.StartUpBootReceiver" >
            <intent-filter>
                <action Android:name="Android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

StartUpBootReceiver:

public class StartUpBootReceiver  extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        Log.d("startuptest", "StartUpBootReceiver " + intent.getAction());

        if ("Android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
            Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
        }
    }
}

Si l'application est en cours d'exécution et que je simule un appel avec

adb Shell
am broadcast -a Android.intent.action.BOOT_COMPLETED

L'événement est correctement reçu. Toutefois, si l'application est fermée, l'événement n'est pas reçu ni reçu au démarrage.

J'ai installé l'application, puis je l'ai lancée plusieurs fois pour m'assurer qu'elle est bien enregistrée. Je suis assez perdu sur celui-ci alors tout conseil serait très apprécié.

Edit: Je vois dans les journaux que toutes les autres applications fermées (Youtube, FileObserver, etc.) reçoivent l'événement boot_completed, mais pas le mien.

25
user346443

Je lance mon application lorsque BOOT_COMPLETED, alors je sais que cela fonctionne. J'ajoute Log.d ça ne s'affichera pas. J'ajoute Toast ça montre. Petites différences dans Manifest.xml

<receiver Android:name="com.example.startuptest.StartUpBootReceiver" Android:enabled="true" Android:exported="true">
    <intent-filter>
         <action Android:name="Android.intent.action.BOOT_COMPLETED" />
         <category Android:name="Android.intent.category.DEFAULT" />
    </intent-filter>            
</receiver>
35
Gina

À partir de Android 3.1, toutes les applications, lors de l’installation, sont placées dans un état "stoppé". application.) 

Android stopped state

En état "arrêté", l'application ne s'exécutera pas pour une raison quelconque, sauf lors du lancement manuel d'une activité. (Ce qui signifie non BroadcastReceviers (ACTION_PACKAGE_INSTALLED, BOOT_COMPLETED etc.) sera invoqué, quel que soit l'événement pour lequel ils ont été enregistrés, jusqu'à ce que l'utilisateur exécute l'application manuellement.)

Ceci est un geste anti-malware de Google. Google a préconisé que les utilisateurs lancent d'abord une activité à partir du programme de lancement, avant que cette application puisse faire beaucoup. Empêcher la transmission de BOOT_COMPLETED jusqu'au lancement de l'activité est une conséquence logique de cet argument.

Plus de détails à ce sujet:
http://developer.Android.com/about/versions/Android-3.1.html#launchcontrols
http://commonsware.com/blog/2011/07/05/boot-completed-regression.html
http://devmaze.wordpress.com/2011/12/05/activating-applications/

89
Caner

Chaque réponse ici ajoute une petite information, voici donc le résumé de tout cela:

Pour vous assurer que vous recevrez le message BOOT_COMPLETED, procédez comme suit:

  1. Ajoutez votre destinataire à manifester (n'oubliez pas les flags ):

    <receiver Android:name="com.yourpacakge.BootReceiver" Android:exported="true" Android:enabled="true">
        <intent-filter>
            <action Android:name="Android.intent.action.BOOT_COMPLETED"/>
            <category Android:name="Android.intent.category.DEFAULT"/>
        </intent-filter>
    </receiver>
    
  2. Ajouter une permission:

    <uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED"/>

  3. Après avoir installé votre application, il doit être déjeuné au moins une fois, manuellement par l'utilisateur, afin de recevoir l'événement Boot complete. ( Plus de détails )

26
Ilya Gazman

avait le même problème, la raison en est que vous utilisez Log.d pour suivre votre application dans logcat; malheureusement, lorsque vous redémarrez votre téléphone, l'application reçoit le BOOT_Complete mais vous ne pouvez pas le voir. car il ne se connecte pas à logcat.

essayez de créer une Toast avec du texte au lieu de Log.d pour vous assurer que BOOT_COMPLETED est ou n'est pas reçu.

espérons que cette aide.

1
Tarek K. Ajaj

Heres une C # version si vous le voulez. Mes tests montrent que cela fonctionne assez bien et que le démarrage est assez rapide ..__ Bien que noter qu’ajouter à la fois dans C # et dans AndroidManifest.xml le casse (du moins pour moi).

J'ai également ajouté quelques exemples intéressants et utiles que je souhaiterais avoir découverts par quelqu'un au lieu de l'apprendre moi-même lors de la lecture des documentaires et autres.

[BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true, Name = "com.nevaran.startup.StartUpBootReceiver")]
[IntentFilter(new string[] {
    Intent.ActionBootCompleted
    , Intent.ActionLockedBootCompleted
    , Intent.ActionMyPackageReplaced
    , Intent.ActionUserInitialize
    , "Android.intent.action.QUICKBOOT_POWERON"
    , "com.htc.intent.action.QUICKBOOT_POWERON"
})]
public class BootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
         if(    intent.Action.Equals(Intent.ActionBootCompleted)
             || intent.Action.Equals(Intent.ActionLockedBootCompleted)
             || intent.Action.Equals(Intent.ActionUserInitialize)
             || intent.Action.Equals("Android.intent.action.QUICKBOOT_POWERON")
             || intent.Action.Equals("com.htc.intent.action.QUICKBOOT_POWERON")
           )
        {
            //run code here only if its started by the chosen actions
        }
        //some code that doesnt care about which action is triggered by
    }
}
1
Nevaran

Pour résoudre ce problème, vous pouvez utiliser firebaseJobDispatcher pour appeler automatiquement. FirebaseJobDispatcher disposera d'un code pour réactiver vos services. Oui, après un certain temps, les services peuvent être arrêtés par le système d'exploitation, mais firebaseJobDispatcher réactivera vos services. FirebaseJobDispatcher a beaucoup de propriétés à partir desquelles vous pouvez définir la portée de ceci;

comment ça marche, pour plus de détails https://github.com/firebase/firebase-jobdispatcher-Android

0
Abdul Rizwan

Si vous souhaitez connaître la raison réelle pour laquelle BOOT_COMPLETE ne fonctionne pas ou ne reçoit pas. Je vous suggérerai d'aller sur le site officiel de développement Android. Ils ont expliqué avec la solution exacte.

Développeur Android - BOOT_COMPLETE

0
Sankar Behera