41 Stimmen

Wie kann ich in Android einen Dialog ohne Aktivitätskontext anzeigen?

Das sollte eigentlich ganz einfach sein, aber ich finde nirgendwo eine Antwort. Ich habe eine Android-Anwendung, die Netzwerkaufgaben im Hintergrund ausführt. Wenn ein Fehler zurückkommt, möchte ich einen Fehlerdialog anzeigen. Wenn die Aufgabe zurückkehrt, weiß ich nicht, welche Aktivität im Vordergrund ist. Basierend auf diese Stelle Es sieht so aus, als ob wir den Anwendungskontext nicht verwenden können, um ein Dialogfeld anzuzeigen (und in der Tat bekomme ich den Absturz, wenn ich es versuche).

Wie kann ich also den Kontext der aktuellen Aktivität ermitteln? Auch hier gilt, dass der Empfänger für die Netzwerkaufgabe im Anwendungskontext läuft, nicht in einer bestimmten Aktivität. Irgendwelche anderen Ideen?

Edit: Ich sollte das klarstellen. Ich möchte keinen Fehlerdialog anzeigen, wenn ich nicht die Vordergrundanwendung bin. Ich interessiere mich nur für den Fall, wo unsere App im Vordergrund ist für jetzt.

1voto

Derorrist Punkte 2484

Hier ist eine Implementierung, die es ermöglicht, einen AlertDialog über der aktuell aktiven Aktivität anzuzeigen (dies ist ein Beispiel für einen Nachrichtendialog, kann aber auch für Alerts verwendet werden).

public class AlertsDialogue
{
    private AlertDialog.Builder alertDialogBuilder;
    private AlertDialog alert;

    public AlertsDialogue(Context context, String title, String message)
    {
        alertDialogBuilder = new AlertDialog.Builder(context);
        alertDialogBuilder.setTitle(title);
        alertDialogBuilder.setIcon(R.drawable.ic_launcher);
        alertDialogBuilder.setMessage(message)
            .setCancelable(false)
            .setPositiveButton(context.getString(R.string.text_ok), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    alert.dismiss();
                }
            });

        alert = alertDialogBuilder.create();
        Window window = alert.getWindow();
        if (window != null)
        {
            // the important stuff..
            window.setType(WindowManager.LayoutParams.TYPE_TOAST);
            alert.show();
        }
        else
            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
    }
}

Der Dialog wird auch dann angezeigt, wenn der Kontext, in dem er instanziiert wurde, nicht mehr aktiv ist, ähnlich wie Toast .

Anruf mit new AlertsDialogue(MyActivity.this, "title", "message");

In der AndroidManifest-Datei sind keine zusätzlichen Berechtigungen erforderlich.

0voto

px3j Punkte 236

Welche Art von Netzwerkaufgaben laufen im Hintergrund ab? Ich würde vorschlagen, das Design möglicherweise zu überdenken. Vielleicht wäre eine Benachrichtigung besser? Oder vielleicht ein Bildschirm mit einer "Ergebnisübersicht". Als Benutzer würde ich ein nicht aufdringliches Fehlersignal bevorzugen, wenn ich nicht aktiv auf den Abschluss der Aufgabe warte.

0voto

Victor Choy Punkte 3670

Auch ich stehe vor diesem Problem. Ich habe eine einfache und effektive Lösung gefunden. In der Regel haben wir eine Basisaktivität, die für die Verarbeitung einer allgemeinen Logik verwendet wird. So haben diese:

public class BaseActionBarActivity extends ActionBarActivity{  //this BaseActionBarActivity is the Base Act

   private static BaseActionBarActivity current;

   @Override
   protected void onStart() {
     super.onStart();
     current=this;
   }

   public static BaseActionBarActivity getCurrentContext() {
     return current;
   }
}

current ist die aktuelle Context Actitvity. Und ich glaube nicht, dass es ein Speicherleck gibt. Es funktioniert gut für mich! Hoffentlich hilfreich

0voto

hopetribe Punkte 91

Müssen Sie den Typ des Fensters, an das der Dialog angehängt ist, wie folgt zurücksetzen: dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

Vergessen Sie nicht, die Berechtigung "Android.permission.SYSTEM_ALERT_WINDOW" in Ihrem Manifest zu deklarieren.

0voto

Janusz Hain Punkte 497

Am besten ist es, Dialoge und andere ansichtsbezogene Arbeiten in Activity / Fragment zu zeigen, nicht in einer anderen Klasse, die keine Ahnung hat, was Kontext ist.

Aber es gibt einige triftige Gründe, die dafür sprechen, dies außerhalb von Views zu tun. Zum Beispiel möchte ich einen Warndialog anzeigen, um das Testen der App im Mock-Build zu erleichtern. Um Aktivitätskontext bereitzustellen, können Sie mehrere Dinge tun, ich werde über zwei schreiben:

  1. Aktivitätskontext mit einem an die Aktivität gebundenen Bereich injizieren. Dies ist die beste Lösung, erfordert aber eine korrekt implementierte Architektur, bei der der Geltungsbereich berücksichtigt wird. Ich werde nicht beschreiben, wie man es hier zu tun, kann es in Tutorials gefunden werden.

  2. Ich habe eine Hilfsklasse mit der Erweiterung der Aktivität erstellt, um Kontext von der Aktivität zu erhalten. Es speichert nicht Kontext, aber Funktion, die Kontext bereitstellen kann, so dass ich denke, es sollte nicht dazu führen, dass Speicherlecks (? nicht getestet, es ist für Mocked-Builds für Tester, so nicht verbringen viel Zeit überprüfen, dass)

    object ActivityContextProviderForMockBuilds {
    
        private val contextProvider = MutableSharedFlow<(Context) -> Unit>(extraBufferCapacity = 1)
    
        fun getContext(contextCallback: (Context) -> Unit) = contextProvider.tryEmit(contextCallback)
    
        fun AppCompatActivity.setContextProviderForMockBuild() {
            if (BuildConfig.MOCKS_ENABLED) {
                contextProvider.onEach {
                    it.invoke(this)
                }.launchIn(lifecycleScope)
            }
        }
    }

Verwendung:

ActivityContextProviderForMockBuilds.getContext { context -> ... }

Aber wie bereits gesagt, sollten Sie nicht Aktivität Kontext außerhalb von Ansichten in den meisten Fällen und wenn ja, dann durch Abhängigkeit Injektion verwenden :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X