Verwenden Sie eine persistente Benachrichtigung der Benutzer zu ermöglichen, läuft Android App zurückzukehren

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

Frage

Ich bin eine App mit zahlreichen Aktivitäten zu entwickeln. Ich möchte eine dauerhafte Benachrichtigung erstellen, dass (mehr oder weniger) sagt: „AppName - Return to AppName“, das vorhanden sein wird, wenn meine Dienste im Hintergrund ausgeführt werden. Erstellen und Entsorgen der Meldung kein Problem war.

Nun kann der Benutzer auf eine beliebige von mehreren Bildschirmen / Aktivitäten, lassen Sie die Anwendung, wollen dann die App über die Benachrichtigung erneut eingeben. Das Problem ist, , die Anmeldung muss eine Absicht hat, die Kutter eine vorbestimmte Aktivität . Ich möchte, dass die Benachrichtigung wieder in den App in , was Aktivität ist an der Spitze der Geschichte Stapel .

Mein erster Versuch, eine hässliche Abhilfe war, um eine Aktivität zu machen (nennen wir es „returnFromNotify“), deren einzige Aufgabe war es, „finish“ sich in seiner „onCreate“. Die Benachrichtigung öffnen würde „returnFromNotify“ in dem Rahmen der Geschichte von Anwendungen, die sich dann sofort entfernen würden, den Benutzer zurück zum vorherigen Vergangenheitszustand in dem Anwendungsstapel sendet. Dies scheint zu funktionieren ... es sei denn, der Benutzer „zurück“ vollständig wieder aus dem App benutzt hat. Dann, wenn sie die Meldung getroffen „returnFromNotify“ lädt, dann endet, so dass sie in den Hauptbildschirm wieder heraus zu senden (da es keine Aktivitäten in der Geschichte Stapel für die App sind).

Ich hielt zu erkennen versuchen, ob es etwas Stapel in der Geschichte war, bevor „returnFromNotify“, und wenn nicht, feuern meine Hauptaktivität auf. Ich kann nicht scheinen, einen Weg zu finden, dies zu tun, auch nicht.

Jede Eingabe oder Vorschläge für einen Java / Android Anfänger? FYI, Meine primäre Geschichte ist mit skriptbasierten Sprachen.

War es hilfreich?

Lösung

Ich mag Ihre ursprüngliche Idee, eine „returnFromNotify“ Aktivität besser als Ihre vorgeschlagene Abhilfe zu schaffen, wie es ist möglich zu erkennen, ob die ResumeActivity an der Unterseite des Stapels (und damit die einzige Aktivität in dem Stapel).

Hier ist, wie Sie es tun können:

Fügen Sie Ihre ResumeActivity zu den manifesten und geben Sie das Nohistory Attribut:

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

Die Angabe Nohistory wird sicherstellen, dass diese Aktivität wird in dem Stapel nicht bleiben, sobald es fertig ist. Auf diese Weise wissen Sie, dass nur eine aktuell laufende Instanz des ResumeActivity im Stapel angezeigt wird.

Um die Anwendung Stapel zu überprüfen, werden Sie auch für die GET_TASKS Erlaubnis fragen müssen:

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

Jetzt können Sie Activitymanager :: getRunningTasks () verwenden festzustellen, ob ResumeActivity die einzige Aktivität im Stapel:

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;
    }

}

Ich weiß, dass Sie diese Frage mehr als 2 Jahren gefragt vor, aber ich bin der Bereitstellung dieser Antwort, falls jemand anderes läuft in dieser besonderen Situation (wie ich). Ich glaube, Sie auf dem richtigen Weg mit der Lösung waren ursprünglich arbeiteten auf.

Andere Tipps

Okay, ich glaube, dass ich eine befriedigende Work-around gefunden habe, für meinen speziellen Fall . Ich habe eine statische integer zu meinem „mainActivity“ hinzugefügt, und jedes Mal, es ist „onCreate“ abgefeuert wird, erhöht er die ganze Zahl. Jedes Mal ist es „onDestroy“ abgefeuert wird, dekrementiert.

In meinem „returnFromNotify“, schaue ich auf der statischen integer zu sehen, ob es größer als 0 ist Wenn ja, ich nehme an, es ist ein aktiver „mainActivity“, und die „Finish“ innen „returnFromNotify“ laufen werde dorthin zurückkehren . Andernfalls nimmt der Benutzer hat „gesichert“ aus, beendet sich dann verwendet „startActivity“, um eine neue Instanz von „mainActivity“ anwerfen.

Dies ist keine universelle Lösung, aber für meine Zwecke, ich glaube, es genügt. Ich bin immer noch offen für andere Antworten, und wenn jemand ein Loch in meiner Logik lochen kann, tun Sie dies bitte - konstruktiv Kritik ist willkommen . Danke.

Ich denke, es keine einfache Möglichkeit, dies zu tun, sondern einen Zähler in der mainActivity der Zugabe würde ich verlängern Anwendung :

  

Basisklasse für diejenigen, die müssen   globalen Anwendungszustand aufrechtzuerhalten. Du   Ihre eigene Implementierung zur Verfügung stellen von   Angabe seines Namens in Ihrem   AndroidManifest.xml des   Tag, der diese Klasse wird dazu führen, dass   wenn der Prozess für Sie instanziiert   für Ihre Anwendung / Paket   erstellt.

Ich würde die Umgebung zu der Logik dort und habe eine Methode wie:

public Intent getIntentForLastActivityShown();

aufgerufen werden, wenn die Meldungsposition geklickt wird.

Mein erster Ansatz wäre SharedPreferences zu verwenden und speichern eine Schlüsselwertpaar etwas wie lastDisplayedActivity genannt. Dann in jeder onResume Aktivitäten (und möglicherweise `onCreate ') Sie würde eine Zeile wie diese haben:

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

Mit anderen Worten, speichern Sie eine Anwendung weite Variable, die angibt, welche Aktivität wurde zuletzt angezeigt. Dann greifen Sie gerade diese Variable von SharedPreferences und starten Sie die entsprechende Aktivität.

Normalerweise verwende ich Aktivität namens „Launcher“, dass die Kontrollen Zustand meiner Anwendung Modell und starten Aktivitäten (oder tun andere Dinge), je nach Modell Regeln. Ich habe Modell Objekt in meiner Anwendungsklasse. Modell können Einstellungen seinen Zustand zu speichern. Ich mache es statische Felder in Aktivitäten zu vermeiden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top