Поймать трансляцию 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);
}
Спасибо всем за помощь!!