Попытка запустить сервис при загрузке на Android - PullRequest
325 голосов
/ 07 мая 2010

Я пытался запустить службу, когда устройство загружается на 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");
    }
}

Ответы [ 16 ]

3 голосов
/ 04 октября 2015

Перед подключением внешнего хранилища отправляется BOOT_COMPLETE execute.Если ваше приложение установлено во внешнее хранилище, оно не получит широковещательное сообщение 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>
2 голосов
/ 25 октября 2017

Это то, что я сделал

1. Я сделал класс приемника

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 голосов
/ 22 июня 2015

Как прокомментировал @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" />
2 голосов
/ 19 марта 2015

Если вы используете 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 автоматически заполняет это разрешение строчными буквами.

1 голос
/ 20 августа 2013

На самом деле, я попал в эту проблему не так давно, и это действительно очень легко исправить, вы на самом деле ничего не делаете неправильно, если вы устанавливаете разрешение "android.intent.action.BOOT_COMPLETED" и фильтр намерений.

Обратите внимание, что если вы используете Android 4.X, вам нужно запустить широковещательный приемник, прежде чем запускать службу при загрузке, это означает, что вы должны сначала добавить активность, как только ваш широковещательный приемник запустится, ваше приложение должно функционировать как вы ожидали, однако, на Android 4.X, я не нашел способ запустить службу при загрузке без каких-либо действий, я думаю, Google сделал это по соображениям безопасности.

0 голосов
/ 29 декабря 2014

Я столкнулся с этой проблемой, если я оставлю пустой конструктор в классе получателя. После удаления пустого contsructor onRreceive методы начали работать нормально.

...