Android - Önyükleme Zamanında Başlatma Hizmeti


109

Önyükleme sırasında bir hizmet başlatmam gerekiyor. Çok aradım. Yayın alıcısından bahsediyorlar. Android geliştirmede yeni olduğum için, Android'deki hizmetler hakkında net bir resim alamadım. Lütfen biraz kaynak kodu sağlayın.


25
@ user244540: Devamlı bir değer sağlamadığı sürece (örneğin, bir VOIP istemcisi) sonsuza kadar çalışması niyetiyle lütfen "önyükleme zamanında bir hizmet başlatmayın". Bu durumlarda startForeground()hizmetinizde kullanın . Aksi takdirde, Android ve kullanıcıları hizmetinizi bir alan israfı olarak öldürecek ve Android Market'te bazı hoş olmayan yorumlar alacaksınız. Bir hizmetin önyükleme zamanında başlamasını istediğinizi düşündüğünüz çoğu durumda AlarmManager, hizmetinizin sürekli yerine periyodik olarak çalışabilmesi için daha iyi hizmet alırsınız .
CommonsWare

2
@CommonsWare: İyi nokta. Ancak, AlarmManageryeniden başlattıktan sonra periyodik çalıştırmaları başlatmak için, çok benzer adımları izlemeniz gerektiğini unutmayın ( onReceiveyöntem içeriğindeki fark )
zaman

1
@CommonsWare: Çok iyi yorum, bu soruya rastladım ve ipucunuz durumuma tam olarak uyuyor. Cevap olsaydı, oy
verirdim

Yanıtlar:


95

2
peki ya uyandırma kilidi? servis başlatılırken cihaz uykuya
dalmaya

Bir hizmeti başlatmak için cep telefonumu en az bir kez başlatmam gerekir mi?
pathe.kiran

@ MarianPaździoch haklı; bir uyandırma kilidine ihtiyacınız var. Aşağıdaki
cevabıma


En son URL'niz güncel değil
Prizoff

192

Alıcınız:

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 dosyanız:

<?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
Makalenin bağlantısı kesildi ancak yine de ihtiyacınız olan tek şey örnek kod, yani +1 :)
Alex

3
Aslında, biraz iyileştirilmesi gerekiyor, alıcıda wakelock kullanmanız gerekir, aksi takdirde hizmetinizin başlamama ihtimali çok azdır.
Vladimir Ivanov

Bunun çalışması için cep telefonumu en az bir kez başlatmam gerekir mi?
pathe.kiran

1
Hayır, ancak uygulamayı android 3.0'dan beri en az bir tane çalıştırmalısınız
Vladimir Ivanov

Bu, uygulama ayarlardan zorla kapatılırsa çalışır mı? Uygulama yine de uyanacak mı?
Srihari Karanth

32

Cihaz önyüklendiğinde otomatik olarak başlaması için kendi uygulama hizmetinizi kaydetmeniz mümkündür. Örneğin, bir http sunucusundan push olaylarını almak istediğinizde ve yeni bir olay meydana gelir gelmez kullanıcıyı bilgilendirmek istediğinizde buna ihtiyacınız vardır. Hizmet başlamadan önce kullanıcının etkinliği manuel olarak başlatması gerekmez ...

Oldukça basit. Öncelikle uygulamanıza RECEIVE_BOOT_COMPLETED izni verin. Daha sonra bir BroadcastReveiver kaydetmeniz gerekir. Biz buna BootCompletedIntentReceiver diyoruz.

Manifest.xml dosyanız artık şu şekilde görünmelidir:

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

Son adım olarak Alıcıyı uygulamanız gerekir. Bu alıcı sadece arka plan hizmetinizi başlatır.

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

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


3
Yukarıdakilerle aynı, ancak gerçekten basit ve hızlı, bu yazıya gelirseniz bunu kullanın.
dbkoren

Tek fark, bunun Manifest'teki Hizmeti doğru ilan etmesidir.
Joaquin Iurchuk

Manifestte hizmetinizi beyan etmeniz sadece doğru değil, gereklidir. Aktivitelerle aynı
Tim

Ana Faaliyet nerede? Aktivite olmadan veya android.intent.category.LAUNCHER! Uygulama yapmak doğru değildir !
nick

@ L'Esperanza elbette, görünür etkinlikleri olmayan uygulamalara sahip olabilirsiniz!
appsthatmatter

15

Burada yayınlanan çözümlerin çoğunda önemli bir parça eksik: bunu uyanık kalma kilidi olmadan yapmak, Hizmetinizin işlenmesi bitmeden ölme riskini taşır. Bu çözümü başka bir başlıkta gördüm, burada da cevapladı.

Yana WakefulBroadcastReceiver api 26 önerilmiyor önerilir 26 altında API Düzeyleri için

Bir uyandırma kilidi almanız gerekir. Neyse ki, Destek kitaplığı bize bunu yapmamız için bir sınıf veriyor :

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

ardından, Hizmetinizde uyandırma kilidini açtığınızdan emin olun:

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

WAKE_LOCK iznini eklemeyi ve alıcınızı bildirime kaydetmeyi unutmayın:

<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
Manifest dosyasında SimpleWakefulReceiver bir hizmet değildir.
Desmond Lua

1
WakefulBroadcastReceiver kullanımdan kaldırıldı
Amin Pinjari

5

BOOT_COMPLETE ve REBOOT için kaydolmalısınız

<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
Literatür, 'android.intent.action.REBOOT'un yalnızca ayrıcalıklı uygulama / kod tarafından kullanılabileceğini söylüyor. Aksi takdirde bunun avantajı nedir?
XMAN

1

Ayrıca, oluşturduğunuz hizmeti Manifest ve kullanım iznine şu şekilde kaydedin:

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

ve sonra braod cast'da Alıcı hizmetinizi arayın

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

Neden hizmetin içindeki Amaç Filtresi?
Joaquin Iurchuk

çünkü önyükleme tamamlandığında MyService çağrılacak
SoftEye

Bu durumda servis sınıfınız servis ve yayın alıcısını genişletecektir. Haklı mıyım
Joaquin Iurchuk

Sınıf, Hizmet sınıfını genişletecektir.
SoftEye

2
Burada yanlış bir şeyler var. Hizmetin Yayın Alıcısından çağrılması gerekiyordu. Ama hizmetinizin yayın alıcısı olduğunu söylüyorsunuz ve bundan sonra hizmet sınıfının Yayın Alıcısını genişletmediğini söylüyorsunuz. Böylece Boot Completed Broadcast'i almayacaktır. OnReceive yöntemini ilan ettiğinizde neyi geçersiz kılıyorsunuz?
Joaquin Iurchuk

0

Önce manifest.xml dosyanıza bir alıcı kaydedin:

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

ve sonra bu alıcı için aşağıdaki gibi bir yayın yazın:

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

Hizmeti yeniden başlatmak için Android Oveya daha fazlası, yani OS> 28 Bu kodu kullanın KOTLIN VERSION 1) Bildirime izin ekleyin

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

2) Bir oluşturun Classve genişletinBroadcastReceiver

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) Manifest dosyasında, uygulama etiketi altında bunun gibi beyan

<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 JobScheduler'ı 26'nın üzerindeki apiler için kontrol edin

WakeLock bunun için en iyi seçenekti, ancak api seviyesi 26'da kullanımdan kaldırıldı Pls, API seviyelerinin 26'nın üzerinde olduğunu düşünüyorsanız bu bağlantıyı kontrol edin
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html# startWakefulService (android.content.Context,% 20android.content.Intent)

Diyor ki

Android O'dan itibaren, arka plan denetimi kısıtlamaları bu sınıfı artık genel olarak kullanışlı hale getirmiyor. (Bir hizmeti yayının alınmasından itibaren başlatmak genellikle güvenli değildir, çünkü bu noktada uygulamanızın ön planda olduğuna ve dolayısıyla bunu yapmanıza izin verildiğine dair herhangi bir garantiniz yoktur.) Bunun yerine, geliştiriciler android kullanmalıdır . app.job.JobScheduler'ın bir işi planlaması için ve bu, uygulamanın bunu yaparken bir uyandırma kilidi tutmasını gerektirmez (sistem iş için bir uyandırma kilidi tutmaya özen gösterecektir).

böylece cosider JobScheduler dediği gibi
https://developer.android.com/reference/android/app/job/JobScheduler

Başlamaktan ve devam ettirmekten başka bir şey yapmaksa ACTION_BOOT_COMPLETED yayınını alabilirsiniz

Ön planla ilgili değilse lütfen bir Erişilebilirlik hizmetinin yapıp yapamayacağını kontrol edin

başka bir seçenek, yayın alıcısından bir etkinlik başlatmak ve onCreate () içinde hizmeti başlattıktan sonra bitirmektir, çünkü daha yeni android sürümleri alıcılardan hizmet başlatmaya izin vermez

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.