Я уже проверил все связанные вопросы и не нашел решения для этой проблемы. Так что это абсолютно новая проблема для меня.
Что у меня
У меня есть приложение для Android, которое регистрирует несколько широковещательных приемников в своем манифесте. Вот как выглядит мой манифест.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.app.myapp">
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-feature
android:name="android.hardware.screen.portrait"
android:required="false" />
<application
android:name=".base.MyApp"
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="@string/label_app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:replace="label, allowBackup">
<receiver android:name=".mics.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<receiver android:name=".PhoneCallReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<receiver
android:name=".mics.DeviceAdminReceiver"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin" />
</receiver>
<receiver
android:name="com.clevertap.android.sdk.InstallReferrerBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<meta-data
android:name="com.app.myapp.utils.ImageLoaderModule"
android:value="GlideModule" />
<meta-data
android:name="com.app.myapp.utils.AudioCoverLoaderModule"
android:value="GlideModule" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<activity
android:name=".core.activities.SplashActivity"
android:excludeFromRecents="true"
android:label="@string/label_app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity-alias
android:name=".core.activities.SplashActivity-Alias"
android:icon="@drawable/ic_launcher"
android:label="@string/label_app_name"
android:noHistory="true"
android:targetActivity="com.app.myapp.core.activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY" />
</intent-filter>
</activity-alias>
<activity
android:name=".core.flow.authFlow.activities.AuthFlowActivity"
android:excludeFromRecents="true"
android:label="@string/label_app_name"
android:screenOrientation="portrait" />
<service android:name=".features.fileCloudSync.KillNotificationService" />
</application>
</manifest>
Есть еще 10-15 других видов деятельности, но они были удалены для простоты. И это основной класс приемника загрузки. Я начинаю сервис отсюда.
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
AlertUtils.showToast(context, "BOOT COMPLETED", Toast.LENGTH_LONG);
}
}
}
и класс приемника телефонных вызовов выглядит примерно так (это было упрощено),
public class PhoneCallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
AlertUtils.showToast(context, "PHONE CALL RECEIVED", Toast.LENGTH_LONG);
// Simplified for brevity
}
}
}
Проблема
Все эти приемники работают нормально, когда я устанавливаю приложение и запускаю его один раз. Но после перезагрузки устройства эти приемники вообще не работают. Ни BootCompleteReceiver
, ни PhoneCallReceiver
не получают свой метод onReceive()
.
Мое предположение заключалось в том, что эти приемники автоматически регистрируются после перезагрузки, но это просто не работает. Мне нужно, чтобы BootCompleteReceiver
работал, чтобы я мог начать важную службу в своем приложении.
Мои наблюдения
Я проверил это полностью. После перезагрузки устройства приемники отлично работают в моих Nexus 5X (нуга), Nexus 6P (нуга), YU Yuphoria (Lollipop), но не в моих OnePlus 3 (нуга) и Mi 4i (леденец).
Как тот же код отлично работает на нескольких устройствах и вообще не работает на других устройствах? Я ничего не изменил.
Что я здесь делаю неправильно? Мое приложение сильно зависит от этих трансляций и запускает службы на их основе. Любая помощь будет высоко оценена.
РЕДАКТИРОВАТЬ 1
Чтобы лучше понять проблему, я создал очень маленький тестовый проект с одним действием и точными тем же BootCompleteReceiver
и PhoneCallReceiver
.
Но странно, этот проект отлично работает на моем OnePlus 3, где мои фактические приемники приложений не работают после перезагрузки. Сначала я предполагал, что проблема в ОС или устройстве каким-то образом, но это не так.
Итак, где же проблема? Это в моем приложении (но отлично работает на других устройствах) или в ОС и устройстве (небольшой тестовый проект отлично работает на той же ОС и на том же устройстве)?
Это действительно сбивает меня с толку. Мне нужна была бы какая-то экспертная помощь.
РЕДАКТИРОВАТЬ 2
Я попробовал предложение @shadygoneinsane. Вот мои наблюдения.
1) Я попытался отправить широковещательную передачу BOOT_COMPLETED через ADB.
./adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.app.myapp
И я получил трассировку стека,
Broadcasting: Intent { act=android.intent.action.BOOT_COMPLETED pkg=com.app.myapp }
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.BOOT_COMPLETED from pid=25378, uid=2000
at android.os.Parcel.readException(Parcel.java:1683)
at android.os.Parcel.readException(Parcel.java:1636)
at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:3696)
at com.android.commands.am.Am.sendBroadcast(Am.java:778)
at com.android.commands.am.Am.onRun(Am.java:404)
at com.android.internal.os.BaseCommand.run(BaseCommand.java:51)
at com.android.commands.am.Am.main(Am.java:121)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:276)
Возможно, потому что мое устройство не внедрено. Я не могу отправить эту трансляцию любым способом.
2) Я попытался с трансляцией PROCESS_OUTGOING_CALLS после этого.
./adb shell am broadcast -a android.intent.action.PROCESS_OUTGOING_CALLS -p com.app.myapp
Я получил это,
Broadcasting: Intent { act=android.intent.action.PROCESS_OUTGOING_CALLS pkg=com.app.myapp }
Broadcast completed: result=0
Кажется, что трансляция прошла успешно, но я не вижу ни одного тоста или какого-либо журнала. Затем я открыл свой номер, чтобы набрать номер, и затем я увижу Toast и журнал.
Таким образом, кажется, что передача широковещательной передачи через ADB не работала, но фактически открывал дозвонщик и набирал номер.
РЕДАКТИРОВАТЬ 3
В соответствии с предложением @ChaitanyaAtkuri, я также попытался добавить приоритет к фильтрам намерений, но это тоже не сработало.
Я использовал приоритеты, такие как 500, 999 и даже самое высокое целочисленное значение, но ничего не работает. Эта проблема также возникает и в некоторых приложениях моих друзей. Они работают на некоторых устройствах и не работают в других.
EDIT 4
У меня наконец выяснилась основная причина проблемы, которая возникает в моем OnePlus 3. Недавно My OnePlus 3 был обновлен до Nougat, и они представили функцию, похожую на устройства Mi, которые предотвращают автоматическое запуск некоторых приложений после перезагрузки.
После отключения этой функции мое приложение начало получать трансляции после перезагрузки. Но это все еще не объясняет две вещи.
1) Мой небольшой тестовый проект автоматически добавляется в список приложений AutoLaunch автоматически, поэтому он работает так, как ожидалось. Но как это возможно? Почему ОС считает это маленькое приложение достойным для автозапуска?
2) Есть такие приложения, как LockDown Pro, 500 Firepaper, которые занесены в черный список на экране приложений AutoLaunch, но все же он получает трансляции после перезагрузки в моих OnePlus 3 и Mi 4i. Как это возможно сейчас? Можно ли программно разрешить моему приложению автоматически запускать на этих устройствах (OnePlus и Mi)?
РЕДАКТИРОВАТЬ 5
Я пробовал решение, предложенное @Rahul Chowdhury, и это действительно работает очень хорошо. После добавления службы доступности проблема решается.
Но если пользователь аннулирует разрешение доступности после его предоставления, то есть ли у меня способ программно проверить, доступно ли разрешение доступности для моего приложения?