Utilizzare una notifica permanente per consentire all'utente di tornare al sistema operativo Android app

StackOverflow https://stackoverflow.com/questions/3568250

Domanda

Sto sviluppando un app con numerose attività. Vorrei creare una notifica persistente che (più o meno) dice: "NomeApp - Ritorna al AppName" che sarà presente ogni volta che i miei servizi in background sono in esecuzione. Creazione e lo smaltimento della notifica non era un problema.

Ora, l'utente potrebbe essere in uno dei diversi schermi / Attività, lasciare l'applicazione, poi si desidera inserire nuovamente l'applicazione tramite la notifica. Il problema è , la notifica deve avere un intento, che lancia un Attività predeterminato . Voglio la notifica di rientrare l'applicazione in qualsiasi attività è in cima della storia pila .

Il mio primo tentativo di una soluzione brutta era di fare un'attività (chiamiamolo "returnFromNotify") il cui unico compito era quello di "finire" se stesso in essa la "onCreate". La notifica avrebbe aperto "returnFromNotify" nell'ambito della storia delle applicazioni, che sarebbe poi rimuovere immediatamente stesso, inviando la schiena all'utente lo stato precedente storia nel stack applicativo. Questo sembra funzionare ... a meno che l'utente ha utilizzato "back" per eseguire completamente fuori della app. Poi, quando hanno colpito la notifica, "returnFromNotify" carichi, quindi finiture, l'invio di nuovo fuori alla schermata iniziale (come non ci sono attività in stack cronologia per l'applicazione).

ho considerato cercando di rilevare se c'era qualcosa nella pila storia prima "returnFromNotify", e se non, avviare la mia attività principale. Non riesco a trovare un modo per fare questo, sia.

Qualsiasi ingresso o suggerimenti per un novizio Java / Android? Cordiali saluti, Il mio storia principale è con linguaggi di script-based.

È stato utile?

Soluzione

Mi piace la tua idea originale di creare un'attività di "returnFromNotify" meglio che la tua soluzione proposta, in quanto è possibile rilevare se il ResumeActivity è in fondo alla pila (e quindi l'unica attività nella pila).

Ecco come si può fare:

Aggiungi il tuo ResumeActivity al manifesto e specificare il noHistory attributo:

<activity android:name=".ResumeActivity" android:noHistory="true" />

Come specificare noHistory farà in modo che questa attività non rimarrà nella pila non appena finisce. In questo modo si sa che solo un'istanza attualmente in esecuzione del ResumeActivity apparirà nella pila.

Al fine di verificare lo stack di applicazione, avrete anche bisogno di chiedere il permesso GET_TASKS:

<uses-permission android:name="android.permission.GET_TASKS" />

Ora è possibile utilizzare ActivityManager :: getRunningTasks () per determinare se ResumeActivity è l'unica attività nello stack:

public class ResumeActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(isOnlyActivityInStack()) { //check the application stack
            //This activity is the only activity in the application stack, so we need to launch the main activity
            Intent main = new Intent(this, MainActivity.class);
            main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(main);
        } else {
            //Return the user to the last activity they had open
            this.finish();
        }
    }

    /**
     * Checks the currently running tasks. If this activity is the base activity, we know it's the only activity in the stack
     *
     * @return  boolean  This activity is the only activity in the stack?
     **/
    private boolean isOnlyActivityInStack() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        boolean onlyActivityInStack = false;

        for(RunningTaskInfo tasks : manager.getRunningTasks(Integer.MAX_VALUE)) {
            if(tasks.baseActivity.getPackageName().equals(this.getPackageName())) { //find this package's application stack
                if(tasks.baseActivity.getClassName().equals(this.getClass().getName())) {
                    //If the ResumeActivity is the base activity, we know that it is the only activity in the stack
                    onlyActivityInStack = true;
                    break;
                }
            }
        }

        return onlyActivityInStack;
    }

}

Lo so che questa domanda oltre 2 anni fa, ma sto fornendo questa risposta nel caso qualcuno corre altro per questa particolare situazione (come ho fatto io). Penso che tu eri sulla strada giusta con la soluzione di cui si stava lavorando verso.

Altri suggerimenti

D'accordo, credo che ho trovato un soddisfacente work-around per il mio caso specifico . Ho aggiunto un intero statica al mio "mainActivity", e ogni volta di "onCreate" viene licenziato, incrementa il numero intero. Ogni volta che viene "OnDestroy" viene licenziato, decrementa.

Nel mio "returnFromNotify", guardo il numero intero statica per vedere se è maggiore di 0. Se è così, suppongo che ci sia un "mainActivity" attivo, e che l'uso di "finitura" dentro "returnFromNotify" Tornerò lì . In caso contrario, assume gli utenti hanno "sostenuto" fuori, si finisce, quindi utilizza "startActivity" per accendere una nuova istanza di "mainActivity".

Questa non è una soluzione universale, ma per i miei scopi, penso che sarà sufficiente. Sono ancora aperto ad altre risposte, e se qualcuno può fare un buco nella mia logica, si prega di farlo - costruttivo la critica è il benvenuto . Grazie.

Credo che non v'è alcun modo semplice per fare questo, ma invece di aggiungere un contatore nel mainActivity vorrei estendere Applicazione :

  

Classe di base per chi ha bisogno di   mantenere lo stato di applicazione globale. voi   in grado di fornire la propria implementazione per   specificandone il nome nella vostra   AndroidManifest.xml di   tag, che farà sì che classe di essere   un'istanza per voi quando il processo   per l'applicazione / pacchetto è   creato.

Vorrei rimanere fedele alla logica lì e hanno un metodo come:

public Intent getIntentForLastActivityShown();

da chiamare quando la voce di notifica viene cliccato.

Il mio primo approccio sarebbe quello di utilizzare SharedPreferences e memorizzare una coppia di valori chiave denominata qualcosa come lastDisplayedActivity. Poi, nel onResume di ogni attività (ed eventualmente `onCreate ') si avrebbe una riga come questa:

sharedPreferences.edit().putInteger("lastDisplayedActivity", ReturnFromNotify.THIS_ACTIVITY_NAME);

In altre parole, è possibile memorizzare una variabile a livello di applicazione che indica che l'attività è stato lo scorso visualizzata. Poi basta afferrare questa variabile da SharedPreferences e lanciare l'attività corrispondente.

Io di solito uso l'attività denominata "Launcher" che i controlli dello stato della mia richiesta di attività modello e inizia (o fa altre cose) a seconda delle norme tipo. Ho messo Modello oggetto nella mia classe Application. Modello può usare Preferenze per memorizzare il suo stato. Lo faccio per evitare campi statici in attività.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top