Android -Mulai Layanan saat Boot

109

Saya perlu memulai layanan saat boot. Saya banyak mencari. Mereka berbicara tentang Penerima Siaran. Karena saya baru mengenal pengembangan Android, saya tidak mendapatkan gambaran yang jelas tentang layanan di Android. Berikan beberapa kode sumber.

Harish
sumber
25
@ user244540: Harap jangan "memulai layanan pada saat boot" dengan maksud agar layanan tersebut berjalan selamanya, kecuali layanan ini terus memberikan nilai (mis., klien VOIP). Dalam kasus tersebut, gunakan startForeground()dalam layanan Anda. Jika tidak, Android dan penggunanya akan mematikan layanan Anda sebagai pemborosan ruang, dan Anda akan mendapatkan beberapa komentar tidak menyenangkan di Android Market. Dalam kebanyakan situasi di mana Anda merasa ingin layanan dimulai pada waktu boot, Anda lebih baik dilayani menggunakan AlarmManagersehingga layanan Anda dapat berjalan secara berkala daripada terus menerus .
CommonsWare
2
@CommonsWare: Poin yang bagus. Namun perhatikan, bahwa untuk memulai operasi berkala AlarmManagersetelah restart, Anda harus mengikuti langkah-langkah yang sangat mirip (perbedaannya terletak pada konten onReceivemetode)
mulai
1
@CommonsWare: Komentar yang sangat bagus, saya menemukan pertanyaan ini dan petunjuk Anda benar-benar sesuai dengan situasi saya. Jika itu adalah jawaban, saya akan memilihnya :-)
chiccodoro

Jawaban:

95

Buat BroadcastReceiverdan daftarkan untuk menerima ACTION_BOOT_COMPLETED . Anda juga membutuhkan izin RECEIVE_BOOT_COMPLETED .

Baca: Mendengarkan dan Menyiarkan Pesan Global, dan Mengatur Alarm

Peter Knego
sumber
2
bagaimana dengan penguncian layar saat aktif? sementara layanan sedang dimulai perangkat mungkin memutuskan untuk tidur ...
Marian Paździoch
Apakah saya perlu mem-boot ponsel saya setidaknya sekali untuk memulai layanan ??
pathe.kiran
@ MarianPaździoch benar; Anda membutuhkan kunci bangun. Lihat jawaban saya di bawah ini: stackoverflow.com/a/30970167/473201
phreakhead
@ pathe.kiran saat boot, ya. Lihat commonsware.com/blog/2011/07/05/boot-completed-regress.html
Tim
URL terbaru Anda sudah usang
Prizoff
192

Penerima Anda:

public class MyReceiver extends BroadcastReceiver {   

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

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

    }
}

AndroidManifest.xml Anda:

<?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>
Vladimir Ivanov
sumber
5
Tautan ke artikel sudah mati tetapi kode sampel adalah semua yang Anda butuhkan, jadi +1 :)
Alex
3
Sebenarnya, perlu sedikit peningkatan, Anda harus menggunakan wakelock di receiver, jika tidak ada kemungkinan kecil layanan Anda tidak akan dimulai.
Vladimir Ivanov
Apakah saya perlu mem-boot ponsel saya setidaknya sekali untuk membuat ini berfungsi ??
pathe.kiran
1
Tidak, tetapi Anda harus menjalankan aplikasi setidaknya satu sejak Android 3.0
Vladimir Ivanov
Apakah ini berfungsi jika aplikasi ditutup paksa dari pengaturan? Akankah aplikasi masih aktif?
Srihari Karanth
32

Anda dapat mendaftarkan layanan aplikasi Anda sendiri untuk memulai secara otomatis ketika perangkat telah di-boot. Anda memerlukan ini, misalnya, saat Anda ingin menerima peristiwa push dari server http dan ingin memberi tahu pengguna segera setelah peristiwa baru terjadi. Pengguna tidak harus memulai aktivitas secara manual sebelum layanan dimulai ...

Cukup sederhana. Pertama-tama, beri aplikasi Anda izin RECEIVE_BOOT_COMPLETED. Selanjutnya Anda perlu mendaftarkan BroadcastReveiver. Kami menyebutnya BootCompletedIntentReceiver.

Manifest.xml Anda sekarang akan terlihat seperti ini:

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

Sebagai langkah terakhir Anda harus menerapkan Penerima. Penerima ini baru saja memulai layanan latar belakang Anda.

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

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

appsthatmatter
sumber
3
Sama seperti di atas tetapi sangat sederhana dan cepat, gunakan yang ini jika Anda datang melalui posting ini.
dbkoren
Satu-satunya perbedaan adalah bahwa ini mendeklarasikan Layanan pada Manifes, yang benar.
Joaquin Iurchuk
Tidak hanya benar untuk mendeklarasikan layanan Anda dalam manifes, itu juga diperlukan. Sama seperti aktivitas
Tim
Dimana Kegiatan Utama !? Tidak benar membuat aplikasi tanpa aktivitas atau android.intent.category.LAUNCHER!
torehan
@ L'Esperanza pasti, Anda dapat memiliki aplikasi yang tidak memiliki aktivitas yang terlihat!
appsthatterter
15

Sebagian besar solusi yang diposting di sini kehilangan bagian penting: melakukannya tanpa kunci pengaktifan menjalankan risiko Layanan Anda terbunuh sebelum selesai diproses. Melihat solusi ini di utas lain, menjawab di sini juga.

Karena WakefulBroadcastReceiver sudah tidak digunakan lagi dalam api 26, direkomendasikan untuk API Level di bawah 26

Anda perlu mendapatkan penguncian layar saat aktif. Untungnya, pustaka Dukungan memberi kita kelas untuk melakukan ini:

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

kemudian, di Layanan Anda, pastikan untuk melepaskan kunci layar aktif:

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

Jangan lupa untuk menambahkan izin WAKE_LOCK dan daftarkan penerima Anda di manifes:

<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>
phreakhead
sumber
1
Dalam file manifes, SimpleWakefulReceiver bukanlah sebuah layanan.
Desmond Lua
1
WakefulBroadcastReceiver tidak digunakan lagi
Amin Pinjari
5

Anda harus mendaftar BOOT_COMPLETE serta 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> 
Raafat Alhmidi
sumber
2
Literatur mengatakan bahwa 'android.intent.action.REBOOT' hanya dapat digunakan oleh aplikasi / kode dengan hak istimewa. Apa keuntungannya jika tidak?
XMAN
1

Juga daftarkan layanan yang Anda buat di Manifes dan izin penggunaan sebagai

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

dan kemudian di braod cast Reciever memanggil layanan Anda

public class MyBroadcastReceiver extends BroadcastReceiver 
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Intent myIntent = new Intent(context, MyService.class);
        context.startService(myIntent);
    }
}
SoftEye
sumber
Mengapa Filter Intent di dalam layanan?
Joaquin Iurchuk
karena ketika boot selesai maka MyService akan dipanggil
SoftEye
Dalam hal ini kelas layanan Anda akan memperluas layanan dan penerima siaran. Apakah saya benar?
Joaquin Iurchuk
Kelas akan memperluas kelas Service.
SoftEye
2
Ada yang salah disini. Layanan ini seharusnya dipanggil dari Penerima Siaran. Tetapi Anda mengatakan bahwa layanan Anda adalah penerima siaran dan setelah itu Anda memberi tahu saya bahwa kelas layanan tidak memperluas Penerima Siaran. Dengan demikian, itu tidak akan menerima Siaran Boot Selesai. Apa yang Anda timpa saat mendeklarasikan metode onReceive?
Joaquin Iurchuk
0

Pertama-tama daftarkan penerima di file manifest.xml Anda:

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

dan kemudian tulis siaran untuk penerima ini seperti:

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();
    }
  }
}
Manoj Tarkar
sumber
0

Untuk Restart layanan di Android Oatau lebih yaitu OS> 28 Gunakan kode ini KOTLIN VERSION 1) Tambahkan izin dalam manifes

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

2) Buat Classdan perpanjang denganBroadcastReceiver

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) Deklarasikan dalam file Manifest seperti ini di bawah tag aplikasi

<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>
Cepat Belajar
sumber
-1

Tolong periksa JobScheduler untuk apis di atas 26

WakeLock adalah opsi terbaik untuk ini tetapi tidak digunakan lagi di api level 26. Silakan periksa tautan ini jika Anda mempertimbangkan level api di atas 26
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html# startWakefulService (android.content.Context,% 20android.content.Intent)

Ia mengatakan

Mulai Android O, pembatasan pemeriksaan latar belakang membuat kelas ini tidak lagi berguna secara umum. (Biasanya tidak aman untuk memulai layanan dari penerimaan siaran, karena Anda tidak memiliki jaminan bahwa aplikasi Anda berada di latar depan pada saat ini dan dengan demikian diizinkan untuk melakukannya.) Sebaliknya, developer harus menggunakan android. app.job.JobScheduler untuk menjadwalkan pekerjaan, dan ini tidak mengharuskan aplikasi menahan penguncian layar saat melakukannya (sistem akan menangani penahanan pengunci layar untuk pekerjaan tersebut).

sehingga dikatakan cosider JobScheduler
https://developer.android.com/reference/android/app/job/JobScheduler

jika ingin melakukan sesuatu selain memulai dan untuk mempertahankannya, Anda dapat menerima siaran ACTION_BOOT_COMPLETED

Jika ini bukan tentang latar depan, periksa apakah layanan Aksesibilitas dapat melakukannya

opsi lain adalah memulai aktivitas dari penerima siaran dan menyelesaikannya setelah memulai layanan dalam onCreate (), karena versi android yang lebih baru tidak memungkinkan memulai layanan dari penerima

Keras
sumber