Dopo aver consultato specialisti in materia, programmatori di vari rami e insegnanti, abbiamo trovato la risposta al problema e la lasciamo riflessa in questo post.
Soluzione:
Ecco una soluzione testata e funzionante su entrambi i dispositivi citati, OnePlus e Mi.
Come hai detto tu, la funzione di prevenzione dell'avvio automatico su OnePlus e Mi impediscono alle app di avviare automaticamente i loro servizi all'avvio, in modo da migliorare la velocità di avvio del dispositivo e le prestazioni della batteria. Tuttavia, esiste una soluzione per far funzionare la vostra app anche quando questa funzione è attivata.
Ho notato che se si dispone di un AccessibilityService
nell'applicazione e questo viene attivato dall'utente, l'applicazione supera il filtro applicato da questi produttori e riceve l'evento di avvio completo e qualsiasi altro evento BroadcastReceiver
. BroadcastReceiver
funziona come previsto.
La possibile spiegazione di questo trucco può essere che dal momento che AccessibilityService
è un servizio a livello di sistema, quindi registrando il proprio servizio si sta passando il filtro applicato da questi produttori e non appena il vostro servizio personalizzato AccessibilityService
viene attivata dal sistema operativo, l'applicazione diventa attiva nel ricevere i dati idonei.BroadcastReceiver
che avete registrato.
Ecco come fare,
Iniziate aggiungendo questo permesso al vostro file AndroidManifest.xml
,
Ciò consentirà di registrare l'applicazione AccessibilityService
con il sistema.
Ora, aggiungiamo una configurazione di base per il nostro AccessibilityService
creando un file, ad esempio my_accessibility_service.xml
all'interno della cartella XML sotto la cartella res del progetto.
Rimane solo un altro passo da fare, definire il file personalizzato AccessibilityService
nel progetto,
public class MyAccessibilityService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) { }
@Override
public void onInterrupt() {
}
}
Si noti che, poiché non si ha bisogno dell'elemento AccessibilityService
per qualsiasi scopo che non sia questo workaround, si possono lasciare vuoti i metodi sovrascritti.
Infine, basta dichiarare il metodo AccessibilityService
nel proprio metodo AndroidManifest.xml
,
Questo è tutto. Ora, all'interno della vostra applicazione, chiedete agli utenti di attivare il servizio di accessibilità per la vostra applicazione dalle impostazioni e lasciatelo attivo e voilà! La vostra applicazione funziona bene su tutti i dispositivi, anche quelli in cui il sistema operativo impone un filtro sulle applicazioni da avviare automaticamente all'avvio.
MODIFICA 1
Ecco come verificare se il servizio di accessibilità è attivato o meno per la vostra applicazione,
private static final int ACCESSIBILITY_ENABLED = 1;
public static boolean isAccessibilitySettingsOn(Context context) {
int accessibilityEnabled = 0;
final String service = context.getPackageName() + "/" + MyAccessibilityService.class.getCanonicalName();
try {
accessibilityEnabled = Settings.Secure.getInt(
context.getApplicationContext().getContentResolver(),
android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
} catch (Settings.SettingNotFoundException e) {
Log.e("AU", "Error finding setting, default accessibility to not found: "
+ e.getMessage());
}
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
if (accessibilityEnabled == ACCESSIBILITY_ENABLED) {
String settingValue = Settings.Secure.getString(
context.getApplicationContext().getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (settingValue != null) {
mStringColonSplitter.setString(settingValue);
while (mStringColonSplitter.hasNext()) {
String accessibilityService = mStringColonSplitter.next();
if (accessibilityService.equalsIgnoreCase(service)) {
return true;
}
}
}
}
return false;
}
Spero che questo sia d'aiuto.
Ciao, arrivo tardi alla festa ma ho seguito questa domanda fin dall'inizio. So che One-plus
e alcuni altri OEM mantengono un elenco di applicazioni che possono ricevere la trasmissione BOOT_COMPLETED. Se la vostra applicazione non è presente nell'elenco, non verrà avviata all'avvio. Ora ho una soluzione che è molto efficiente in termini di memoria e risorse e garantisce l'avvio dell'attività o del servizio dopo il riavvio o l'avvio rigido. AccessibilityService
come proposto in questa risposta. Ecco come funziona...
- Aggiungere
nel vostromanifest
nel file.
2. Se non si ha una dipendenza da com.google.android.gms:play-services-gcm
aggiungere quanto segue alla sezione dipendenze di build.gradle:
compile 'com.firebase:firebase-jobdispatcher:0.5.2'
Altrimenti, aggiungere quanto segue:
compile 'com.firebase:firebase-jobdispatcher-with-gcm-dep:0.5.2'
Questa è una libreria di firebase
che dipende da google-play-service
per programmare i lavori e dal mio punto di vista google-play-service
ha il permesso di avviarsi all'avvio, quindi invece del sistema google-play-service
eseguirà il lavoro non appena il dispositivo viene riavviato.
-
Ora questo passo è facile Basta definire una classe JobService
public class MyJobService extends JobService { @Override public boolean onStartJob(JobParameters job) { Log.v("Running", "====>>>>MyJobService"); return false; // Answers the question: "Is there still work going on?" } @Override public boolean onStopJob(JobParameters job) { Log.v("Stopping", "====>>>>MyJobService"); return true; // Answers the question: "Should this job be retried?" }
}
-
Aggiungere il Job Service nel file manifest.
-
Programmare questo lavoro ovunque si voglia, per esempio all'avvio dell'applicazione.
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(getApplicationContext())); Bundle myExtrasBundle = new Bundle(); myExtrasBundle.putString("some_key", "some_value"); Job myJob = dispatcher.newJobBuilder() // the JobService that will be called .setService(MyJobService.class) // uniquely identifies the job .setTag("my-unique-tag-test") // repeat the job .setRecurring(true) // persist past a device reboot .setLifetime(Lifetime.FOREVER) // start between 0 and 60 seconds from now .setTrigger(Trigger.executionWindow(0, 60)) // don't overwrite an existing job with the same tag .setReplaceCurrent(false) // retry with exponential backoff .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL) // constraints that need to be satisfied for the job to run .setExtras(myExtrasBundle) .build(); dispatcher.mustSchedule(myJob);
6. Ecco fatto! Ora è possibile eseguire l'attività o il servizio all'avvio del dispositivo, indipendentemente dalla presenza o meno nella white list.
C'è un punto da notare: Google Play Service deve essere installato sul dispositivo, altrimenti non funzionerà.
@Aritra, prova questo
Rimuovere il filtro di intento quickBoot e provare a eseguirlo, come da documentazione è richiesto solo BootCompleted per ottenerlo. Forse lo interrompe.
Inoltre, un altro punto importante da notare:
Non affidatevi completamente o testate i dispositivi Mi, perché hanno un proprio sistema operativo che blocca le funzioni di base di Android, come l'interruzione dei servizi di notifica push e dei servizi in background solo per ottimizzare l'uso della batteria. Per testare questo su un dispositivo Mi, contrassegnare l'applicazione come "AutoStart" nell'applicazione Sicurezza e poi provare.
Se ti è piaciuto il nostro lavoro, puoi lasciare una divisione su cosa aggiungeresti a questo scritto.