Activity / ProgressDialog: Auf Ergebniss von BroadcastReceiver reagieren

  • Antworten:7
  • Bentwortet
[res][per]
  • Forum-Beiträge: 22

02.08.2015, 15:07:35 via Website

Hallo,

ich stehe gerade auf dem Schlauch. Ich habe in meiner Activity einen Progress Dialog. Zusammen mit diesem starte ich einen Broadcast Receiver, welcher den SMS Eingang überwacht. Nun möchte ich, dass der Dialog beendet wird, sobald eine SMS von einer bestimmten Nummer kommt.

Mein Dialog:

protected void sendSMS(String sms){
        try {
            final ComponentName receiver = new ComponentName(this, IncomingSms.class);
            final PackageManager pm = this.getPackageManager();
            pm.setComponentEnabledSetting(
                receiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);

            waitSms = new ProgressDialog(this);
            waitSms.setTitle("Warte auf Bestätigungs SMS");
            waitSms.setCancelable(false);
            waitSms.setMessage("Abbrechen setzt die Einstellung in der App auf inaktiv zurück. Nicht warten übernimmt die Einstellung in der App, wartet aber nicht weiter auf eine Bestätigungs SMS.");
            waitSms.setButton(DialogInterface.BUTTON_NEGATIVE, "Abbrechen", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
                    waitSms.dismiss();
                }
            });
            waitSms.setButton(DialogInterface.BUTTON_POSITIVE, "Nicht warten", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
                    waitSms.dismiss();
                }
            });
            waitSms.show();
        }

Mein Broadcast Receiver:

public class IncomingSms extends BroadcastReceiver {

    // Get the object of SmsManager
    final SmsManager sms = SmsManager.getDefault();

    public void onReceive(Context context, Intent intent) {

        // Retrieves a map of extended data from the intent.
        final Bundle bundle = intent.getExtras();

        try {

            if (bundle != null) {

                final Object[] pdusObj = (Object[]) bundle.get("pdus");

                for (int i = 0; i < pdusObj.length; i++) {

                    SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
                    String phoneNumber = currentMessage.getDisplayOriginatingAddress();

                    String senderNum = phoneNumber;
                    String message = currentMessage.getDisplayMessageBody();

                    Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message);

                    int duration = Toast.LENGTH_LONG;
                    Toast toast = Toast.makeText(context, "senderNum: "+ senderNum + ", message: " + message, duration);
                    toast.show();

                } // end for loop
            } // bundle is null

        } catch (Exception e) {
            Log.e("SmsReceiver", "Exception smsReceiver" +e);
        }
    }
}

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

02.08.2015, 15:13:48 via Website

Und was ist jetzt das Problem :P
Ich vermute mal dass dein Dialog vorzeitig veendet wird, da du auf beiden Buttons die du zur auswahl hast den dielog mit waitSms.dismiss();beendest.
Beim "warten" darfst du das erst machen wenn du die SMS empfangen hast.
Das ist aber ein Problem, weil dann musst du die Instanz deines Dilogs mit in den Broadcast Receiver schleusen, oder zumindest zugriff darauf bekommen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
[res][per]
  • Forum-Beiträge: 22

02.08.2015, 15:17:45 via Website

Mit den Buttons ist ja richtig so, weil der Nutzer dann keine Lust mehr hat auf die SMS zu warten.

Es geht mir darum, wie ich es jetzt hin bekomme, dass wenn die SMS von einer vorgegebenen Nummer kommt, den Dialog zu beenden.

Also das was du schreibst, die Instanz des Dialogs in den Receiver "schleusen".

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

02.08.2015, 15:28:04 via Website

Für den Broadcast Receiver brauchst du ja einen Intent mit welchem dieser dann aufgerufen wird.
Dem intent kannst du dann die Instanz mitgeben, vorausgesetzt ein ProgressDialog (Klasse) ist seralizable:
http://stackoverflow.com/a/14383023

Das weiss ich jetzt aber nicht auswendig.
Zur not mit static verweisen und hoffen dass der GC das nicht löscht.

— geändert am 02.08.2015, 15:28:42

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Sven R.
  • Forum-Beiträge: 1.904

03.08.2015, 07:48:47 via App

Du könntest einfach einen anonymen Receiver in der MainActivity deklarieren:

Receiver r = new Receiver() {onReceive(...){MainActivity.this.smsReceived();}}

In der smsReceived() guckst du erstmal, ob die Activity noch läuft, zur Sicherheit. Dann kannst du den Dialog per vorher gesetztem Tag finden und dismissen.

— geändert am 03.08.2015, 07:50:54

Wenn dir mein Beitrag gefällt, kannst dich einfach mit dem 👍 "Danke"-Button auf der Website dieses Forums bedanken. 😀

Why Java? - Because I can't C#

Antworten
[res][per]
  • Forum-Beiträge: 22

03.08.2015, 11:32:09 via Website

Receiver r = new Receiver() {onReceive(...){MainActivity.this.smsReceived();}}

so ähnlich habe ich es jetzt auch gemacht, den BroadcastReceiver direkt in der Activity gesetzt und registriere ihn jetzt im Programm Code.

Antworten
Sven R.
  • Forum-Beiträge: 1.904

03.08.2015, 14:10:55 via App

Ich glaube die Lösung ist gar nicht so unelegant.

Wenn dir mein Beitrag gefällt, kannst dich einfach mit dem 👍 "Danke"-Button auf der Website dieses Forums bedanken. 😀

Why Java? - Because I can't C#

Antworten
Gelöschter Account
  • Forum-Beiträge: 438

08.08.2015, 05:38:47 via App

Oder man nimmt einfach einen Eventbus, wie z.B. Otto (http://square.github.io/otto/), mit dem man Komponenten sehr schön entkoppeln kann.
Bei Eingang der entsprechenden SMS feuert man dann ein Event über den Bus und so lange der Dialog da ist, subscribed er die Event-Klasse und wird entsprechend vom Bus informiert.

Otto mag zwar zunächst mal nur Events auf dem GUI Thread, aber das kann man auch umstellen - sollte dokumentiert sein.

Aktuelles Entwicklungsprojekt: (thinking) Sudoku Dojo Free (lightbulb)
Ich freue mich über Tester/innen.

Antworten