Android - uruchamianie usługi w czasie rozruchu


109

Muszę uruchomić usługę w czasie rozruchu. Szukałem dużo. Mówią o Broadcastreceiver. Ponieważ jestem nowy w programowaniu dla Androida, nie mam jasnego obrazu usług na Androida. Proszę podać kod źródłowy.


25
@ user244540: Proszę nie „uruchamiać usługi w czasie rozruchu” z zamiarem ciągłego działania, chyba że stale dostarcza wartości (np. klient VOIP). W takich przypadkach użyj startForeground()w swojej usłudze. W przeciwnym razie Android i jego użytkownicy zabiją twoją usługę jako stratę miejsca, a ty otrzymasz nieprzyjemne komentarze w Android Market. W większości sytuacji, w których myślisz, że chcesz, aby usługa była uruchamiana w czasie rozruchu, lepiej jest korzystać z niej, AlarmManageraby usługa mogła działać okresowo, a nie w sposób ciągły .
— CommonsWare

2
@CommonsWare: Słuszna uwaga. Należy jednak pamiętać, że aby rozpocząć okresowe przebiegi AlarmManagerpo ponownym uruchomieniu, należy wykonać bardzo podobne kroki (różnica polega na treści onReceivemetody)
— standardowo

1
@CommonsWare: Bardzo dobry komentarz, natknąłem się na to pytanie, a Twoja wskazówka dokładnie pasuje do mojej sytuacji. Gdyby to była odpowiedź, zagłosowałbym za nią :-)
— chiccodoro

Odpowiedzi:


95

Utwórz BroadcastReceiveri zarejestruj go, aby otrzymać ACTION_BOOT_COMPLETED . Potrzebujesz również uprawnienia RECEIVE_BOOT_COMPLETED .

Przeczytaj: Odsłuchiwanie i nadawanie globalnych wiadomości oraz ustawianie alarmów


2
a co z blokadą budzenia? podczas gdy usługa jest uruchamiany urządzenie może zdecydować, aby przejść śpi ...
— Marian Paździoch

Czy muszę przynajmniej raz uruchomić telefon, aby rozpocząć usługę?
— pathe.kiran

@ MarianPaździoch ma rację; potrzebujesz blokady budzenia. Zobacz moją odpowiedź poniżej: stackoverflow.com/a/30970167/473201
— phreakhead


Twój ostatni adres URL jest nieaktualny
— Prizoff

192

Twój odbiornik:

public class MyReceiver extends BroadcastReceiver {   

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

     Intent myIntent = new Intent(context, YourService.class);
     context.startService(myIntent);

    }
}

Twój plik AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.broadcast.receiver.example"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">

        <activity android:name=".BR_Example"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    <!-- Declaring broadcast receiver for BOOT_COMPLETED event. -->
        <receiver android:name=".MyReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

    </application>

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

</manifest>

5
Link do artykułu jest martwy, ale i tak przykładowy kod jest wszystkim, czego potrzebujesz, więc +1 :)
— Alex

3
Właściwie wymaga to niewielkiej poprawy, musisz użyć wakelocka w odbiorniku, w przeciwnym razie istnieje niewielka szansa, że ​​twoja usługa się nie uruchomi.
— Vladimir Ivanov

Czy muszę przynajmniej raz uruchomić telefon, aby to zadziałało?
— pathe.kiran

1
Nie, ale musisz uruchomić aplikację co najmniej jedną od Androida 3.0
— Vladimir Ivanov

Czy to działa, jeśli aplikacja jest wymuszana z poziomu ustawień? Czy aplikacja nadal będzie się wybudzać?
— Srihari Karanth

32

Istnieje możliwość zarejestrowania własnej usługi aplikacji do automatycznego uruchamiania po uruchomieniu urządzenia. Jest to potrzebne na przykład, gdy chcesz odbierać zdarzenia push z serwera http i chcesz poinformować użytkownika, gdy tylko wystąpi nowe zdarzenie. Użytkownik nie musi uruchamiać aktywności ręcznie przed uruchomieniem usługi ...

To całkiem proste. Najpierw przyznaj swojej aplikacji uprawnienie RECEIVE_BOOT_COMPLETED. Następnie musisz zarejestrować BroadcastReveiver. Nazywamy to BootCompletedIntentReceiver.

Twój plik Manifest.xml powinien teraz wyglądać następująco:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.jjoe64">
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
 <application>
  <receiver android:name=".BootCompletedIntentReceiver">
   <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
   </intent-filter>
  </receiver>
  <service android:name=".BackgroundService"/>
 </application>
</manifest>

Jako ostatni krok musisz zaimplementować odbiornik. Ten odbiornik właśnie uruchamia usługę w tle.

package com.jjoe64;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import com.jjoe64.BackgroundService;

public class BootCompletedIntentReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
  if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
   Intent pushIntent = new Intent(context, BackgroundService.class);
   context.startService(pushIntent);
  }
 }
}

Od http://www.jjoe64.com/2011/06/autostart-service-on-device-boot.html


3
Tak samo jak powyżej, ale naprawdę proste i szybkie, użyj tego, jeśli przyjdziesz przez ten post.
— dbkoren,

Jedyną różnicą jest to, że deklaruje to usługę w Manifeście, co jest poprawne.
— Joaquin Iurchuk

Zadeklarowanie służby w manifeście jest nie tylko poprawne, ale jest to wymagane. To samo co z zajęciami
— Tim

Gdzie jest główna aktywność !? Tworzenie aplikacji bez aktywności lub android.intent.category.LAUNCHER!
— nick

@ L'Esperanza na pewno możesz mieć aplikacje, które nie mają widocznych działań!
— appsthatmatter

15

W większości przedstawionych tutaj rozwiązań brakuje ważnego elementu: zrobienie tego bez blokady uśpienia grozi śmiercią usługi przed zakończeniem przetwarzania. Widziałem to rozwiązanie w innym wątku, odpowiadając również tutaj.

Ponieważ WakefulBroadcastReceiver jest przestarzałe w API 26, jest zalecane dla poziomów API poniżej 26

Musisz uzyskać blokadę budzenia. Na szczęście biblioteka pomocy technicznej daje nam do tego klasę :

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);
    }
}

następnie w swojej usłudze pamiętaj o zwolnieniu blokady uśpienia:

    @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);
    }

Nie zapomnij dodać uprawnienia WAKE_LOCK i zarejestrować odbiorcę w manifeście:

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

...

<service android:name=".SimpleWakefulReceiver">
    <intent-filter>
        <action android:name="com.example.SimpleWakefulReceiver"/>
    </intent-filter>
</service>

1
W pliku manifestu SimpleWakefulReceiver nie jest usługą.
— Desmond Lua

1
WakefulBroadcastReceiver jest przestarzały
— Amin Pinjari

5

powinieneś zarejestrować się w BOOT_COMPLETE, a także w REBOOT

<receiver android:name=".Services.BootComplete">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.REBOOT"/>
        </intent-filter>
    </receiver> 

2
Literatura mówi, że „android.intent.action.REBOOT” może być używany tylko przez uprzywilejowaną aplikację / kod. Jaka to korzyść w przeciwnym razie?
— XMAN

1

Zarejestruj również utworzoną usługę w Manifeście i pozwolenie na używanie jako

<application ...>
   <service android:name=".MyBroadcastReceiver">
        <intent-filter>
            <action android:name="com.example.MyBroadcastReciver"/>
        </intent-filter>
   </service>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

a potem w nowej obsadzie Reciever wezwać serwis

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

Dlaczego filtr intencji w usłudze?
— Joaquin Iurchuk

ponieważ po zakończeniu rozruchu nazwa MyService zostanie nazwana
— SoftEye

W takim przypadku klasa usług rozszerzy usługę i odbiornik transmisji. Czy mam rację?
— Joaquin Iurchuk

Klasa rozszerzy klasę Service.
— SoftEye

2
Coś tu jest nie tak. Usługa ma być wywoływana z Odbiornika transmisji. Ale mówisz, że twoja usługa jest odbiornikiem transmisji, a potem mówisz mi, że klasa usług nie rozszerza odbiornika transmisji. W związku z tym nie otrzyma komunikatu o zakończeniu rozruchu. Co nadpisujesz, deklarując metodę onReceive?
— Joaquin Iurchuk

0

Najpierw zarejestruj odbiornik w pliku manifest.xml:

    <receiver android:name="com.mileagelog.service.Broadcast_PowerUp" >
        <intent-filter>
            <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
            <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
        </intent-filter>
    </receiver>

a następnie napisz transmisję dla tego odbiornika jak:

public class Broadcast_PowerUp extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();

    if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
        Toast.makeText(context, "Service_PowerUp Started",
                Toast.LENGTH_LONG).show();


    } else if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {



        Toast.makeText(context, "Service_PowerUp Stoped", Toast.LENGTH_LONG)
        .show();
    }
  }
}

0

Aby ponownie uruchomić usługę w Android Olub więcej, tj. OS> 28 Użyj tego kodu WERSJA KOTLIN 1) Dodaj uprawnienia w manifeście

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

2) Utwórz Classi rozszerz go za pomocąBroadcastReceiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.core.content.ContextCompat



class BootCompletedReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, arg1: Intent?) {
        Log.d("BootCompletedReceiver", "starting service...")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            ContextCompat.startForegroundService(context, Intent(context, YourServiceClass::class.java))
        } else {
            context.startService(Intent(context, YourServiceClass::class.java))
        }
    }
}

3) Zadeklaruj w pliku manifestu w ten sposób pod znacznikiem aplikacji

<receiver android:name=".utils.BootCompletedReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>

-1

Sprawdź JobScheduler dla apis powyżej 26

WakeLock był najlepszą opcją do tego, ale jest przestarzały na poziomie API 26. Sprawdź ten link, jeśli rozważasz poziomy API powyżej 26
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html# startWakefulService (android.content.Context,% 20android.content.Intent)

To mówi

Począwszy od Androida O, ograniczenia sprawdzania w tle sprawiają, że ta klasa nie jest już ogólnie użyteczna. (Generalnie nie jest bezpieczne uruchamianie usługi od momentu odebrania transmisji, ponieważ nie masz żadnych gwarancji, że Twoja aplikacja znajduje się w tym momencie na pierwszym planie, a zatem ma pozwolenie na to). Zamiast tego programiści powinni używać Androida. app.job.JobScheduler do zaplanowania zadania i nie wymaga, aby aplikacja utrzymywała w tym czasie blokadę wybudzenia (system zajmie się utrzymaniem blokady wybudzenia dla zadania).

tak jak mówi cosider JobScheduler
https://developer.android.com/reference/android/app/job/JobScheduler

jeśli ma coś zrobić, niż zacząć i to zatrzymać, możesz odebrać transmisję ACTION_BOOT_COMPLETED

Jeśli nie chodzi o pierwszy plan, sprawdź, czy usługa ułatwień dostępu może zrobić

inną opcją jest rozpoczęcie czynności z odbiornika rozgłoszeniowego i zakończenie jej po uruchomieniu usługi w ramach onCreate (), ponieważ nowsze wersje Androida nie pozwalają na uruchamianie usług z odbiorników

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.