Поймать трансляцию BOOT_COMPLETED, только если приложение уже запущено (эмулятор Android, Lollipop)

Пожалуйста, помогите мне выяснить, почему мое приложение не получает широковещательное сообщение BOOT_COMPLETED, если мое приложение уже не запущено.

Моя цель - чтобы приложение автоматически запускалось после завершения загрузки устройства (запустите мой графический интерфейс). Мой подход заключается в том, чтобы перехватить трансляцию BOOT_COMPLETED, а затем начать свою основную деятельность из метода onReceive().

Проблема в том, что мое приложение перехватывает трансляцию BOOT_COMPLETED, только если она уже запущена. Я ожидаю, что ОС запустит процесс моих приложений и вызовет точку входа onReceive() при отправке широковещательной рассылки BOOT_COMPLETED. Может ли кто-нибудь помочь мне понять, где я ошибся? Я думаю, что моя ошибка, скорее всего, в моем файле AndroidManifest.xml, но я не уверен, что мне не хватает (мой первый проект Android).

Я использую эмулятор Android Studio, Lollipop на Nexus 5. Эмулятор настроен на "Не запускать активность" при загрузке, поскольку именно так будет работать реальное оборудование.

Я отправляю трансляцию на эмулятор следующим образом, и ловлю ее, если мое приложение уже запущено:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.example.matt.catchbootcompletebroadcast

Я думаю, моя проблема в моем файле манифеста, вот он (AndroidManifest.xml):

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.matt.catchbootcompletebroadcast" android:installLocation="internalOnly">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <receiver android:name=".BootCompleteReceiver" android:enabled="true" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

И вот мой класс onReceive:

    package com.example.matt.catchbootcompletebroadcast;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.Context;
import android.util.Log;


/**
 * Created by matt on 8/20/2015.
 * To send broadcast: adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.example.matt.catchbootcompletebroadcast
 */
public class BootCompleteReceiver extends BroadcastReceiver
{
    @Override public void onReceive(Context context, Intent intent)
    {
        Log.d("ReceivedABroadcast", "Received A Broadcast");
        if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
        {
            Log.d("ReceivedBootCompleted", "Received BOOT_COMPLETED broadcast");
        }
        // Open the main activity to this application
        Intent startApp = new Intent(context, MainActivity.class);
        context.startActivity(startApp);
    }

}

Все советы очень ценятся!

2 ответа

Некоторые идеи:

Попробуйте запустить его на устройстве Android. Если это не сработает, попробуйте это: в файле манифеста Android для <receiver> тег удалить enabled а также exported часть. А внутри класса Receiver удалите if заявление.

Причина: поскольку вы уже отфильтровали намерения, полученные приемником вещания, if Заявление в значительной степени бесполезно. Если все это не работает, это может помочь вам: Android объявил, что следующие действия должны быть написаны только программно. И я считаю, что этот список содержит intent.action.BOOT_COMPLETED так что, возможно, это сработает, если вы объявите получателя программно. Для меня это выглядит правильно. Но я полагаю, что эти идеи могут стоить того.

Чтобы суммировать все комментарии выше, кроме кода в моем первом посте, решение было:

(1) Я мог только заставить свое приложение получать трансляцию BOOT_COMPLETED при загрузке с реальным оборудованием. Возможно, это возможно с эмулятором, но у меня эмулятор не работал.
(2) Откройте приложение один раз вручную перед перезагрузкой. После этого приложение будет автоматически запускаться после каждой загрузки.

(3) Мой onReceive() должен был включать флаг FLAG_ACTIVITY_NEW_TASK, иначе приложение зависало при попытке запуска. Мой onReceive() в итоге выглядел так:

    @Override public void onReceive(Context context, Intent intent)
    {
        Log.d("ReceivedABroadcast", "Received A Broadcast");
        if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
        {
            Log.d("ReceivedBootCompleted", "Received BOOT_COMPLETED broadcast");
        }
        // Open the main activity to this application
        Intent startApp = new Intent(context, MainActivity.class);
        startApp.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    
        startApp.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);  
        context.startActivity(startApp);
    }

Спасибо всем за помощь!!

Другие вопросы по тегам