2010-12-30 12 views
96

Potrzebuję uruchomić usługę przy starcie systemu. Dużo szukałem. Mówią o Broadcastreceiver. Ponieważ jestem nowy w rozwoju Androida, nie mam jasnego obrazu usług na Androida. Proszę podać kod źródłowy.Android - uruchomienie usługi w czasie rozruchu

+23

@ user244540: Nie należy "uruchamiać usługi podczas rozruchu" z zamiarem jej nieprzerwanego działania, chyba że stale dostarcza ona wartość (np. Klienta VOIP). W takich przypadkach użyj 'startForeground()' w swojej usłudze. W przeciwnym razie Android i jego użytkownicy zabiją Twoją usługę jako marnowanie przestrzeni, a otrzymasz nieprzyjemne komentarze na Android Market. W większości sytuacji, w których wydaje się, że chcesz uruchomić usługę w czasie rozruchu, lepiej korzystać z 'AlarmManager', aby Twoja usługa mogła działać * okresowo * zamiast * bez przerwy *. – CommonsWare

+2

@CommonsWare: Dobra uwaga. Zauważ jednak, że aby uruchomić okresowe uruchomienia przez 'AlarmManager' po restarcie, musisz wykonać bardzo podobne kroki (różnica jest zawarta w metodzie' onReceive') – stanwise

+1

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

Odpowiedz

91

Tworzenie BroadcastReceiver i zarejestrować go otrzymywać ACTION_BOOT_COMPLETED. Potrzebujesz również uprawnienia RECEIVE_BOOT_COMPLETED.

Czytaj: Listening For and Broadcasting Global Messages, and Setting Alarms

+2

co z blokadą wake? gdy usługa jest uruchomiona, urządzenie może zdecydować o zasypianiu ... –

+0

Czy muszę uruchomić telefon komórkowy co najmniej raz, aby uruchomić usługę? –

+0

@ MarianPoczekdzioch ma rację; potrzebujesz blokady wybudzania. Zobacz moją odpowiedź poniżej: http://stackoverflow.com/a/30970167/473201 – phreakhead

185

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 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> 
+4

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

+3

Właściwie to wymaga niewielkiej poprawy, musisz użyć wakelock w odbiornik, w przeciwnym razie istnieje mała szansa, że ​​twoja usługa się nie rozpocznie. –

+0

Czy muszę uruchomić telefon komórkowy co najmniej raz, aby to zadziałało? –

29

Jest możliwe, aby zarejestrować swoją usługę aplikacji do uruchamiania automatycznie, gdy urządzenie zostało uruchomiony. Potrzebujesz tego, na przykład, gdy chcesz otrzymywać zdarzenia push z serwera http i , aby poinformować użytkownika, gdy tylko pojawi się nowe zdarzenie. Użytkownik nie musi ręcznie wykonywać czynności przed rozpoczęciem usługi ...

To bardzo proste. Najpierw daj swojej aplikacji pozwolenie RECEIVE_BOOT_COMPLETED. Następnie musisz zarejestrować BroadcastReveiver. Nazywamy to BootCompletedIntentReceiver.

Twój manifest.xml powinna 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> 

W ostatnim kroku trzeba zaimplementować odbiornik. Odbiornik po prostu 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

To samo, co powyżej, ale naprawdę proste i szybkie, użyj tego, jeśli dotrzesz do tego posta . – dbkoren

+0

Jedyną różnicą jest to, że deklaruje Usługę w Manifeście, co jest poprawne. –

+0

Jest nie tylko poprawne deklarowanie usługi w manifeście, jest wymagane. Tak jak w przypadku działań –

1

również zarejestrować utworzoną usługę w manifeście i wykorzystuje-zezwolenie 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 braod odbiornik szarego wywołać usługę

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

Dlaczego filtr Intent w serwisie? –

+0

ponieważ po zakończeniu rozruchu usługa MyService zostanie nazwana – SoftEye

+0

. W takim przypadku twoja klasa usług rozszerzy odbiornik usług i transmisji. Czy mam rację? –

0

Najpierw zarejestruj odbiornik ver 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 napisać transmisję do tego odbiornika, takich 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(); 
    } 
    } 
} 
12

Większość rozwiązań zamieszczonych tutaj brakuje ważnego elementu: robi to bez blokady tras wake ryzyko, że Twoja Usługa zostanie zabita przed zakończeniem przetwarzania. Widziałem to rozwiązanie w innym wątku, odpowiadając również tutaj.

Najpierw należy uzyskać blokadę wybudzania.Na szczęście, Support library gives us a class to zrobić:

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 Serwisie, upewnij się, aby zwolnić blokadę budzenia:

@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ć pozwolenie WAKE_LOCK i zarejestrować swój odbiornik w manifest:

<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ą. –

3

należy zarejestrować BOOT_COMPLETE jak 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> 
+0

Literatura mówi, że "android.intent.action.REBOOT" może być używany tylko przez uprzywilejowaną aplikację/kod. Jaka jest tego zaleta? –

Powiązane problemy