2015-10-07 5 views
7

Vorrei usare il permesso per Android 6 nella mia app ma ho visto uno strano evento. Forse puoi aiutarmi a questo.Android 6 Autorizzazioni => Blocco quando si disabilita l'autorizzazione e si ritorna all'app

Se si avvia l'app con autorizzazioni "Pericolose", queste autorizzazioni vengono visualizzate nelle "Autorizzazioni app" del proprio dispositivo Android. PERFEZIONARE!

MA se si mantiene l'app in background, andare al menu "Autorizzazioni app", disabilitare (è possibile abilitare e quindi disabilitare) un'autorizzazione e tornare alla propria app, Android non andare mai su onStart (Frammento o attività)?! E non tornarci mai più.

Se non si tocca l'autorizzazione o se si abilita un'autorizzazione => passa a onStart e ad altri.

Questo è problematico, per exemple, se la vostra applicazione usa gli ascoltatori, non è possibile riavviarlo e si può avere un incidente ...

Non si conosce il metodo in cui Android andare quando si disattiva un permesso?

ho cercato onCreate onStart onResume onRestart onRestoreInstanceState onActionModeStarted onRestoreInstanceState onPostResume onContentChanged

... ma c'è modo ...:/

+2

"Android mai andare a onStart (frammento o attività)?! E non tornare mai più. "- Android termina il tuo processo se l'utente revoca un'autorizzazione dalle Impostazioni. Lo gestisci allo stesso modo se Android interrompe il tuo processo per qualsiasi altro motivo mentre sei in background. – CommonsWare

+0

Grazie per la tua risposta! Continuo l'investigazione Quando creo la mia attività, mostro 1 frammento.Se cambio il permesso e torno indietro, ci sono 2 frammenti (il frammento prima del cambio permesso e dopo). Hai qualche idea del perché il vecchio il frammento è mantenuto? –

+0

"Hai idea del motivo per cui il vecchio frammento è conservato?" - perché il tuo compito è ancora eccezionale, e così Android sta ricreando l'attività e ripristinando il suo stato nel miglior modo possibile, che include creazione di eventuali frammenti esistenti Otterrete gli stessi risultati se venite modificati in una configurazione (ad esempio, ruotate lo schermo), poiché l'attività verrà distrutta e ricreata per impostazione predefinita. Controllare se il frammento esiste prima di aggiungere ng – CommonsWare

risposta

4

Ecco la mia soluzione:

Io uso alcuni frammenti nel mio mainActi VITY.

Come sapete, l'attività viene ricreato quando l'utente disattiva un permesso => ​​passare attraverso onCreate, ...

quello che faccio nel onCreate (...) della mia mainActivity, rimuovo tutti i frammenti caricati e metto la mia app nello stesso stato della prima esecuzione.

Ti piace questa:

// Clean fragments (only if the app is recreated (When user disable permission)) 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    if (fragmentManager.getBackStackEntryCount() > 0) { 
     fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
    } 

    // Remove previous fragments (case of the app was restarted after changed permission on android 6 and higher) 
    List<Fragment> fragmentList = fragmentManager.getFragments(); 
    if (fragmentList != null) { 
     for (Fragment fragment : fragmentList) { 
      if (fragment != null) { 
       fragmentManager.beginTransaction().remove(fragment).commit(); 
      } 
     } 
    } 

Fate attenzione !!! : Ho avuto un arresto anomalo con la versione 23.2.0 delle librerie app e di progettazione. Questo arresto si verifica quando viene ricreata l'app!

Controllare questo link per ulteriori informazioni.

+1

quando sappiamo che l'attività è stata ricreata? Getting Crash "Il frammento non esiste più". – Santosh

1

Come già sottolineato, Android sta rilanciando la tua app. Questo è lo stesso comportamento di quando la tua app è in background e il sistema uccide l'applicazione man mano che viene utilizzata più memoria. Cosa succede quando torni alla tua applicazione è che l'ultima attività inclusiv frammenti (s) viene ricreata.

In genere viene utilizzata una schermata di avvio (schermata iniziale) per inizializzare l'applicazione. Dopo l'inizializzazione dell'applicazione (ad esempio i servizi, viewmodel è pronto) l'attività di avvio viene trasferita all'attività principale.

Un arresto anomalo comune si verifica in molte applicazioni quando l'app viene ricreata (ad esempio revoca autorizzazioni) poiché l'app non viene inizializzata e vengono utilizzati i servizi oi viewmodels che sono nulli. Non penso che ci sia un modo per evitare di ricreare l'ultima attività dopo il riavvio dell'app.

Che cosa si potrebbe fare è controllare se l'applicazione è inizializzata e in caso contrario passare all'attività di avvio e inizializzare l'app. Tieni presente che devi gestire le applicazioni unitializzate nell'attività e anche i frammenti.

Xamarin codice esempio:

if (!((MyApplication)ApplicationContext).IsInitialized) 
{ 
    Intent intent = new Intent(Application.Context,typeof(StartupActivity)); 
    intent.SetFlags(ActivityFlags.NewTask); 
    StartActivity(intent); 
    Finish(); 
} 

Appena base.onCreate viene chiamato i frammenti vengono create quindi anche la condizione "soluzione" da ACS-squadra non evita la ricreazione dell'ultimo frammento.

Con il codice di esempio fornito sopra il ciclo di vita sarà in caso l'attività ha avuto un frammento:

  • revocare il permesso di app viene ucciso
  • Riavvia applicazione
  • Applicazione OnCreate
  • LastActivity.OnCreate
  • LastFragment.OnAttach
  • LastFragment.OnCreate
  • LastFragment.OnCreateView
  • LastFragment.OnViewCreated
  • LastFragment.OnDestroy
  • LastFragment.OnDettach
  • LastActivity.OnDestroy
  • StartupActivity.OnCreate

Tra l'altro è possibile anche testare un app ricomincia la shell adb:

Apri la tua app quindi vai a e schermata iniziale roid in modo che la vostra applicazione è in background

adb shell "ps | grep <com.yourpackage>" // get the app process id 
adb shell run-as <com.yourpackage> kill <app-process-id> // kill the app 

avviare la vostra applicazione di nuovo sopra l'icona o le attività recenti

Problemi correlati