Android-부팅시 서비스 시작


109

부팅 할 때 서비스를 시작해야합니다. 나는 많이 검색했다. 그들은 Broadcastreceiver에 대해 이야기하고 있습니다. Android 개발을 처음 접했기 때문에 Android 서비스에 대한 명확한 그림을 얻지 못했습니다. 소스 코드를 제공해주세요.


25
@ user244540 : 지속적으로 가치를 제공하지 않는 한 (예 : VOIP 클라이언트) 영원히 실행하려는 의도로 "부팅시 서비스를 시작"하지 마십시오. 이 경우 startForeground()서비스에서 사용 하십시오. 그렇지 않으면 Android와 사용자가 공간 낭비로 인해 서비스를 중단하고 Android 마켓에서 불쾌한 댓글을 받게됩니다. 부팅시 서비스가 시작되기를 원한다고 생각하는 대부분의 상황에서는 서비스를 지속적 으로AlarmManager 실행 하는 것이 아니라 주기적으로 실행할 수 있도록 사용 하는 것이 좋습니다 .
CommonsWare 2010

2
@CommonsWare : 좋은 지적입니다. 그러나 AlarmManager재시작 후 주기적인 실행을 시작 하려면 매우 유사한 단계를 수행해야합니다 ( onReceive방법 의 내용에 차이가 있음 )
stanwise

1
@CommonsWare : 아주 좋은 의견입니다.이 질문을 우연히 발견했고 귀하의 힌트가 제 상황에 정확히 맞습니다. 이 답변이라면 나는 :-) 그것을 투표 것이다
chiccodoro

답변:


95

2
wake lock은 어떻습니까? 서비스가 시작되는 동안 장치를 이동하기로 결정할 수도 자고 ...
마리아 Paździoch

서비스를 시작하려면 모바일을 한 번 이상 부팅해야합니까 ??
pathe.kiran

@ MarianPaździoch가 맞습니다. wake lock이 필요합니다. 아래 내 대답을 참조하십시오 : stackoverflow.com/a/30970167/473201
phreakhead


최근 URL은 오래된
Prizoff

192

수신기 :

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 :

<?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
기사에 대한 링크는 죽었지 만 어쨌든 샘플 코드 만 있으면되므로 +1 :)
Alex

3
실제로는 약간의 개선이 필요합니다. 수신기에서 wakelock을 사용해야합니다. 그렇지 않으면 서비스가 시작되지 않을 가능성이 약간 있습니다.
Vladimir Ivanov

이 작업을 수행하려면 모바일을 한 번 이상 부팅해야합니까 ??
pathe.kiran

1
아니,하지만 당신은 안드로이드 3.0부터 응용 프로그램 중 하나 이상을 실행해야합니다
블라디미르 이바노프

앱이 설정에서 강제 종료 된 경우 작동합니까? 앱이 계속 깨어나나요?
Srihari Karanth

32

기기가 부팅되면 자동으로 시작되도록 자체 애플리케이션 서비스를 등록 할 수 있습니다. 예를 들어, http 서버에서 푸시 이벤트를 수신하고 새 이벤트가 발생하는 즉시 사용자에게 알리려면이 정보가 필요합니다. 사용자는 서비스가 시작되기 전에 수동으로 활동을 시작할 필요가 없습니다.

아주 간단합니다. 먼저 앱에 RECEIVE_BOOT_COMPLETED 권한을 부여하세요. 다음으로 BroadcastReveiver를 등록해야합니다. 우리는 그것을 BootCompletedIntentReceiver라고 부릅니다.

이제 Manifest.xml은 다음과 같습니다.

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

마지막 단계로 Receiver를 구현해야합니다. 이 수신기는 백그라운드 서비스를 시작합니다.

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

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


3
위와 동일하지만 정말 간단하고 빠릅니다.이 게시물에 오면 이것을 사용하십시오.
dbkoren 2013-08-16

유일한 차이점은 이것이 매니페스트에 서비스를 선언한다는 것입니다.
Joaquin Iurchuk 2015 년

매니페스트에서 서비스를 선언하는 것은 정확할뿐만 아니라 필수입니다. 활동과 동일
Tim

주요 활동은 어디에!? 활동없이 앱을 만드는 것은 올바르지 않습니다 android.intent.category.LAUNCHER!
nick

@ L' Esperanza 확실히 눈에 보이는 활동이없는 앱을 가질 수 있습니다!
appsthatmatter 2011

15

여기에 게시 된 대부분의 솔루션에는 중요한 부분이 누락되어 있습니다. wake lock없이 수행하면 처리가 완료되기 전에 서비스가 종료 될 위험이 있습니다. 이 솔루션을 다른 스레드에서 보았고 여기에서도 대답했습니다.

이후 WakefulBroadcastReceiver는 API 26에서 더 이상 사용되지 않습니다 그것은 추천 (26) 아래의 API 레벨에 대한

wake lock을 얻어야합니다. 다행히 지원 라이브러리는 이를 수행 할 수 있는 클래스제공 합니다.

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

그런 다음 서비스에서 wake lock을 해제해야합니다.

    @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 권한을 추가하고 매니페스트에 수신기를 등록하는 것을 잊지 마십시오.

<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
매니페스트 파일에서 SimpleWakefulReceiver는 서비스가 아닙니다.
Desmond Lua

1
WakefulBroadcastReceiver가 더 이상 사용되지 않음
Amin Pinjari

5

BOOT_COMPLETE 및 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
문헌에 따르면 'android.intent.action.REBOOT'는 권한있는 앱 / 코드에서만 사용할 수 있습니다. 그렇지 않으면 어떤 이점이 있습니까?
XMAN

1

또한 생성 된 서비스를 매니페스트에 등록하고 다음과 같이 사용 권한을 사용합니다.

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

그런 다음 braod cast Reciever에서 서비스에 전화하십시오.

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

왜 서비스 내부에 인 텐트 필터가 있습니까?
Joaquin Iurchuk 2015 년

부팅은 다음이면 MyService를 호출할지 완료 할 때 때문에
SoftEye

이 경우 서비스 클래스는 서비스 및 브로드 캐스트 수신기를 확장합니다. 내가 맞아?
Joaquin Iurchuk 2015

클래스는 서비스 클래스를 확장합니다.
SoftEye

2
여기에 문제가 있습니다. 서비스는 브로드 캐스트 수신기에서 호출되어야합니다. 하지만 서비스가 브로드 캐스트 수신기라고 말하고 그 후에 서비스 클래스가 브로드 캐스트 수신기를 확장하지 않는다고 말하고 있습니다. 따라서 부팅 완료 브로드 캐스트를 수신하지 않습니다. onReceive 메서드를 선언 할 때 무엇을 재정의합니까?
Joaquin Iurchuk 2015 년

0

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

다음과 같이이 수신기에 대한 브로드 캐스트를 작성하십시오.

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

Android OOS> 28 이상 에서 서비스를 다시 시작 하려면이 코드를 사용하십시오 KOTLIN VERSION 1) 매니페스트에 권한 추가

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

2) 만들기 Class및 확장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) 애플리케이션 태그 아래에 이와 같은 매니페스트 파일에서 선언

<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 이상의 API를 확인합니다.

WakeLock 은 이에 대한 최선의 옵션이지만 api 레벨 26에서는 더 이상 사용되지 않습니다. api 레벨이 26 이상인 경우이 링크를 확인하십시오.
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html# startWakefulService (android.content.Context, % 20android.content.Intent)

그것은 말한다

Android O부터 백그라운드 확인 제한으로 인해이 클래스는 더 이상 일반적으로 유용하지 않습니다. (이 시점에서 앱이 포 그라운드에 있고 따라서 그렇게 할 수 있다는 보장이 없기 때문에 일반적으로 브로드 캐스트 수신부터 서비스를 시작하는 것은 안전하지 않습니다.) 대신 개발자는 android를 사용해야합니다 . app.job.JobScheduler 를 사용하여 작업을 예약 할 수 있으며, 그렇게하는 동안 앱이 wake lock을 유지할 필요가 없습니다 (시스템이 작업에 대한 wake lock을 유지합니다).

그래서 cosider JobScheduler
https://developer.android.com/reference/android/app/job/JobScheduler

시작하고 유지하는 것보다 무언가를하려면 방송을 수신 할 수 있습니다. ACTION_BOOT_COMPLETED

전경에 관한 것이 아니라면 접근성 서비스가 할 수 있는지 확인하십시오.

또 다른 옵션은 broadcast receiver에서 활동을 시작하고 onCreate () 내에서 서비스를 시작한 후 완료하는 것입니다. 최신 Android 버전에서는 수신기에서 서비스를 시작할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.