web-dev-qa-db-ger.com

Versuch, einen Dienst beim Booten zu starten Android

Ich habe versucht, einen Dienst zu starten, wenn ein Gerät unter Android gestartet wird, kann es jedoch nicht zum Laufen bringen. Ich habe mir eine Reihe von Links online angesehen, aber keiner der Codes funktioniert. Vergesse ich etwas?

AndroidManifest.xml

<receiver
    Android:name=".StartServiceAtBootReceiver"
    Android:enabled="true"
    Android:exported="false"
    Android:label="StartServiceAtBootReceiver" >
    <intent-filter>
        <action Android:name="Android.intent.action._BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<service
    Android:name="com.test.RunService"
    Android:enabled="true" />

Rundfunkempfänger

public void onReceive(Context context, Intent intent) {
    if ("Android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
        Intent serviceLauncher = new Intent(context, RunService.class);
        context.startService(serviceLauncher);
        Log.v("TEST", "Service loaded at start");
    }
}
325
Alex

Die anderen Antworten sehen gut aus, aber ich dachte, ich würde alles zu einer vollständigen Antwort zusammenfassen.

Sie benötigen Folgendes in Ihrer AndroidManifest.xml - Datei:

  1. In Ihrem <manifest> Element:

    <uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED" />
    
  2. In Ihrem <application> - Element (stellen Sie sicher, dass Sie einen vollständig qualifizierten [oder relativen] Klassennamen für Ihr BroadcastReceiver verwenden):

    <receiver Android:name="com.example.MyBroadcastReceiver">  
        <intent-filter>  
            <action Android:name="Android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
    

    (Die Attribute Android:enabled, exported usw. sind nicht erforderlich. Die Android Standardeinstellungen sind korrekt)

    In MyBroadcastReceiver.Java:

    package com.example;
    
    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent startServiceIntent = new Intent(context, MyService.class);
            context.startService(startServiceIntent);
        }
    }
    

Aus der ursprünglichen Frage:

  • es ist nicht klar, ob sich das Element <receiver> im Element <application> befand
  • es ist nicht klar, ob der korrekte vollqualifizierte (oder relative) Klassenname für BroadcastReceiver angegeben wurde
  • es gab einen Tippfehler in der <intent-filter>
598
Timo Bruck

Als zusätzliche Info: BOOT_COMPLETE wird an die Anwendungen gesendet Vorher Externer Speicher wird bereitgestellt. Wenn die Anwendung auf einem externen Speicher installiert ist, wird keine BOOT_COMPLETE-Broadcast-Nachricht empfangen.

Weitere Details hier in Abschnitt Rundfunkempfänger warten auf "Boot abgeschlossen"

83
inazaruk

So starten Sie den Dienst beim Gerätestart (Autorun-App usw.)

Zum Ersten: seit Version Android 3.1+) erhalten Sie BOOT_COMPLETE nicht mehr, wenn der Benutzer Ihre App nicht mindestens einmal gestartet oder die Anwendung "erzwungen" hat. Dies wurde durchgeführt, um zu verhindern, dass Malware den Dienst automatisch registriert. Diese Sicherheitslücke wurde in neueren Versionen von Android geschlossen.

Lösung:

App mit Aktivität erstellen. Wenn der Benutzer es einmal ausführt, kann die App die Broadcast-Nachricht BOOT_COMPLETE empfangen.

Zum Zweiten: BOOT_COMPLETE wird gesendet, bevor der externe Speicher bereitgestellt wird. Wenn die App auf einem externen Speicher installiert ist, wird keine BOOT_COMPLETE-Broadcast-Nachricht empfangen.

In diesem Fall gibt es zwei Lösungen:

  1. Installieren Sie Ihre App im internen Speicher
  2. Installieren Sie eine weitere kleine App im internen Speicher. Diese App empfängt BOOT_COMPLETE und führt die zweite App auf externem Speicher aus.

Wenn Ihre App bereits im internen Speicher installiert ist, können Sie anhand des folgenden Codes nachvollziehen, wie der Dienst beim Gerätestart gestartet wird.


In Manifest.xml

Genehmigung:

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

Registrieren Sie Ihren BOOT_COMPLETED Empfänger:

<receiver Android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action Android:name="Android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

Registrieren Sie Ihren Dienst:

<service Android:name="org.yourapp.YourCoolService" />

Im Empfänger OnBoot.Java:

public class OnBoot extends BroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // Create Intent
        Intent serviceIntent = new Intent(context, YourCoolService.class);
        // Start service
        context.startService(serviceIntent);

    }

 }

Für HTC müssen Sie möglicherweise auch diesen Code im Manifest hinzufügen, wenn das Gerät RECEIVE_BOOT_COMPLETED nicht abfängt:

<action Android:name="Android.intent.action.QUICKBOOT_POWERON" />

Der Empfänger sieht jetzt so aus:

<receiver Android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action Android:name="Android.intent.action.BOOT_COMPLETED"/>
        <action Android:name="Android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

Wie teste ich BOOT_COMPLETED, ohne den Emulator oder das reale Gerät neu zu starten? Es ist einfach. Versuche dies:

adb -s device-or-emulator-id Shell am broadcast -a Android.intent.action.BOOT_COMPLETED

Wie bekomme ich die Geräte-ID? Liste der angeschlossenen Geräte mit IDs abrufen:

adb devices

adb in ADT finden Sie standardmäßig in:

adt-installation-dir/sdk/platform-tools

Genießen! )

66
user3439968

Zusammen mit

<action Android:name="Android.intent.action.BOOT_COMPLETED" />  

benutze auch,

<action Android:name="Android.intent.action.QUICKBOOT_POWERON" />

HTC-Geräte scheinen BOOT_COMPLETED nicht zu erfassen

34
Tony

beachten Sie, dass zu Beginn der Frage ein Tippfehler vorliegt:

<action Android:name="Android.intent.action._BOOT_COMPLETED"/>

anstatt :

<action Android:name="Android.intent.action.BOOT_COMPLETED"/>

ein kleines "_" und all diese Probleme :)

20
Evgeny Erlihman

Ich habe gerade herausgefunden, dass es an der Option Fast Boot In Settings> Power liegen könnte.

Wenn ich diese Option deaktiviert habe, empfängt meine Anwendung diese Übertragung, aber nicht anders.

Übrigens habe ich Android 2.3.3 Auf HTC Incredible S.

Ich hoffe es hilft.

13
Omer Akhter

Ich denke, Ihr Manifest muss hinzufügen:

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

Nachdem ich alle genannten Antworten und Tricks ausprobiert habe, finde ich endlich heraus, warum der Code in meinem Telefon nicht funktioniert. Einige Android Handys wie "Huawei Honor 3C Android 4.2.2" haben ein Statup Manager Menü in ihren Einstellungen und Ihre App muss überprüft werden In der Liste. :)

6
Amir

Ich habe ein zusätzliches <category> - Tag, weiß nicht, ob das einen Unterschied macht.

<receiver Android:name="BootIntentReceiver">  
        <intent-filter>  
            <action Android:name="Android.intent.action.BOOT_COMPLETED" />  
            <category Android:name="Android.intent.category.HOME" />  
        </intent-filter>  
</receiver>

Haben Sie versucht, die if-Klausel "Android.intent.action.BOOT_COMPLETED".equals(intent.getAction() wegzulassen, da der Empfänger wahrscheinlich sowieso nur diese Absicht erhält?

5
Nick

Verweisen Sie auf diesen Link http://khurramitdeveloper.blogspot.in/2013/06/start-activity-or-service-on-boot.html Schrittweise Anleitung zur Verwendung des Boot-on-Service

4
Jaichander

Vor dem Mounten des externen Speichers wird BOOT_COMPLETE gesendet. Execute.if Ihre App wird auf einem externen Speicher installiert und erhält keine BOOT_COMPLETE-Broadcast-Nachricht. Um dies zu verhindern, können Sie Ihre Anwendung im internen Speicher installieren. Dazu fügen Sie einfach diese Zeile in die Datei menifest.xml ein

<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:installLocation="internalOnly"
... >

Einige HTC-Geräte können eine "Schnellstart" -Funktion aktivieren, die eher einem tiefen Ruhezustand als einem tatsächlichen Neustart ähnelt und daher nicht die Absicht BOOT_COMPLETE enthalten sollte. Um dies wiederherzustellen, können Sie diesen Absichtsfilter in Ihrem Empfänger hinzufügen:

            <intent-filter>
                <action Android:name="Android.intent.action.BOOT_COMPLETED" />
                <action Android:name="Android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
3

Wenn Sie Android Studio verwenden und die automatische Vervollständigung sehr lieben, muss ich Sie darüber informieren, dass ich Android Studio v 1.1 verwende. 0 und ich haben die automatische Vervollständigung für die folgende Berechtigung verwendet

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

Und Android Studio Auto-CompletedRECEIVE_BOOT_COMPLETED alles in Kleinbuchstaben wie receive_boot_completed und ich riss mir immer wieder die Haare aus, weil ich meine Checkliste bereits ausgekreuzt hatte, um beim Booten den Service zu starten. Ich habe es gerade noch einmal bestätigt

Android Studio vervollständigt diese Berechtigung automatisch in Kleinbuchstaben.

2
Haroon Dilshad

Das habe ich getan

1. Ich habe die Empfängerklasse erstellt

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //whatever you want to do on boot
       Intent serviceIntent = new Intent(context, YourService.class);
       context.startService(serviceIntent);
    }
}

2.im Manifest

<manifest...>
    <uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED"/>
    <application...>
        <receiver Android:name=".BootReceiver" Android:enabled="true" Android:exported="false">
            <intent-filter>
                <action Android:name="Android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    ...

.und nachdem ALLES, was Sie MÜSSEN, um den Empfänger in Ihrer MainActivity "einzustellen", kann es innerhalb des onCreate sein

...
 final ComponentName onBootReceiver = new ComponentName(getApplication().getPackageName(), BootReceiver.class.getName());
        if(getPackageManager().getComponentEnabledSetting(onBootReceiver) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
        getPackageManager().setComponentEnabledSetting(onBootReceiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
...

den letzten Schritt habe ich von ApiDemos gelernt

2
San Juan

Wie @Damian kommentierte, machen alle Antworten in diesem Thread es falsch. Wenn Sie dies manuell tun, besteht die Gefahr, dass Ihr Dienst während des Ruhezustands des Geräts angehalten wird. Sie müssen zuerst eine Wecksperre erhalten. Glücklicherweise gibt uns die Support Bibliothek eine Klasse um dies zu tun:

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This is the Intent to deliver to our service.
        Intent service = new Intent(context, SimpleWakefulService.class);

        // Start the service, keeping the device awake while it is launching.
        Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
        startWakefulService(context, service);
    }
}

stellen Sie dann in Ihrem Service sicher, dass Sie die Aktivierungssperre aufheben:

    @Override
    protected void onHandleIntent(Intent intent) {
        // At this point SimpleWakefulReceiver is still holding a wake lock
        // for us.  We can do whatever we need to here and then tell it that
        // it can release the wakelock.

...
        Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }

Vergiss nicht, die WAKE_LOCK-Berechtigung zu deinem Hauptfest hinzuzufügen:

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

Tatsächlich gerate ich vor nicht allzu langer Zeit in dieses Problem, und es ist wirklich sehr einfach zu beheben. Sie machen eigentlich nichts falsch, wenn Sie das "Android.intent.action.BOOT_COMPLETED" Erlaubnis und Absichtsfilter.

Beachten Sie, dass Sie unter Android 4.X) den Broadcast-Listener ausführen müssen, bevor Sie den Dienst beim Booten starten. Dies bedeutet, dass Sie zuerst eine Aktivität hinzufügen müssen, sobald Ihr Broadcast-Receiver ausgeführt wird , Ihre App sollte wie erwartet funktionieren, jedoch auf Android 4.X, ich habe keine Möglichkeit gefunden, den Dienst beim Booten ohne Aktivität zu starten. Ich denke, Google hat dies aus Sicherheitsgründen getan Gründe dafür.

1
David Hx

Ich stand vor diesem Problem, wenn ich den leeren Konstruktor in der Empfängerklasse belasse. Nach dem Entfernen des leeren Controllers begann onRreceive Methos einwandfrei zu funktionieren.

0
redrom