Android BOOT_COMPLETED не получен, когда приложение закрыто
Я знаю, что этот вопрос часто задавался на сайте, но, похоже, я не могу найти решение. Мой BOOT_COMPLETED получатель не вызывается, когда приложение не запущено.
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.startuptest"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="internalOnly">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.startuptest.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>
<receiver android:name="com.example.startuptest.StartUpBootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
StartUpBootReceiver:
public class StartUpBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("startuptest", "StartUpBootReceiver " + intent.getAction());
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
}
}
}
Если приложение работает, и я имитирую вызов с
adb shell
am broadcast -a android.intent.action.BOOT_COMPLETED
Событие получено правильно, однако, если приложение закрыто, событие не получено и не получено при запуске.
Я установил приложение и запустил его пару раз, чтобы убедиться, что оно зарегистрировано. Я довольно потерян на этом, поэтому любые советы будут высоко оценены.
Изменить: я вижу в журналах, что все другие закрытые приложения (Youtube, FileObserver и т. Д.) Получают событие boot_completed, только не мое.
9 ответов
Я запускаю свое приложение, когда BOOT_COMPLETED, поэтому я знаю, что оно работает. я добавить Log.d
это не покажет. я добавить Toast
это шоу. Небольшие отличия в Manifest.xml
<receiver android:name="com.example.startuptest.StartUpBootReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Начиная с Android 3.1 все приложения после установки переводятся в состояние "остановлено" (это то же состояние, в котором заканчивается приложение после принудительной остановки приложения из приложения "Настройки").
Находясь в состоянии "остановлено", приложение не будет работать по любой причине, кроме как при ручном запуске действия.(Значение нет BroadcastReceviers
(ACTION_PACKAGE_INSTALLED
, BOOT_COMPLETED
и т. д.) будет вызываться независимо от события, для которого они зарегистрированы, пока пользователь не запустит приложение вручную.)
Это шаг против вредоносных программ со стороны Google. Google выступает за то, чтобы пользователи сначала запустили действие из панели запуска, прежде чем это приложение сможет сделать многое. предотвращение BOOT_COMPLETED
от доставки до запуска операции является логическим следствием этого аргумента.
Подробнее об этом:
http://developer.android.com/about/versions/android-3.1.html
http://commonsware.com/blog/2011/07/05/boot-completed-regression.html
http://devmaze.wordpress.com/2011/12/05/activating-applications/
Каждый ответ здесь добавляет небольшой кусочек информации, поэтому вот краткое изложение всего этого:
Чтобы убедиться, что вы получите BOOT_COMPLETED, убедитесь, что вы делаете следующее:
Добавьте ваш получатель в манифест (не забудьте флаги):
<receiver android:name="com.yourpacakge.BootReceiver" android:exported="true" android:enabled="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </receiver>
Добавить разрешение:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
После установки приложения оно должно быть как минимум один раз, вручную, пользователем, чтобы получить событие завершения загрузки.( Подробнее)
Боролся с той же проблемой, причина в том, что вы используете Log.d для отслеживания вашего приложения в logcat, к сожалению, когда вы перезагружаете свой телефон, приложение получает BOOT_Complete, но вы не можете видеть его, потому что оно не регистрируется в logcat.
попробуйте сделать Toast
с текстом вместо Log.d
чтобы убедиться, что BOOT_COMPLETED или не получен.
надеюсь это поможет.
Вот версия C#, если вы, ребята, хотите этого. Мои тесты показывают, что это работает в значительной степени безупречно, и запуск довольно быстр. Хотя обратите внимание, что добавление его как в C#, так и в AndroidManifest.xml нарушает его (по крайней мере, для меня).
Я также добавил несколько хороших и полезных примеров, которые мне хотелось бы узнать у кого-то, а не изучать их самому, читая документальные фильмы и тому подобное.
[BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true, Name = "com.nevaran.startup.StartUpBootReceiver")]
[IntentFilter(new string[] {
Intent.ActionBootCompleted
, Intent.ActionLockedBootCompleted
, Intent.ActionMyPackageReplaced
, Intent.ActionUserInitialize
, "android.intent.action.QUICKBOOT_POWERON"
, "com.htc.intent.action.QUICKBOOT_POWERON"
})]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if( intent.Action.Equals(Intent.ActionBootCompleted)
|| intent.Action.Equals(Intent.ActionLockedBootCompleted)
|| intent.Action.Equals(Intent.ActionUserInitialize)
|| intent.Action.Equals("android.intent.action.QUICKBOOT_POWERON")
|| intent.Action.Equals("com.htc.intent.action.QUICKBOOT_POWERON")
)
{
//run code here only if its started by the chosen actions
}
//some code that doesnt care about which action is triggered by
}
}
Чтобы решить эту проблему, вы можете использовать firebaseJobDispatcher для автоматического вызова, у firebaseJobDispatcher будет код для реагирования на ваши сервисы, да, через некоторое время сервисы могут быть остановлены ОС, но ваш firebaseJobDispatcher снова активирует ваши сервисы. FirebaseJobDispatcher имеет множество свойств, из которых вы можете определить область этого;
как это работает, для более подробной информации https://github.com/firebase/firebase-jobdispatcher-android
Добавление следующего, казалось, сработало для меня вместе с действием намерения BOOT_COMPLETED
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
Если вы хотите узнать фактическую причину, по которой BOOT_COMPLETE не работает или не получает. Я предлагаю вам перейти на официальный сайт разработки Android. Они объяснили с точным решением.
Для получения трансляции вам необходимо установить флаги android:enabled="true" android:exported="true" в манифесте.
<receiver android:name=".bootReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>