BroadcastReceiver не получает BOOT_COMPLETED
Я искал здесь похожие проблемы, но по какой-то причине мой BroadcastReceiver никогда не заканчивал тем, что получил намерение android.intent.action.BOOT_COMPLETED.
Вот мой (относительный) файл Android.Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
<receiver android:name=".BootReceiver"
android:enabled="true"
android:exported="true"
android:label="BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
И вот фактический получатель.
public class BootReceiver extends BroadcastReceiver {
private static final String TAG="BootReceiver";
@Override public void onReceive(Context context,Intent intent){
try{
context.startService(new Intent(context,ConnectivityListener.class));
Log.i(TAG,"Starting Service ConnectivityListener");
}catch(Exception e){
Log.e(TAG,e.toString());
}
}
}
Спасибо! Любая помощь с благодарностью
9 ответов
Оказывается, получатель не был в теге манифеста. Упс! Спасибо за помощь ребята! Самое плохое в тестировании - это постоянно выключать и включать телефон.:П
Вы можете эмулировать все широковещательные действия, подключившись через adb к устройству и открыв оболочку устройства.
Вот так:
- открыть консоль / терминал и перейти к /platform-tools
- тип
adb shell
или на Linux/ Mac./adb shell
- в типе оболочки
am broadcast -a android.intent.action.BOOT_COMPLETED
или какое-либо действие вы хотите уволить
Есть множество хороших команд, идущих с adb или оболочкой adb. Просто попробуйте
С уважением, Фло
редактировать: черт возьми, я хотел этот ответ в качестве ответа на "пришлось каждый раз включать / выключать телефон". Извините ребята
Я публикую это в надежде, что это будет полезно для того, кто попробовал все, но все еще не может запустить его при загрузке после установки или раньше работал и больше не работает.
Итак, если вы добавили разрешение:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
И зарегистрировал свой получатель:
<receiver android:name="com.example.startuptest.StartUpBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
И закодировал твой BroadcastReceiver
:
public class StartUpBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
...
}
}
}
Начиная с Android 3.1 все приложения после установки переводятся в состояние "остановлено" (это то же состояние, в котором заканчивается приложение после принудительной остановки приложения из приложения "Настройки").
Находясь в состоянии "остановлено", приложение не будет работать по любой причине, кроме как при ручном запуске действия. (Значение нет BroadcastRecevier
(ACTION_PACKAGE_INSTALLED
, BOOT_COMPLETED
и т. д. будут вызываться независимо от события, для которого они зарегистрированы, пока пользователь не запустит приложение вручную.)
Это дизайнерское решение Google по предотвращению вредоносных программ. Google выступает за то, чтобы пользователи сначала запустили действие с панели запуска, прежде чем это приложение сможет многое сделать. предотвращение BOOT_COMPLETED
от доставки до запуска операции является логическим следствием этого аргумента.
Как только пользователь запустит какое-либо действие в вашем приложении один раз, вы получите трансляцию 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/
Если ваше приложение установлено на внешнее хранилище (SD-карту), вы никогда не получите действие Boot Complete. Так что вы должны указать android:installLocation="internalOnly"
в manifest tag
,
Ваш <uses-permission>
элемент должен быть непосредственным потомком <manifest>
элемент, и ваш список кода выше предполагает, что это не так.
Вот пример проекта, демонстрирующего использование BOOT_COMPLETED
,
Похоже, что это приоритетная тема для этой проблемы, поэтому я хотел добавить решение для моих коллег по C#. Я ломал голову, пытаясь понять, что я делаю неправильно, попробовав все здесь, но безрезультатно. Я, наконец, выяснил, что было не так, и это немного отличается от совета по разработке C# Mono. По сути, это сводится к тому, что я только что выучил трудным путем. С C# НЕ МОДИФИЦИРУЙТЕ AndroidManifest.xml вручную!
См. Это руководство для справки: Xamarin: Работа с AndroidManifest.xml
Более конкретно для этой проблемы, вот как вы это делаете.
Во-первых, в свойствах вашего проекта на вкладке Manifest есть список флажков для выбора разрешений, которые вы хотите предоставить, одним из которых является RECEIVE_BOOT_COMPLETED. Проверьте это, чтобы предоставить эти разрешения.
Во-вторых, вам нужно поместить соответствующие теги в ваш класс BroacastReceiver.
[BroadcastReceiver]
[IntentFilter(new String[]{ Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.LowPriority)]
public class MyBootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// Do your boot work here, set alarms, show toasts, whatever
}
}
Заключительная часть [IntentFilter()], имеющая дело с приоритетом, не требуется, она просто позволяет другим вещам с более высоким приоритетом выполняться в первую очередь при загрузке и является хорошей практикой, если ваше приложение не является высокоприоритетным.
Как вы увидите в связанной статье, использование этих тегов в вашем коде приведет к тому, что файл AndroidManifest.xml будет создан во время сборки, и все будет так, как должно быть. Я обнаружил, что при изменении манифеста вручную для включения тега получателя система заставляла его искать класс на один уровень слишком глубоко, вызывая исключение ClassNotFound. Он пытался создать экземпляр [Пространство имен].[Пространство имен].[BroadcastReceiver], что было неверным. И это было сделано из-за ручного редактирования манифеста.
В любом случае, надеюсь, это поможет.
Также еще один быстрый совет с помощью инструмента adb. Если вы хотите получить более легкую для чтения версию журнала, попробуйте это:
C: \ Android \ platform-tools \ adb logcat >> C: \ log.txt
Это создаст дамп логката в текстовый файл, который вы можете открыть и прочитать немного проще, чем в окне командной строки. Делает вырезать и вставлять вещи немного проще тоже.
Относится к некоторым устройствам под управлением Android Kitkat 4.4.4_r2/r1.
Кажется, в Android есть ошибка, из-за которой android.intent.action.BOOT_COMPLETED не транслируется.
Увидеть:
BOOT FAILURE, готовый к работе с менеджером пакетов
В большинстве случаев это не ответ на ваши проблемы (скорее всего, из-за разрешений и т. Д.), Но если вы работаете с Kitkat, вы можете посмотреть, подходит ли вам это.
У меня была эта проблема, и android.intent.action.BOOT_COMPLETED просто не транслировался в некоторых случаях, когда он запускался!
Другие ответы здесь уже касались того, как идеально реализовать Broadcast Receiver, чтобы он работал, однако у меня все еще были проблемы с получением намерения BOOT_COMPLETED до тех пор, пока я не понял, что приложение действительно работает при запуске из телефона / эмулятора, нажав на значок приложения. Всякий раз, когда я запускаю свое приложение с помощью команд отладки / запуска из Android Studio, намерение BOOT_COMPLETED не будет доставлено, пока приложение не будет открыто и запущено.
Я надеюсь, что это может помочь кому-то, кто, как и я, часами боролся с этой проблемой. Более того, если у кого-нибудь есть объяснение этому поведению, я был бы очень рад узнать об этом больше.
При добавлении <category android:name="android.intent.category.HOME" />
это в моем файле манифеста решить мою проблему и работает.
<receiver android:name=".BroadCastRecieverClass">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
У меня была такая же проблема. Это было решено после изменения имени получателя в манифесте на полный путь к моему классу: com.bla.bla.bla.Receiver