BroadcastReceiver empfängt BOOT_COMPLETED nicht

70

Ich habe mich hier nach ähnlichen Problemen umgesehen, aber aus irgendeinem Grund erhält mein BroadcastReceiver nie die Absicht android.intent.action.BOOT_COMPLETED.

Hier ist meine (relative) Android.Manifest-Datei:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>    
<receiver android:name=".BootReceiver"
        android:enabled="true"
        android:exported="true"
        android:label="BootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>

        </intent-filter>
    </receiver>

Und hier ist der eigentliche Empfänger.

public class BootReceiver extends BroadcastReceiver {
private static final String TAG="BootReceiver";

@Override public void onReceive(Context context,Intent intent){
    try{
        context.startService(new Intent(context,ConnectivityListener.class));
        Log.i(TAG,"Starting Service ConnectivityListener");
    }catch(Exception e){
        Log.e(TAG,e.toString());
    }
}
}

Vielen Dank! Jede Hilfe wird sehr geschätzt

apmeyers1987
quelle
1
Blinde Vermutung - Ihr Empfänger befindet sich nicht im Hauptpaket und es gibt kein Paket / Hauptpaket / BootReceiver.java, sondern Paket / Hauptpaket / Empfänger / BootReceiver.java, dh der Pfad zum Empfänger ist falsch.
Fiktion
Danke, ich habe nicht daran gedacht, das zu überprüfen, aber kein Glück, es ist definitiv im Standardpaket.
Apmeyers1987
Das gleiche Problem kann auftreten, wenn die Empfängerdeklaration android enthält: exported = "true" würde insgesamt einen neuen Prozess für den Empfänger erstellen. Ihr Logger (Log.i) druckt die Ergebnisse in einer neuen Konsole, die Sie unter Android Monitor (Android Studio) nicht einmal bemerken würden. Ich würde empfehlen, diese Aussage zu entfernen, es sei denn, Sie wissen, was es bedeutet.
Samuel Robert

Antworten:

167

Sie können alle Broadcast-Aktionen emulieren, indem Sie über adb eine Verbindung zum Gerät herstellen und eine Geräte-Shell öffnen.

Auf geht's:

  • Öffnen Sie die Konsole / das Terminal und navigieren Sie zu / platform-tools
  • Typ adb shelloder unter Linux / Mac./adb shell
  • im Shell-Typ am broadcast -a android.intent.action.BOOT_COMPLETEDoder in welcher Aktion auch immer Sie auslösen möchten

Es gibt eine Reihe netter Befehle, die mit adb oder der adb-Shell geliefert werden. Probier es einfach

Grüße Flo

edit: oh verdammt, ich wollte diese Antwort als Antwort auf "musste jedes Mal das Telefon ein- und ausschalten". Entschuldigung Leute

fklappan
quelle
6
Überhaupt nicht das, was die ursprüngliche Frage stellte (also keine Gegenstimme), trotzdem fand ich das sehr hilfreich, danke.
CoatedMoose
13
Wenn Sie dies in adb unter 4.2.2 ausführen, wird Ihr Gerät tatsächlich neu gestartet
Luke,
9
Die nützlichste zufällige Antwort aller Zeiten
Alessandro Roaro
27
Bei neueren Android-Versionen müssen Sie ausführen adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.mypackage.name. Ohne die Übertragung auf Ihre App zu beschränken, wird Ihr Gerät tatsächlich neu gestartet.
Klinge
7
Ich erhalte die folgende Fehlermeldung, wenn ich diesen Befehl Broadcasting: Intent { act=android.intent.action.BOOT_COMPLETED } java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.BOOT_COMPLETED from pid=3566, uid=2000
erteile
151

Ich poste dies in der Hoffnung, dass es für jemanden hilfreich sein wird, der alles versucht hat, es aber nach der Installation noch nicht zum Booten bringen kann oder früher funktioniert hat und nicht mehr funktioniert.

Angenommen, Sie haben die Berechtigung hinzugefügt:

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

Und Ihren Empfänger registriert:

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

Und codiert Ihre BroadcastReceiver:

public class StartUpBootReceiver extends BroadcastReceiver {

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

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

Ab Android 3.1 werden alle Anwendungen bei der Installation in den Status " Gestoppt " versetzt. (Dies ist derselbe Status, in dem die Anwendung endet, nachdem der Benutzer die App aus der Anwendung " Einstellungen " zwangsweise gestoppt hat .)

Android gestoppt Zustand

Im Status "Gestoppt" wird die Anwendung aus keinem Grund ausgeführt , außer durch manuelles Starten einer Aktivität. (Bedeutung nicht BroadcastRecevier( ACTION_PACKAGE_INSTALLED, BOOT_COMPLETEDusw. wird aufgerufen, unabhängig von der Veranstaltung , für die sie sich registriert haben, bis der Benutzer manuell die App läuft .)

Dies ist eine Designentscheidung von Google, um Malware-Apps zu verhindern. Google hat empfohlen, dass Nutzer zuerst eine Aktivität über den Launcher starten sollten, bevor diese Anwendung viel bewirken kann. Die BOOT_COMPLETEDlogische Konsequenz dieses Arguments ist die Verhinderung der Zustellung bis zum Start der Aktivität.

Sobald ein Benutzer eine Aktivität in Ihrer App einmal ausgeführt hat, erhalten Sie nach allen zukünftigen Startvorgängen die Broadcast BOOT_COMPLETED.

Weitere Details hierzu:
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/

Caner
quelle
8
+1 Dies ist eine großartige Antwort und mir war dies nicht bewusst. Eine relevante Information ist, dass seit 3.1 "... das System FLAG_EXCLUDE_STOPPED_PACKAGESzu allen Broadcast-Absichten beiträgt." Dies führt jedoch zu der in Ihrer Antwort beschriebenen Situation: "Ein Hintergrunddienst oder eine Hintergrundanwendung kann dieses Verhalten überschreiben, indem er die FLAG_INCLUDE_STOPPED_PACKAGES flagBroadcast-Absichten hinzufügt, die gestoppte Anwendungen aktivieren sollen." Ich muss dies jedoch noch testen: p (entnommen aus dem Link, den Sie unter developer.android.com/about/versions/… gepostet haben )
Dori
12
Es sollte klargestellt werden, dass Sie nach allen zukünftigen Startvorgängen die BOOT_COMPLETED-Übertragung erhalten, sobald ein Benutzer eine Aktivität in Ihrer App einmal ausführt. Die einzige Einschränkung besteht darin, dass der Benutzer, wenn er das Schließen Ihrer App erzwingt, diese manuell erneut starten muss, bevor Sie erneut BOOT_COMPLETED-Broadcasts empfangen.
Splaktar
@Dori Konnten Sie das Verhalten des Flags FLAG_INCLUDE_STOPPED_PACKAGES überprüfen?
ARK
addFlagsDies ist nur möglich, wenn Sie Ihre Aktivität zum ersten Mal gestartet haben. Daher wird die Notwendigkeit, die Anwendung zum ersten Mal zu starten, nicht umgangen.
tommed
1
Bleibt eine aktivierte App aktiviert, wenn sie auf eine neue Version aktualisiert wird? über App Store oder adb install -r?
BeniBela
57

Wenn Ihre App auf einem externen Speicher (SD-Karte) installiert ist , erhalten Sie niemals die Aktion "Boot abgeschlossen". So können Sie angeben müssen , android:installLocation="internalOnly"in der manifest tag.

Sundeep1501
quelle
Endlich habe ich verstanden, warum meine App beim Booten auf einigen Telefonen nicht gestartet wird, während sie auf anderen OK funktioniert. Es ging darum, auf welchem ​​Speicher standardmäßig Apps installiert werden.
Mixaz
1
Es funktioniert auch nicht auf meinem Lollipop 5.1.1-Gerät. Es ist nicht möglich, BOOT_COMPLETED zu verwenden, ohne die Aktivität zu starten.
Venugopal
14

Ihr <uses-permission>Element muss ein unmittelbares untergeordnetes <manifest>Element des Elements sein, und Ihre obige Codeliste weist darauf hin, dass dies nicht der Fall ist.

Hier ist ein Beispielprojekt , das die Verwendung von demonstriert BOOT_COMPLETED.

CommonsWare
quelle
Entschuldigung, es war oben ein wenig irreführend, da ich nur Ausschnitte aus dem Manifest genommen habe, da es sehr lang ist, aber die Nutzungserlaubnis ist ein direktes Kind von <manifest>
apmeyers1987
2
+1 für die Angabe der korrekten Position des <uses-permission> -Elements. Ich habe das falsch verstanden, als ich es als Kind von <application> hatte, das ohne Warnungen oder Fehler kompiliert wurde, aber natürlich nicht funktionierte.
Pater Stack
10

Es stellte sich heraus, dass der Empfänger nicht im Tag des Manifests enthalten war. Hoppla! Vielen Dank für Ihre Hilfe Jungs! Das Schlimmste am Testen ist, dass Sie das Telefon immer wieder ausschalten und einschalten müssen. : P.

apmeyers1987
quelle
15
Wie ich an anderer Stelle auf SO gelesen habe, müssen Sie nicht neu starten, sondern nur eine Shell:adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
Tresor
6

Dies scheint der vorderste Thread für dieses Problem zu sein, daher wollte ich eine Lösung für meine C # -Kollegen hinzufügen. Ich habe mir den Kopf zerbrochen, um herauszufinden, was ich falsch gemacht habe, nachdem ich hier alles versucht hatte, ohne Erfolg. Ich habe endlich herausgefunden, was falsch war, und es unterscheidet sich ein wenig von den Ratschlägen hier für die C # Mono-Entwicklung. Im Grunde läuft es auf etwas hinaus, das ich gerade auf die harte Tour gelernt habe. Mit C # AndroidManifest.xml NICHT manuell ÄNDERN!

Weitere Informationen finden Sie in diesem Handbuch: Xamarin: Arbeiten mit AndroidManifest.xml

Hier erfahren Sie, wie Sie dieses Problem direkter lösen können.

Zunächst gibt es in Ihren Projekteigenschaften auf der Registerkarte Manifest eine Kontrollkästchenliste zur Auswahl der Berechtigungen, die Sie bereitstellen möchten. Eine davon ist RECEIVE_BOOT_COMPLETED. Überprüfen Sie dies, um diese Berechtigungen bereitzustellen.

Zweitens müssen Sie die richtigen Tags in Ihre BroacastReceiver-Klasse einfügen.

[BroadcastReceiver]
[IntentFilter(new String[]{ Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.LowPriority)]
public class MyBootReceiver : BroadcastReceiver
{
   public override void OnReceive(Context context, Intent intent)
   {
      // Do your boot work here, set alarms, show toasts, whatever
   }
}

Der letzte Teil von [IntentFilter ()], der sich mit der Priorität befasst, ist nicht erforderlich. Er lässt lediglich andere Dinge mit höherer Priorität beim Booten zuerst erledigen und ist eine gute Vorgehensweise, wenn Ihre App keine hohe Priorität hat.

Wie Sie im verlinkten Artikel sehen werden, wird durch die Verwendung dieser Tags in Ihrem Code die Datei AndroidManifest.xml zum Zeitpunkt der Erstellung erstellt, und zwar so, wie es sein sollte. Was ich fand, war, dass das System beim manuellen Ändern des Manifests, um das Empfänger-Tag einzuschließen, veranlasste, dass es nach der Klasse eine Ebene zu tief suchte, wodurch eine ClassNotFound-Ausnahme ausgelöst wurde. Es wurde versucht, [Namespace]. [Namespace]. [BroadcastReceiver] zu instanziieren, was falsch war. Und das geschah aufgrund der manuellen Manifeständerungen.

Wie auch immer, hoffe das hilft.

Auch noch ein kurzer Tipp mit dem ADB-Tool. Wenn Sie eine besser lesbare Version des Protokolls erhalten möchten, versuchen Sie Folgendes:

C: \ Android \ platform-tools \ adb logcat >> C: \ log.txt

Dadurch wird der Logcat in eine Textdatei geschrieben, die Sie etwas einfacher öffnen und lesen können als im Eingabeaufforderungsfenster. Erleichtert auch das Ausschneiden und Einfügen von Dingen.

Wanabrutbier
quelle
Hast du es unter MIUI auf Xiaomi versucht?
Alexey Subbota
1

In Bezug auf einige Geräte mit Android Kitkat 4.4.4_r2 / r1.

Es scheint einen Fehler in Android zu geben, der dazu führt , dass android.intent.action.BOOT_COMPLETED nicht gesendet wird.

Siehe:
BOOT FAILURE macht den Package Manager Service bereit

In den meisten Fällen ist dies nicht die Antwort auf Ihre Probleme (wahrscheinlicher aufgrund von Berechtigungen usw.). Wenn Sie jedoch Kitkat ausführen, können Sie nachsehen, ob dies bei Ihnen der Fall zu sein scheint.

Ich hatte dieses Problem und android.intent.action.BOOT_COMPLETED wurde manchmal einfach nicht gesendet, wenn es gestartet wurde!

JohnyTex
quelle
In Android Version 5.1 gibt es auch das gleiche Problem?
Ajith KP
Was sollen wir also dagegen tun?
Slim_user71169
0

Wenn Sie <category android:name="android.intent.category.HOME" />dies zu meiner Manifestdatei hinzufügen , lösen Sie mein Problem und funktionieren.

<receiver android:name=".BroadCastRecieverClass">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.HOME" />
        </intent-filter>
    </receiver>
Ayaz Khan
quelle
0

In anderen Antworten wurde bereits erläutert, wie der Broadcast-Empfänger perfekt implementiert werden kann, damit er funktioniert. Ich hatte jedoch immer noch Probleme, die Absicht BOOT_COMPLETED zu empfangen, bis ich durch Drücken auf das App-Symbol feststellte, dass die App beim Starten vom Telefon / Emulator tatsächlich funktionierte. Immer wenn ich meine App mit den Debug / Run-Befehlen von Android Studio starte, wird die Absicht BOOT_COMPLETED nicht geliefert, es sei denn, die App wird geöffnet und ausgeführt.

Ich hoffe, dies kann jemandem helfen, der wie ich stundenlang mit diesem Problem zu kämpfen hatte. Wenn jemand eine Erklärung für dieses Verhalten hat, würde ich mich sehr freuen, mehr darüber zu erfahren.

c0rtexx
quelle