База знань
Автозапуск програми під час завантаження
Тема отримання повідомлення ACTION_BOOT_COMPLETED залишається актуальною і до цього дня. Багато новачків стикаються з проблемою: вони не отримують у своїх додатках даного повідомлення.
Можна виділити наступні правила:
У маніфесті вказати дозвіл:
<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED” />
У маніфесті в блоці application зареєструвати приймач на прийом повідомлення ACTION_BOOT_COMPLETED:
<receiver android:name=”.MyBroadcastReceiver”>
<intent-filter>
<action android:name=”android.intent.action.BOOT_COMPLETED” />
</intent-filter>
</receiver>
В описі без необхідності не вказуйте атрибути «enabled», «exported» і т.д. Цілком достатньо налаштувань і атрибутів за замовчуванням.
Код вашого широкомовного приймача:
public class BootCompletedReceiver extends BroadcastReceiver {
public BootCompletedReceiver() {
}
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
// ваш код тут
}
}
}
Якщо ваш приймач використовується тільки для повідомлення ACTION_BOOT_COMPLETED, то перевірка «if» не обов’язкова. Однак іноді розробники використовують один і той же ресивер для різних повідомлень. В цьому випадку фільтруйте повідомлення, перевіряючи їх усередині методу onReceive().
Додаток повинен бути встановлений на внутрішню пам’ять. Android влаштовано таким чином, що повідомлення ACTION_BOOT_COMPLETED відправляється додаткам перед монтуванням зовнішній пам’яті. Тому додатки, встановлені на зовнішній пам’яті, ніколи не отримають це повідомлення. Щоб вказати системі не встановлювати додаток на зовнішню пам’ять, у маніфесті НЕ потрібно прописувати для атрибута «@android: installLocation» значення «auto» або «preferExternal». За замовчуванням, тобто якщо цей атрибут не вказаний, Android встановить вашу програму тільки на внутрішню пам’ять. Однак згідно з офіційною документацією краще явно вказати значення «internalOnly», щоб у вас та інших розробників не виникло спокуси в майбутньому вказати інше значення.
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
android:installLocation=”internalOnly”
… >
Після встановлення або примусової зупинки (force stop) програма повинна бути запущена хоча б один раз, щоб система «запам’ятала» цей додаток для відправки йому повідомлення ACTION_BOOT_COMPLETED. Таку поведінку було реалізовано у версії Android 3.1 з міркувань безпеки. В чому суть? Усі нещодавно встановлені програми знаходяться в стані «stopped» (не плутати з активіті, тому що система по-різному керує цим станом у додатках і активностях). У цей же стан додаток «переходить», коли користувач у налаштовуваннях телефону примусово його зупиняє. Поки додаток знаходиться в такому стані, він не буде запускатися системою з жодної причини (наприклад, через ACTION_BOOT_COMPLETED), виключаючи, звичайно ж, запуск самим користувачем. Завдяки такому нововведенню чимала частина вірусів і троянців» перестала працювати, тому що вже неможливо запуститися автоматично після встановлення.
Виняток становлять системні додатки.
Особливості режиму Fast boot в HTC-пристроях: Відомо, що HTC-пристрої не перезавантажуються у класичному розумінні, а використовують так званий режим Fast boot (це одна з форм глибокого сну), зберігаючи стан ОС на диск. Тому повідомлення ACTION_BOOT_COMPLETED не надсилається системою, оскільки насправді перезавантаження не відбувається. Замість ACTION_BOOT_COMPLETED система може відправити наступні повідомлення:
<action android:name=”android.intent.action.QUICKBOOT_POWERON” />
<action android:name=”com.htc.intent.action.QUICKBOOT_POWERON” />
У вашому додатку вкажіть у тезі «receiver» крім ACTION_BOOT_COMPLETED також вказані вище повідомлення. Крім цього необхідно прописати додатковий дозвіл:
<uses-permission android:name=”android.permission.QUICKBOOT_POWERON” />
Розберемо помилки, які роблять новачки під час налаштування програми й у коді.
Toast toast = Toast.makeText(context.getApplicationContext(),
context.getResources().getString(R.string.your_message), Toast.LENGTH_LONG);
toast.show();
<receiver
android:name=”.BootCompletedReceiver”
android:enabled=”true”
android:exported=”true” >
<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED” />
<intent-filter>
<action android:name=”android.intent.action.BOOT_COMPLETED” />
</intent-filter>
</receiver>
У терміналі виконайте:
adb shell
Далі, щоб відправити ACTION_BOOT_COMPLETED всіх програм, наберіть у терміналі:
am broadcast -a android.intent.action.BOOT_COMPLETED
Або для відправки ACTION_BOOT_COMPLETED певної програми наберіть у терміналі:
am broadcast -a android.intent.action.BOOT_COMPLETED your.package.name
В емуляторі: встановіть ваше ПЗ, запустивши його зі студії. При цьому студія збере ваш проєкт, встановить додаток і запустить його. Після цього закрийте емулятор (це аналогічно вимкненню на реальному пристрої). Щоб отримати повідомлення ACTION_BOOT_COMPLETED, запустіть емулятор з AVD-менеджера, а не за допомогою кнопки «Run app» у студії.
Після запуску емулятора на вкладці Android Monitor вкажіть запущений емулятор і ваш додаток, щоб переглянути логи logcat.
Щоб ваш додаток запускався під час завантаження на всіх пристроях, маніфест як мінімум повинен виглядати наступним чином:
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
android:installLocation=”internalOnly”
package=”com.site.yourapp” >
<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED” />
<uses-permission android:name=”android.permission.QUICKBOOT_POWERON” />
<application>
<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>
<receiver
android:name=”.BootCompletedReceiver” >
<intent-filter>
<action android:name=”android.intent.action.BOOT_COMPLETED” />
<action android:name=”android.intent.action.QUICKBOOT_POWERON” />
<action android:name=”com.htc.intent.action.QUICKBOOT_POWERON” />
</intent-filter>
</receiver>
</application>
</manifest>
Код ресивера, як правило, буде таким:
public class BootCompletedReceiver extends BroadcastReceiver {
public BootCompletedReceiver() {
}
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Toast toast = Toast.makeText(context.getApplicationContext(),
context.getResources().getString(R.string.your_message), Toast.LENGTH_LONG);
toast.show();
Log.d(“myapp”, context.getResources().getString(R.string.your_message);
// ваш код тут
}
}
}
Зв'язатися з нами
Адреса: г. Київ, 03058, а/с 24
E-mail: info@qalight.com.ua