Android 부팅시 서비스 시작


332

장치가 Android에서 부팅 될 때 서비스를 시작하려고했지만 작동하지 않습니다. 온라인에서 여러 링크를 살펴 보았지만 코드가 작동하지 않습니다. 내가 뭔가를 잊고 있습니까?

AndroidManifest.xml

<receiver
    android:name=".StartServiceAtBootReceiver"
    android:enabled="true"
    android:exported="false"
    android:label="StartServiceAtBootReceiver" >
    <intent-filter>
        <action android:name="android.intent.action._BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<service
    android:name="com.test.RunService"
    android:enabled="true" />

BroadcastReceiver

public void onReceive(Context context, Intent intent) {
    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
        Intent serviceLauncher = new Intent(context, RunService.class);
        context.startService(serviceLauncher);
        Log.v("TEST", "Service loaded at start");
    }
}

2
나는 내가 한 일을 모르지만 지금은 효과가 있다고 생각합니다. 수신자에 대한 android : permission = "android.permission.RECEIVE_BOOT_COMPLETED"
Alex

<action android : name = "android.intent.action._BOOT_COMPLETED"/>에서 여분의 "_"을 (를) 확인
하셨나요

시스템이 리시버를 호출 할 수 있도록 내 보낸 값이 true 여야합니다. 아니면 기본적으로 사실입니까?
Eugen Pechanec

Oreo를 위해 여기를보십시오 : stackoverflow.com/questions/44502229/…
Andy Weinstein

답변:


601

다른 답변은 좋아 보이지만 모든 것을 하나의 완전한 답변으로 마무리한다고 생각했습니다.

AndroidManifest.xml파일에 다음이 필요 합니다.

  1. 당신의 <manifest>요소에서 :

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  2. 당신에 <application>요소 (당신을위한 완전한 [또는 상대] 클래스 이름을 사용하십시오 BroadcastReceiver) :

    <receiver android:name="com.example.MyBroadcastReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
    

    (당신은 필요하지 않습니다 android:enabled, exported속성 등 : 안드로이드 기본 설정이 올바른지)

    에서 MyBroadcastReceiver.java:

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

원래 질문에서 :

  • 경우는 분명하지 않다 <receiver>요소가 있었다 <application>요소
  • 에 대한 정규화 된 (또는 상대적) 올바른 클래스 이름 BroadcastReceiver이 지정 되었는지 확실하지 않습니다.
  • 에 오타가 있었다 <intent-filter>

2
이것은 좋아 보인다. 나는 이것을 기초로 사용할 것입니다, 감사합니다 :). 확인 표시 나 공언 또는 슬프게도 슬프게도 :(. 누구든지 이것을 확인?
Nanne

51
보완 : 앱이 내부 메모리에 설치되어 있는지 확인 <manifest xmlns : android = "..."package = "..."android : installLocation = "internalOnly">
Bao Le

2
<overceiver> 태그의 Android Jellybean 4.2.2에서는 stackoverflow.com/questions/16671619/…에
Piovezan

6
수신자가 다른 것들에 사용되는 경우 : <br> if ( "android.intent.action.BOOT_COMPLETED".equals (intent.getAction ())) {Intent serviceIntent = new Intent (context, Service_Location.class); // i.putExtra ( "KEY1", "서비스에서 사용할 값"); context.startService (serviceIntent); }
Gunnar Bernstein

2
대신 developer.android.com/reference/android/support/v4/content/… 를 확장해야 합니다. 장치 웨이크 업 이벤트를 수신 한 다음 작업을 서비스로 전달하는 브로드 캐스트 리시버를 구현하는 일반적인 패턴에 대한 헬퍼는 전환 중에 디바이스가 다시 휴면 상태로 돌아 가지 않도록합니다. 이 클래스는 부분 웨이크 잠금을 생성하고 관리합니다. 사용하려면 WAKE_LOCK 권한을 요청해야합니다.
Damian

84

추가 정보 : BOOT_COMPLETE는 외부 저장소가 마운트 되기 전에 응용 프로그램으로 전송됩니다 . 따라서 응용 프로그램을 외부 저장소에 설치하면 BOOT_COMPLETE 브로드 캐스트 메시지가 수신되지 않습니다.

자세한 내용 은 "부트 완료"를 수신하는 브로드 캐스트 수신기 섹션에 있습니다 .


위의 문제를 방지하기 위해 개발자는 앱의 매니페스트에서 "android : installLocation ="internalOnly "를 설정할 수 있습니다. 이것이 나쁜 생각입니까? 스마트 폰 앱의 경우 모든 사용자 중 99.9 % (내 추측)가 앱을 정상적으로 설치하면 내부 저장 장치가 아닌 외부 저장 장치를 사용하여, 매니페스트에 "internalOnly"또한 잘 될 것 같다 나는 당신에이 가지고있는 생각이나 아이디어 감사하겠습니다..을
AJW

69

장치 부팅시 서비스를 시작하는 방법 (자동 실행 앱 등)

먼저 : Android 3.1 이상 버전 이후로 사용자가 앱을 한 번 이상 시작한 적이 없거나 "강제 종료"응용 프로그램을 사용하면 BOOT_COMPLETE를받지 못합니다. 이것은 맬웨어가 자동으로 서비스를 등록하는 것을 방지하기 위해 수행되었습니다. 이 보안 허점은 최신 버전의 Android에서 닫혔습니다.

해결책:

활동이있는 앱을 만듭니다. 사용자가 한번 실행하면 앱은 BOOT_COMPLETE 브로드 캐스트 메시지를 수신 할 수 있습니다.

두 번째로 : 외부 저장소를 마운트하기 전에 BOOT_COMPLETE가 전송됩니다. 앱이 외부 저장소에 설치되어 있으면 BOOT_COMPLETE 브로드 캐스트 메시지가 수신되지 않습니다.

이 경우 두 가지 해결책이 있습니다.

  1. 내부 저장소에 앱 설치
  2. 내부 저장소에 다른 작은 앱을 설치하십시오. 이 앱은 BOOT_COMPLETE를 수신하고 외부 저장소에서 두 번째 앱을 실행합니다.

앱이 이미 내부 저장소에 설치된 경우 아래 코드를 사용하면 장치 부팅시 서비스를 시작하는 방법을 이해할 수 있습니다.


Manifest.xml에서

허가:

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

BOOT_COMPLETED 리시버를 등록하십시오.

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

서비스를 등록하십시오 :

<service android:name="org.yourapp.YourCoolService" />

수신기 OnBoot.java에서 :

public class OnBoot extends BroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // Create Intent
        Intent serviceIntent = new Intent(context, YourCoolService.class);
        // Start service
        context.startService(serviceIntent);

    }

 }

장치가 RECEIVE_BOOT_COMPLETED를 잡지 않으면 HTC의 경우 Manifest 에이 코드를 추가해야 할 수도 있습니다.

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

수신자는 이제 다음과 같이 보입니다 :

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

재시작 에뮬레이터 또는 실제 장치없이 BOOT_COMPLETED를 테스트하는 방법은 무엇입니까? 그것은 간단합니다. 이 시도:

adb -s device-or-emulator-id shell am broadcast -a android.intent.action.BOOT_COMPLETED

장치 ID를 얻는 방법? ID가있는 연결된 장치 목록을 가져옵니다.

adb devices

ADT의 adb는 기본적으로 다음에서 찾을 수 있습니다.

adt-installation-dir/sdk/platform-tools

즐겨! )


첫 단락은 자본이었습니다. 디버거에서 실행할 수 없습니다.
estornes

34

와 함께

<action android:name="android.intent.action.BOOT_COMPLETED" />  

또한 사용

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

HTC 장치가 BOOT_COMPLETED를 잡지 못하는 것 같습니다


HTC 장치에 대한 권한과 비슷한 것을 추가해야합니까?
Nanda

2
이것은 어떤 상황에서는 유용 할 수 있지만 HTC 빠른 부팅은 시스템 상태가 파일 시스템에 저장되고 android.intent.action.QUICKBOOT_POWERON빠른 부팅에서 복원 할 때만 전송되는 최대 절전 모드라는 것을 알고 있습니다. 즉, 빠른 부팅에서 복구 할 때 알람이 유지되는 경우 알람 재설정과 같은 작업을 수행 할 필요가 없습니다. 따라서 <action android:name="android.intent.action.QUICKBOOT_POWERON" />사용자가 장치가 부팅되었다고 생각할 때 무언가를하려는 경우 에만 사용해야 합니다.
HexAndBugs

2
앱 개발자의 관점에서 볼 때 동작이 HTC 장치에만있는 경우이를 사용해서는 안됩니다. BOOT_COMPLETED는 설명서에 따라 장치를 켤 때 항상 전송되기 때문입니다. 일부 다른 제조업체는 다른 빠른 부팅 방법을 생각 해낼 수 있으며 각 사양에 따라 코드를 엉망으로 만들 수 있습니다.
Subin Sebastian

@HexAndBugs Fast Boot가 시스템 상태가 파일 시스템에 저장되는 최대 절전 모드임을 확인할 수 있습니까? 시스템 상태가 저장되지 않은 경우 빠른 부팅 후 향후 알림에 사용되는 경보를 재설정하고 싶습니다. 권고하십시오.
AJW

20

질문의 시작 부분에 오타가 있습니다.

<action android:name="android.intent.action._BOOT_COMPLETED"/>

대신에 :

<action android:name="android.intent.action.BOOT_COMPLETED"/>

하나의 작은 "_"와이 모든 문제 :)


13

Fast Boot옵션 이 원인 일 수 있음을 알았습니다 . Settings>Power

이 옵션을 해제하면 응용 프로그램에서이 브로드 캐스트를 수신하지만 그렇지 않으면 수신되지 않습니다.

그건 그렇고, 나는 Android 2.3.3에있다 HTC Incredible S.

도움이 되길 바랍니다.


문제의 확실한 원인. Android 4.0.3을 실행하는 HTC Desire C에서도 관찰되었습니다.
Zelimir


7

언급 된 답변과 트릭을 모두 시도한 후에 마침내 휴대 전화에서 코드가 작동하지 않는 이유를 알았습니다. "Huawei Honor 3C Android 4.2.2 " 와 같은 일부 Android 휴대 전화 에는 설정에 통계 관리자 메뉴가 있으며 목록에서 앱을 확인해야합니다. :)


5

추가 <category>태그가 있는데 그 차이가 있는지 모르겠습니다.

<receiver android:name="BootIntentReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
            <category android:name="android.intent.category.HOME" />  
        </intent-filter>  
</receiver>

"android.intent.action.BOOT_COMPLETED".equals(intent.getAction()수신자가 어쨌든 그 의도 만 수신하기 때문에 if-clause 생략을 시도 했습니까 ?


이 시도하고 내가 또한이 얘기를 깜빡 했네요 BTW를 작동하지 않았다 <사용-권한 안드로이드 : = "android.permission.RECEIVE_BOOT_COMPLETED"/ 이름>
알렉스

2
경우에 따라 : android.intent.category.HOME을 AndroidManifest의 태그에 추가하면 해킹을 사용하여 호환성 모드를 해제 한 후에도 Samsung Galaxy Tab에서 호환 모드로 앱을 실행합니다. 이것이 다른 탭과 동일한 지 확실하지 않습니다. HOME 카테고리를 전혀 설정하지 않는 것이 좋습니다. 불필요합니다.
moonlightcheese


3

외부 저장소를 마운트하기 전에 BOOT_COMPLETE가 실행됩니다. 앱이 외부 저장소에 설치되어 있으면 BOOT_COMPLETE 브로드 캐스트 메시지를받지 않습니다. 이를 방지하기 위해 내부 저장소에 응용 프로그램을 설치할 수 있습니다. menifest.xml 에이 줄을 추가하면됩니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="internalOnly"
... >

일부 HTC 장치는 최대 절전 모드와 비슷하고 실제 재부팅이 아닌 "빠른 부팅"기능을 활성화 할 수 있으므로 BOOT_COMPLETE 의도를 제공하지 않아야합니다. 이를 복구하기 위해 수신기 내부에이 의도 필터를 추가 할 수 있습니다.

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>

제안한 바와 같이, 위의 문제를 방지하기 위해 개발자는 앱의 매니페스트에 "android : installLocation ="internalOnly "를 설정할 수 있습니다. 이것이 나쁜 생각입니까? 스마트 폰 앱의 경우 모든 사용자의 99.9 % (내 추측) 외부 저장소가 아닌 내부 저장소를 사용하여 앱을 정상적으로 설치하면 매니페스트에 "internalOnly"가 추가 된 것 같습니다. AJW
AJW

3

이것이 내가 한 일입니다

1. Receiver 클래스를 만들었습니다

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //whatever you want to do on boot
       Intent serviceIntent = new Intent(context, YourService.class);
       context.startService(serviceIntent);
    }
}

2. 매니페스트에서

<manifest...>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <application...>
        <receiver android:name=".BootReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    ...

3. MainActivity에서 수신기를 "설정"해야 할 경우 onCreate 내부에있을 수 있습니다.

...
 final ComponentName onBootReceiver = new ComponentName(getApplication().getPackageName(), BootReceiver.class.getName());
        if(getPackageManager().getComponentEnabledSetting(onBootReceiver) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
        getPackageManager().setComponentEnabledSetting(onBootReceiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
...

내가 ApiDemos로부터 배운 마지막 가파른


2

Android Studio를 사용 중이며 자동 완성을 좋아하는 경우 알려드립니다 .Android Studio v 1.1.0을 사용하고 있으며 다음 권한에 대해 자동 완성을 사용했습니다.

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

그리고 Android Studio 자동 완성은 RECEIVE_BOOT_COMPLETED모두 소문자 로 완료 receive_boot_completed되었으며 부팅시 서비스를 시작하기 위해 수행해야 할 일에 대한 체크리스트를 이미 체크 아웃했기 때문에 머리카락을 계속 뽑았습니다. 방금 다시 확인했습니다

Android Studio는이 권한을 소문자로 자동 완성합니다.


2

@Damian이 언급 했듯이이 스레드의 모든 답변이 잘못되었습니다. 이와 같이 수동으로 수행하면 장치가 잠자기 상태에서 서비스가 중지 될 위험이 있습니다. 먼저 깨우기 잠금을 얻어야합니다. 운좋게도 지원 라이브러리는 이 작업을 수행 할 수 있는 클래스제공 합니다.

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

그런 다음 서비스에서 웨이크 잠금을 해제하십시오.

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

작은 질문 나는 의심의 여지가 있습니다. 내 경우 서비스 A는 서비스 하지 IntentService 때문에, 나는이 방법을 사용할 수 없습니다 onHandleIntend의 방법이 될 수 없습니다 재정의 간단한에서 서비스 ?
paolo2988

같은 문제가 있습니다. 도와 주실 래요? 감사! stackoverflow.com/questions/35373525/starting-my-service
Ruchir Baronia 2018

아마도 사용 onNewIntent()합니까? 또는 IntentService의 소스를보고 서비스가 일치하도록하기 위해 무엇을해야하는지 확인할 수 있습니다.
phreakhead

1

사실, 오래 전에이 문제에 봉착했으며 실제로 수정하기가 정말 쉽습니다. "android.intent.action.BOOT_COMPLETED"권한과 의도 필터 를 설정하면 실제로 아무런 문제가 없습니다 .

Android 4.X의 경우 부팅시 서비스를 시작하기 전에 브로드 캐스트 리스너를 실행해야합니다. 즉, 브로드 캐스트 리시버가 실행되면 활동을 먼저 추가해야합니다. 그러나 Android 4.X에서는 아무런 활동없이 부팅 할 때 서비스를 시작하는 방법을 찾지 못했습니다. 보안상의 이유로 Google이 그렇게했다고 생각합니다.


0

수신자 클래스에 빈 생성자를두면이 문제에 직면했습니다. 빈 컨스트럭터를 제거한 후 Rreceive methos가 정상적으로 작동하기 시작했습니다.

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