1. Nimm jetzt an unserem 2. ADVENT-Gewinnspiel teil - Alle Informationen findest Du hier!

BroadcastReceiver Lifetime - Newbiefrge

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von KurrKurr, 02.09.2010.

  1. KurrKurr, 02.09.2010 #1
    KurrKurr

    KurrKurr Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    143
    Erhaltene Danke:
    24
    Registriert seit:
    16.01.2010
    Phone:
    Motorola Milestone
    Hallo Leute,

    Ich hab mich erst vor kurzem begonnen, mich mit Android auseinanderzusetzen. Bitte steinigt mich nicht gleich. Ich hab auch schon die Suche beansprucht, dabei ist aber nichts herausgekommen.

    Folgendes Szenario:

    Ich schreibe grade ein Plug-In für Locale, welches hört, ob sich der Verindungsstatus irgendwie ändert (home, roaming, etc.). Ich hab schon einige Zeit gebraucht, bis ich überrissen habe, wie genau die Locale-Anbindung funktioniert.

    Ich stehe jetzt vor folgendem Problem: Ich habe einen Receiver per XML deklaration registriert, der auf "ConnectivityManager.CONNECTIVITY_ACTION", also auf gebroadcastete "android.net.conn.CONNECTIVITY_CHANGE"-Intents reagiert.

    Es funktioniert zwar alles, aber eben nur EIN EINZIGES MAL. Ich bin mittlerweile draufgekommen, dass nach dem aufruf der onReceive()-Methode die Lebenszeit des Receivers um ist.

    Gibt es jetzt eine Möglichkeit, diesen Receiver wieder zu registrieren, nachdem er das Intent empfangen hat und nach onReceive() aufgehört hat zu existieren?

    Ein Service wäre zwar eine Möglichkeit, aber dieser würde dann, womöglich für eine sehr lange Zeit ungenutzt im Speicher herumgammenln und nur Ressourcen vergeuden. Deshalb habe ich mir überlegt, ob ich nicht den Receiver noch einmal starten kann.

    Ginge das über den umweg über eine Activity, die natürlich nicht sichtbar sein soll?

    Ich stehe hier etwas an. Vielleicht könnte mir jemand einen Hinweis in die Richtige Richtung geben. Ein Link oder so würde schon reichen; Den Rest recherchiere ich dann schon.

    Grüße,
    Chris

    [Edit]
    P.S.: Könnte vl. ein Moderator den Rechtschreibfehler im Titel ausbessern? Es sollte Newbiefrage und nicht Newbiefrge heißen... (kann ich das denn nicht selbst?)
     
  2. FelixL, 02.09.2010 #2
    FelixL

    FelixL Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Der Receiver sollte eigentlich jedes mal neu feuern...was danach passiert kommt drauf an was der Entwickler vor hat. Allzu aufwendige Sachen sollte man nicht machen, weil der Receiver dann zu lange braucht um abgearbeitet zu werden. In diesem Fall empfiehlt sich dann ein Service. Außerdem kann man von einem Receiver aus sowieso nicht alle Aktionen ausführen die man vielleicht braucht.

    Und wegen dem Titel: Nein, kann man leider nicht selbst ändern, und ich kann die Rechtschreibfehler in meinen Titeln auch nicht sehen ohne mich ständig zu ärgern :D

    Poste doch mal bitte deinen ganzen Code, wenn es nicht zu viel oder zu geheim ist :p
     
  3. the_alien, 02.09.2010 #3
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Naja, der Receiver sollte jedesmal aufgerufen werden wenn der Broadcast kommt. Neu registrieren brauchst du ihn nicht, da er in der XML deklariert ist. Dann hängt er immer dran.

    Wahrscheinlich wird dein Receiver auch aufgerufen und du machst beim 2. Mal etwas anders als beim ersten Mal. Aller Wahrscheinlichkeit nach hast du irgendwelche Objektvariablen, in denen nun schon was drin steht und die du abfragst.

    Schließe mich FelixL an. Poste mal den Code, auch wenn er zu geheim ist ;)
     
  4. KurrKurr, 02.09.2010 #4
    KurrKurr

    KurrKurr Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    143
    Erhaltene Danke:
    24
    Registriert seit:
    16.01.2010
    Phone:
    Motorola Milestone
    Also laut android-API sieht die Sache so aus:

    Mein Code ist ganz am Ende des Posts zu finden. So geheim ist der ja nicht.

    Zuerst ein paar Erklärungen:
    Wundert euch nicht über die Comments. Ich hab mir nämlich das von Locale zur verfügung gestellte Beispiel einer Display-Condition (Display an/aus) genommen und das ganze geändert.

    Kurze Erläuterung: Die Condition selbst funktioniert sehr gut (das ist auch ein BroadcastReceiver, der von Locale ein Intent empfängt), und auch das Bearbeiten (die Edit-Action) der zu prüfenden Bedingung, die entscheidet, ob meine Locale-Condition zutrifft, oder nicht funktioniert soweit.

    Wenn ich die Variable REQUEST_REQUERY, deren Wert ein Intent "com.twofortyfouram.Intent.ACTION_REQUEST_QUERY" ist Broadcaste, dann weise ich Locale an, meine Condition wieder mal zu checken.

    Die Klasse selbst reagiert auf "android.net.conn.CONNECTIVITY_CHANGE". Die wichtigsten beiden Zeilen sind eigentlich
    Code:
            ContextWrapper cw = new ContextWrapper(context);
            cw.sendBroadcast(REQUEST_REQUERY);
    Das meiste andere ist eigentlich nur logging, da ich auf Fehlersuche bin.

    Die Methode getCarrierState() werde ich glaube ich da wieder rausnehmen, da ich sie, denke ich, nicht brauche. Darum ist sie auch auskommentiert.

    Die Aufgabe selbst ist eigentlich so simpel:

    1. Höre auf "android.net.conn.CONNECTIVITY_CHANGE"
    2. Sende Broadcast "com.twofortyfouram.Intent.ACTION_REQUEST_QUERY"
    Nur leider funtkioniert das nur ein EINZIGES Mal...

    Chris

    P.S.: Hier der Code:

    Code:
    package com.schmeisserweb.carrierstring;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.ContextWrapper;
    import android.content.Intent;
    import android.os.Bundle;
    import android.telephony.TelephonyManager;
    import android.util.Log;
    
    /**
     * {@code Service} for monitoring the {@code REGISTERED_RECEIVER_ONLY}
     * {@code Intent}s {@link Intent#ACTION_SCREEN_ON} and
     * {@link Intent#ACTION_SCREEN_OFF}.
     */
    public final class NetworkConnectivityReceiver extends BroadcastReceiver {
    
        private static final Intent REQUEST_REQUERY = new Intent(
                com.twofortyfouram.Intent.ACTION_REQUEST_QUERY);
    
        static {
            REQUEST_REQUERY.putExtra(com.twofortyfouram.Intent.EXTRA_ACTIVITY,
                    EditActivity.class.getName());
        }
        //private static String carrier;
        
        @Override
        public void onReceive(final Context c, final Intent i) {
            startReception(c, i);
        }
    
        private void startReception(final Context context, final Intent intent) {
            String action = intent.getAction();
            Log.d("CarrierCondition", "Action Received: " + action + " From intent: " + intent);
            Bundle extras = intent.getExtras();
            for (String key : extras.keySet()) {
                Log.d("CarrierCondition", key + "::" + extras.get(key));
            }
            //carrier = getCarrierState(context);
            ContextWrapper cw = new ContextWrapper(context);
            Log.d("CarrierCondition","Broadcast sent");
            cw.sendBroadcast(REQUEST_REQUERY);
            
            /*final IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            cw.registerReceiver(this, filter);*/
            
    
        }
    
    /*    public static String getCarrierState(final Context c) {
            if (carrier == null) {
                try {
                    final ContextWrapper cw = new ContextWrapper(c);
                    final TelephonyManager tm = (TelephonyManager) cw
                            .getSystemService(Context.TELEPHONY_SERVICE);
                    final String carrier = tm.getNetworkOperatorName();
    
                    Log.d("CarrierCondition", "State is " + carrier); //$NON-NLS-1$ //$NON-NLS-2$
    
                    return carrier;
                } catch (final Exception e) {
                    Log.e("CarrierCondition", "Error", e); //$NON-NLS-1$ //$NON-NLS-2$
                }
            }
    
            return carrier;
        }
    */
    }
    
     
  5. KurrKurr, 02.09.2010 #5
    KurrKurr

    KurrKurr Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    143
    Erhaltene Danke:
    24
    Registriert seit:
    16.01.2010
    Phone:
    Motorola Milestone
    Hmmmm.... sehr schräg: Jetzt gehts irgendwie... Also zumindest das Broadcasten.

    Jetzt spinnt die Bedingung selbst wieder...

    Bald ist es soweit: Ich hab zwar schon ein Einsteigerbuch zu Android gelesen und mich mit diversen Tutorials beschäftigt, aber jetzt gehe ich bald in die nächste Buchhandlung und kaufe mir ein richtig dickes Android-Buch...

    Aber noch mal zurück zu meinem Problem:

    Also ein über Java-Code registrierter Receiver lebt einen Aufruf lang und ein über XML deklarierter, lungert immer herum. Habe ich das richtig verstanden?

    Chris
     
  6. FelixL, 02.09.2010 #6
    FelixL

    FelixL Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Ich glaub die über Java-Code registrierten leben solange bis der Service der das Ding registriert hat nicht mehr da ist. Kann also sein das man damit nie was empfängt, aber auch vielleicht für immer ;)

    Die xml-Dinger sind meiner Meinung nach wenn möglich vorzuziehen.
    Ich ärgere mich z.B. ohne Ende darüber das das für ACTION_HEADSET_PLUG nicht geht -.-
     
  7. KurrKurr, 02.09.2010 #7
    KurrKurr

    KurrKurr Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    143
    Erhaltene Danke:
    24
    Registriert seit:
    16.01.2010
    Phone:
    Motorola Milestone
    Darüber hab ich denke ich schon Mal was aus StackOverflow gelesen... denke ich.

    Ich bin zZt. der Ansicht, dass die Requestverwaltung von Locale wahrscheinlich daran schuld ist, dass mein Broadcast nicht immer zu einer Überprüfung der Condition führt.

    Es steht in deren API:
    Wahrscheinlich ist es besser, das ganze selbst zu Implementieren und sich nicht auf das Framework von Locale zu verlassen...

    Hat eigentlich schon jemand Erfahrung im Umgang mit Locale gemacht? Also aus Developersicht?

    MfG, Chris
     
  8. Kranki, 02.09.2010 #8
    Kranki

    Kranki Ehrenmitglied

    Beiträge:
    3,831
    Erhaltene Danke:
    814
    Registriert seit:
    19.07.2009
    Tablet:
    Samsung Galaxy Tab 3 7.0 Lite
    So steht es in meinem Buch.
     
    FelixL bedankt sich.
  9. KurrKurr, 02.09.2010 #9
    KurrKurr

    KurrKurr Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    143
    Erhaltene Danke:
    24
    Registriert seit:
    16.01.2010
    Phone:
    Motorola Milestone
    Welches hast du denn? Ich möchte nämlich nicht länger im Android-Nebel herumdümpeln, sondern mit fundiertem Hintergrundwissen an die Sache herangehen.

    Chris
     
  10. Kranki, 02.09.2010 #10
    Kranki

    Kranki Ehrenmitglied

    Beiträge:
    3,831
    Erhaltene Danke:
    814
    Registriert seit:
    19.07.2009
    Tablet:
    Samsung Galaxy Tab 3 7.0 Lite

Diese Seite empfehlen