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

ServiceStart beim Boot angepasst auf Userpräferenz

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von sem_thesis, 25.03.2011.

  1. sem_thesis, 25.03.2011 #1
    sem_thesis

    sem_thesis Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    111
    Erhaltene Danke:
    0
    Registriert seit:
    06.03.2011
    Phone:
    Nexus One
    Hallo! :D


    Wie der Threadtitel schon sagt: Ich möchte einen Service laufen lassen, sobald Nexus One fertig bootet, falls der User den Service ausgewählt hat.

    Ich beschreibe kurz was ich gemacht habe und wo ich nicht mehr weitergekommen bin:

    1) Der Service ist in der Klasse UpdaterService.class implementiert
    2) Der User kann in der UserPrivacyOptions.class auswählen, ob er diesen Service aktivieren möchte (CheckBoxPreference cPhone: nimmt Wert 0 oder 1 an )

    Code:
    package com.semesterproject.socialmine;
    
    
    import android.content.Intent;
    import android.os.Bundle;
    import android.preference.CheckBoxPreference;
    import android.preference.Preference;
    import android.preference.Preference.OnPreferenceClickListener;
    import android.preference.PreferenceActivity;
    import android.widget.Toast;
     
    
    public class UserPrivacyOptions extends PreferenceActivity implements OnPreferenceClickListener {
       
    
       
           /* Assign a variable name to every feature i.e. preference */
            public CheckBoxPreference cPhone;
        
        
           /* The onCreate Method loads all Privacy Options and sets a Listener on the each of them */
           
            protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
    
                    /* Load graphical layout from res/layout/userprivacyoptions.xml directory */
                    addPreferencesFromResource(R.layout.userprivacyoptions);  
    
    
                    /* Assign variables to the corresponding checkbox given in 'android:key=".."' of userprivacyoptions.xml */
    
                    cPhone = (CheckBoxPreference) findPreference("checkboxPhone");
       
    
                    /* Make all preferences 'listenable', i.e. to check their state and act accordingly */
    
                    cPhone.setOnPreferenceClickListener(this); 
                    
                    /* Initialize all Services */
     
                    if (cPhone.isChecked())
                   {
                    startService(new Intent(this, UpdaterService.class));
                  } else {         
                    stopService(new Intent(this, UpdaterService.class));
                  }       
        
            }
    
    
            
           /* The onPreferenceClick Method reacts to a User Click by either activating or deactivating services */
            
          public boolean onPreferenceClick(Preference preference) {
    
                if (cPhone.isChecked())
               {
                startService(new Intent(this, UpdaterService.class));
                  Toast.makeText(getBaseContext(), "Activating Phone Mining now!",Toast.LENGTH_LONG).show();                        
              } else {         
                stopService(new Intent(this, UpdaterService.class));
                   Toast.makeText(getBaseContext(), "Deactivating Phone Mining  now!",Toast.LENGTH_LONG).show();                        
              }       
     
             
             return true;
          }
    }
    
    3) Nun habe ich eine Receiverklasse eingebaut namens StartAtBootServiceReceiver.class, die auf Phoneboot reagiert und den Service startet. Ich habe folgenden Tutorial zu Hilfe genommen: Starting an Android Service at Device Boot — Greg Fiumara

    So weit, so gut.

    4) Jetzt kommt der schwierige Teil: StartAtBookServiceReceiver.class soll nur reagieren falls cPhone.isChecked den Wert 1 ergibt, sonst soll der Service nicht starten.

    Code:
    package com.semesterproject.socialmine;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.preference.CheckBoxPreference;
     
    
    
    /* This class collects privacy settings from UserPrivacyOptions.class
     * and starts the respective Service at bootup is enabled */
    
    
    public class StartAtBootServiceReceiver extends BroadcastReceiver {
       
       
       @Override
       public void onReceive(Context context, Intent intent) 
       {
          
          /* This only enables the Service if cPhone is true
           * Somehow the app crashes when I use this code, so I commented it for now
           * Can you find any mistakes or another way to do this?
           
          UserPrivacyOptions u = new UserPrivacyOptions();
          CheckBoxPreference cp = u.cPhone;
          
          if (cp.isChecked())   {
             
                if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
             
                Intent i = new Intent();
                i.setAction("com.semesterproject.socialmine.UpdaterService");
                context.startService(i);
              }      
             
          }
       
       }
       
       
    }
    Konsequenz: Sofort nach dem Booten --> APP-CRASH!


    Hat jemand 'ne Idee wie man das tweaken kann?
    Kommentare sind willkommen : )


    PS: Sourcecode ist im Attachment als zip-File fürs Testen eingebettet.
     

    Anhänge:

  2. maniac103, 25.03.2011 #2
    maniac103

    maniac103 Android-Lexikon

    Beiträge:
    1,237
    Erhaltene Danke:
    1,157
    Registriert seit:
    24.01.2011
    Wie wär's mit
    Code:
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    boolean enabled = prefs.getBoolean("checkboxPhone", false);
    
    if (enabled) {
        /* starte Service */
    }
    
    ;)
     
    sem_thesis bedankt sich.
  3. sem_thesis, 25.03.2011 #3
    sem_thesis

    sem_thesis Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    111
    Erhaltene Danke:
    0
    Registriert seit:
    06.03.2011
    Phone:
    Nexus One
    Wow - du bist guuuutttt :thumbsup:

    Kannst du mir bitte kurz erklären, wieso meine Variante nicht funktioniert hat und deine schon??
     
  4. Fr4gg0r, 25.03.2011 #4
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    Die SharedPreferences werden doch in xml in /data gespeichert...
    was du tust ist ein Objekt deiner Preference Klasse zu erstellen, die jedoch nicht die in xml gespeicherten Werte lädt.

    Der Crash wird wohl von nem Nullpointer her kommen.

    Wenn du im Konstruktor die Werte lädst und die CheckboxPreference initialisierst, dürfte es funktionieren. ;)
     
  5. maniac103, 25.03.2011 #5
    maniac103

    maniac103 Android-Lexikon

    Beiträge:
    1,237
    Erhaltene Danke:
    1,157
    Registriert seit:
    24.01.2011
    Genauer gesagt dürfte es reichen, u.onCreate(null) aufzurufen. Bin mir da aber nicht sicher, und ist auch ziemlich von-hinten-durch-die-Brust-ins-Auge.
    Die Variante, die ich gepostet habe, ist um Längen schneller, weil sie wirklich nur die Einstellung ausliest.

    Wichtig zum Verständnis: Die CheckBoxPreference ist nicht die eigentliche Einstellung, sondern nur eine Repräsentation. Die eigentliche Einstellung liegt in den SharedPreferences; das Speichern wird halt durch die CheckBoxPreference transparent im Hintergrund gemacht.
     
  6. sem_thesis, 25.03.2011 #6
    sem_thesis

    sem_thesis Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    111
    Erhaltene Danke:
    0
    Registriert seit:
    06.03.2011
    Phone:
    Nexus One
    Ok...... leuchtet mir ein wenig ein.


    Mit deiner Variante könnte ich also von überall die CheckBox-Werte aufrufen.

    Ich habe jetzt genau den gleichen Code in der Hauptklasse (leerer Screen) eingegeben.
    Die Hauptklasse zeigt den ersten leeren Bildschirm an, sobald die App installiert wird.
    Mit dem SharedPreferences-Code ist das Ganze wieder gecrasht - hätte aber nich sein sollen, oder?
    Liegt das daran, dass die Präferenzen erst nach erscheinen des Präferenzscreens geladen werden und deshalb noch gar nicht 'existieren' auf eine Art?
    Es gibt aber bestimmte Defaultwerte im .xml File.


    Ich hab' auch eine andere Variante versucht - nämlich ein Intent aufrufen der UserPrivacyOptions.class.
    Dies hat aber bewirkt, dass der HauptScreen gar nicht erscheint, sondern die App gerade zum UserPrivacyOptions screen übergeht :(



    Hmmmmm.... versteh's jetzt doch nicht.
    Wie kann ich sofort nach App-Install die Präferenzen abrufen und Service starten (in der onCreate() Methode) ?
     
  7. maniac103, 26.03.2011 #7
    maniac103

    maniac103 Android-Lexikon

    Beiträge:
    1,237
    Erhaltene Danke:
    1,157
    Registriert seit:
    24.01.2011
    Doch, das muss so sein :D

    Spaß beiseite: Damit das nicht in Rumraterei ausartet, poste mal bitte den Code und den Stacktrace (aus dem Logcat).

    Nein, die SharedPreferences schauen nur ins Config-File. Wie gesagt: Der PreferenceScreen ist nur eine Repräsentation der Config-Werte; die Werte kann man aber auch ohne GUI auslesen.

    Die aber wiederum nix mit den Defaults beim getBoolean, getString usw. zu tun haben (das false, was bei mir dransteht, ist der Defaultwert).

    Das ist ja auch Sinn und Zweck des Intents ;)
    Ich glaube, du solltest erst mal noch etwas Doku lesen ;)

    Direkt nach Installation den Service starten geht glaub ich nicht. Ich würde den Service nach der Installation deaktiviert lassen und starten, wenn der Benutzer die Checkbox setzt.
     
  8. sem_thesis, 26.03.2011 #8
    sem_thesis

    sem_thesis Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    111
    Erhaltene Danke:
    0
    Registriert seit:
    06.03.2011
    Phone:
    Nexus One
    Wirklich??
    Hmm... ja der Sinn meiner App ist eigentlich, dass der Benutzer eigentlich im Vordergrund etwas spielt und im Hintergrund seine Daten gesammelt werden.
    Auf den Preference-Screen kommt er aber nur, wenn er dies im Menü wählt.


    Hm.. also wenn es wirklich nicht möglich ist, dann muss ich in der oncreate()-Methode das Intent zum Preference-Screen aufrufen, damit gerade nach Installation der Preference-Screen erscheint. Sonst werden die Services womöglich nie gestartet :blink:


    PS: Neuer Sourcecode ist angehängt.
     

    Anhänge:

Diese Seite empfehlen