Servizio di avvio di Android al momento dell'avvio


109

Devo avviare un servizio all'avvio. Ho cercato molto. Stanno parlando di Broadcastreceiver. Dato che sono nuovo nello sviluppo di Android, non ho ottenuto un'immagine chiara dei servizi su Android. Fornisci un codice sorgente.


25
@ user244540: Non "avviare un servizio all'avvio" con l'intenzione di farlo funzionare per sempre, a meno che non fornisca continuamente valore (ad esempio, un client VOIP). In questi casi, usa startForeground()nel tuo servizio. Altrimenti, Android ei suoi utenti elimineranno il tuo servizio come uno spreco di spazio e riceverai alcuni commenti spiacevoli nell'Android Market. Nella maggior parte delle situazioni in cui si pensa di voler avviare un servizio all'avvio, è meglio utilizzarlo in AlarmManagermodo che il servizio possa essere eseguito periodicamente anziché continuamente .
CommonsWare

2
@CommonsWare: buon punto. Tuttavia, AlarmManageronReceive
tieni

1
@CommonsWare: commento molto buono, mi sono imbattuto in questa domanda e il tuo suggerimento si adatta perfettamente alla mia situazione. Se fosse stata una risposta l'avrei votata a favore :-)
chiccodoro

Risposte:


95

Crea un BroadcastReceivere registralo per ricevere ACTION_BOOT_COMPLETED . Hai anche bisogno dell'autorizzazione RECEIVE_BOOT_COMPLETED .

Leggi: ascolto e trasmissione di messaggi globali e impostazione di allarmi


2
che dire del wakelock? mentre il servizio è avviato il dispositivo potrebbe decidere di andare a dormire ...
Marian Paździoch

Devo avviare il mio cellulare almeno una volta per avviare un servizio?
pathe.kiran

@ MarianPaździoch ha ragione; hai bisogno di un wakelock. Vedere la mia risposta qui sotto: stackoverflow.com/a/30970167/473201
phreakhead


Il tuo ultimo URL non è aggiornato
Prizoff

192

Il tuo ricevitore:

public class MyReceiver extends BroadcastReceiver {   

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

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

    }
}

Il tuo 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
Il link all'articolo è morto ma il codice di esempio è tutto ciò di cui hai bisogno comunque, quindi +1 :)
Alex

3
In realtà, ha bisogno di piccoli miglioramenti, devi usare wakelock nel ricevitore, altrimenti c'è una piccola possibilità che il tuo servizio non inizi.
Vladimir Ivanov

Devo avviare il mio cellulare almeno una volta per farlo funzionare ??
pathe.kiran

1
No, ma è necessario eseguire l'applicazione almeno una da Android 3.0
Vladimir Ivanov

Funziona se l'app viene chiusa forzatamente dalle impostazioni? L'app si riattiverà ancora?
Srihari Karanth

32

È possibile registrare il proprio servizio dell'applicazione per l'avvio automatico quando il dispositivo è stato avviato. Ciò è necessario, ad esempio, quando si desidera ricevere eventi push da un server http e si desidera informare l'utente non appena si verifica un nuovo evento. L'utente non deve avviare l'attività manualmente prima dell'avvio del servizio ...

È abbastanza semplice. Per prima cosa dai alla tua app l'autorizzazione RECEIVE_BOOT_COMPLETED. Successivamente è necessario registrare un BroadcastReveiver. Lo chiamiamo BootCompletedIntentReceiver.

Il tuo Manifest.xml dovrebbe ora assomigliare a questo:

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

Come ultimo passaggio devi implementare il ricevitore. Questo ricevitore avvia semplicemente il servizio in background.

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

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


3
Come sopra ma davvero semplice e veloce, usa questo se vieni da questo post.
dbkoren

L'unica differenza è che questo dichiara il servizio sul manifesto, che è corretto.
Joaquin Iurchuk

Non è solo corretto dichiarare il proprio servizio nel manifest, è obbligatorio. Come per le attività
Tim

Dov'è l'attività principale !? Non è corretto creare app senza attività o android.intent.category.LAUNCHER!
nick

@ L'Esperanza di sicuro, puoi avere app che non hanno attività visibili!
appsthatmatter

15

Alla maggior parte delle soluzioni pubblicate qui manca un pezzo importante: farlo senza un wakelock rischia che il tuo servizio venga interrotto prima che sia terminata l'elaborazione. Ho visto questa soluzione in un altro thread, rispondendo anche qui.

Poiché WakefulBroadcastReceiver è deprecato in api 26, è consigliato per i livelli API inferiori a 26

È necessario ottenere un wakelock. Fortunatamente, la libreria di supporto ci offre una classe per farlo:

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

quindi, nel tuo Servizio, assicurati di rilasciare il wakelock:

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

Non dimenticare di aggiungere l'autorizzazione WAKE_LOCK e di registrare il tuo ricevitore nel 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
Nel file manifest, SimpleWakefulReceiver non è un servizio.
Desmond Lua

1
WakefulBroadcastReceiver è deprecato
Amin Pinjari

5

dovresti registrarti per BOOT_COMPLETE e 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
La letteratura afferma che "android.intent.action.REBOOT" può essere utilizzato solo da app / codice privilegiati. Quale vantaggio è questo altrimenti?
XMAN

1

Registra anche il servizio creato nel Manifest e utilizza l'autorizzazione come

<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"/>

e poi in braod cast Reciever chiama il tuo servizio

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

Perché il filtro di intenti all'interno del servizio?
Joaquin Iurchuk

perché una volta completato l'avvio, MyService verrà chiamato
SoftEye

In tal caso, la classe di servizio estenderà il servizio e il ricevitore di trasmissione. Ho ragione?
Joaquin Iurchuk

La classe estenderà la classe Service.
SoftEye

2
C'è qualcosa che non va qui. Il servizio dovrebbe essere chiamato dal ricevitore di trasmissione. Ma stai dicendo che il tuo servizio è il ricevitore di trasmissione e dopo mi dici che la classe di servizio non si estende a Ricevitore di trasmissione. Pertanto, non riceverà la trasmissione di avvio completato. Cosa stai sovrascrivendo quando dichiari il metodo onReceive?
Joaquin Iurchuk

0

Prima registra un ricevitore nel tuo file 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>

e poi scrivi una trasmissione per questo ricevitore come:

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

Per riavviare il servizio in Android Oo più, ad esempio OS> 28 Utilizzare questo codice KOTLIN VERSION 1) Aggiungere l'autorizzazione nel manifest

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

2) Crea un Classed estendilo conBroadcastReceiver

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) Dichiarare in un file manifest come questo sotto il tag dell'applicazione

<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

Pls controlla JobScheduler per le API superiori a 26

WakeLock era l'opzione migliore per questo, ma è deprecato nel livello API 26 Pls controlla questo collegamento se consideri i livelli API superiori a 26
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html# startWakefulService (android.content.Context,% 20android.content.Intent)

Dice

A partire da Android O, le limitazioni del controllo in background rendono questa classe generalmente non più utile. (In genere non è sicuro avviare un servizio dalla ricezione di una trasmissione, perché non hai alcuna garanzia che la tua app sia in primo piano a questo punto e quindi autorizzata a farlo.) Invece, gli sviluppatori dovrebbero usare Android. app.job.JobScheduler per pianificare un lavoro e ciò non richiede che l'app mantenga un wakelock mentre lo fa (il sistema si occuperà di tenere un wakelock per il lavoro).

così come dice cosider JobScheduler
https://developer.android.com/reference/android/app/job/JobScheduler

se è per fare qualcosa che per iniziare e per mantenerla puoi ricevere la trasmissione ACTION_BOOT_COMPLETED

Se non si tratta di primo piano, controlla se un servizio di accessibilità può andare bene

un'altra opzione è avviare un'attività dal ricevitore di trasmissione e terminarla dopo aver avviato il servizio all'interno di onCreate (), poiché le versioni più recenti di Android non consentono di avviare i servizi dai ricevitori

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.