SharedPreferences sind auf einmal leer

  • Antworten:6
  • OffenNicht stickyNicht beantwortet
  • Forum-Beiträge: 4

29.06.2015, 00:47:13 via Website

Hallo erstmal,
an alle hier im Forum. Ich erstelle gerade eine App und habe mich bisher, auch durch schwierige Sachen, ganz gut allein durchgefuchst. Nun bin ich jedoch seit Tagen am Verzweifeln und weiß nicht mehr weiter.
Ich habe als Einstieg eine Login DialogActivity, das Passwort wird in den SharedPreferences gespeichert. Ein Service überprüft dann einige Events und es poppt ggf. eine weitere DialogActivity auf. Das hier einzugebende Passwort checke ich nun bei Button-Klick mit dem in den SharedPreferences gespeicherten Passwort auf Übereinstimmung. Alles funktioniert bei allen Dialogen soweit einwandfrei. Innerhalb der gesamten App sind die Prefs abrufbar und alle da.
Nun habe ich eine weitere DialogActivity, wo ich es genauso wie in den anderen gemacht habe, doch auf einmal sind die Prefs leer. Kein gespeichertes Password mehr da…, und ich bekomme eine NullPointerException.

Ich habe es alternati mit einer static Variable in meinem Service versucht, die ich dann in der betreffenden DialogActivity abrufe…, erfolglos. Die ist auch leer.
Ich bitte Euch um Hilfe, was ich tun kann. Die SharedPrefs-Lösung wäre mir schon am liebsten, da ich alle anderen Daten auch darin speichere.

Hier meine Logcat-Ausgabe:

06-29 00:20:47.552: E/AndroidRuntime(16170): FATAL EXCEPTION: main
06-29 00:20:47.552: E/AndroidRuntime(16170): Process: de.getappsolution.kidstimelocker, PID: 16170
06-29 00:20:47.552: E/AndroidRuntime(16170): java.lang.IllegalStateException: Could not execute method of the activity
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.view.View$1.onClick(View.java:4221)
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.view.View.performClick(View.java:5155)
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.view.View$PerformClick.run(View.java:20747)
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.os.Handler.handleCallback(Handler.java:739)
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.os.Handler.dispatchMessage(Handler.java:95)
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.os.Looper.loop(Looper.java:145)
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.app.ActivityThread.main(ActivityThread.java:5832)
06-29 00:20:47.552: E/AndroidRuntime(16170): at java.lang.reflect.Method.invoke(Native Method)
06-29 00:20:47.552: E/AndroidRuntime(16170): at java.lang.reflect.Method.invoke(Method.java:372)
06-29 00:20:47.552: E/AndroidRuntime(16170): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
06-29 00:20:47.552: E/AndroidRuntime(16170): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
06-29 00:20:47.552: E/AndroidRuntime(16170): Caused by: java.lang.reflect.InvocationTargetException
06-29 00:20:47.552: E/AndroidRuntime(16170): at java.lang.reflect.Method.invoke(Native Method)
06-29 00:20:47.552: E/AndroidRuntime(16170): at java.lang.reflect.Method.invoke(Method.java:372)
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.view.View$1.onClick(View.java:4216)
06-29 00:20:47.552: E/AndroidRuntime(16170): ... 10 more
06-29 00:20:47.552: E/AndroidRuntime(16170): Caused by: java.lang.NullPointerException: println needs a message
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.util.Log.println_native(Native Method)
06-29 00:20:47.552: E/AndroidRuntime(16170): at android.util.Log.i(Log.java:207)
06-29 00:20:47.552: E/AndroidRuntime(16170): at de.getappsolution.kidstimelocker.DialogAdminDisabled.disableAdmin(DialogAdminDisabled.java:66)
06-29 00:20:47.552: E/AndroidRuntime(16170): at de.getappsolution.kidstimelocker.DialogAdminDisabled.onClick(DialogAdminDisabled.java:38)
06-29 00:20:47.552: E/AndroidRuntime(16170): ... 13 more

Vielen Dank für jeden noch so kleinen Tip.

Antworten
  • Forum-Beiträge: 4

29.06.2015, 13:27:34 via Website

Das ist mir klar, ich weiß auch wo. Die Frage ist, wie du oben lesen kannst, WARUM?
In allen anderen Dialogen kann ich auf alle gespeicherten SharedPrefs zugreifen, nur in dieser einen DialogActivity sind die prefs auf einmal leer.

Die Speicherung des Passwortes, das ich im besagten Dialog abrufen wil, wird gespeichert. Das habe ich durch den Debugger geschickt und das funktioniert fehlerfrei. Es müsste also theoretisch da sein.

— geändert am 29.06.2015, 13:30:51

Antworten
  • Forum-Beiträge: 72

29.06.2015, 14:17:11 via Website

Kannst du uns mal deinen Code schreiben?
Ich vermute mal, dass du einen anderen Speicher Pfad angegeben hast.

Antworten
  • Forum-Beiträge: 4

29.06.2015, 15:47:08 via Website

Hier die Login Activity --> Passwortspeicherung: (startApp() habe ich der Länge wegen nicht mit kopiert)

public class LoginActivity extends Activity implements OnClickListener {
SharedPreferences prefs;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
    Log.i("prefs main", prefs.getAll().toString());
    if(prefs.contains(MainActivity.KEY_LOGIN_PASS)) {
        setContentView(R.layout.login_activity);
    } else {
        setContentView(R.layout.set_pass_activity);
    }
}

@Override
public void onClick(View view) {
    switch (view.getId()) {
    case R.id.setpass_ok_button:
        savePassword();
        break;

    case R.id.setpass_cancel_button:
        this.finish();
        break;

    case R.id.login_ok_button:
        startApp();
        break;

    case R.id.login_close_button:
        this.finish();
        break;

    default:
        break;
    }
}

//!!!!!!!!!!!!!!!!!!!!!!
//encrypt it later!!!!!!
//!!!!!!!!!!!!!!!!!!!!!!
private void savePassword() {
    EditText text = (EditText) findViewById(R.id.setpass_edit_password);
    String passText = text.getText().toString();
    if (passText.trim().equals("")) {
        Toast.makeText(this, "Bitte Passwort eingeben", Toast.LENGTH_SHORT).show();
    } else {
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(MainActivity.KEY_LOGIN_PASS, passText);
        editor.commit();
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        this.finish();
    }
}

Mein Service --> ruft die DialogActivity auf: (gekürzt, auf die wichtigsten Methoden)

public class ServiceLockApps extends Service {
SharedPreferences prefs;
DevicePolicyManager devicePolicyManager;
ComponentName devAdmin;
private String hour = "hour";
private String minute = "minute";
int smsCounter = 0;
int smsCounterUpdate = 1;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

public void onCreate() {
    prefs = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putBoolean(MainActivity.KEY_PASS_OK, false);
    editor.commit();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i("ServiceLockApp", "Service gestartet");
    Runnable r = new Runnable() {
        public void run() {
            int delay = 5000;
            int period = 5000;
            Timer timer = new Timer();

            timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    String currAppName = "";

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                        List<RunningAppProcessInfo> processes = activityManager.getRunningAppProcesses();
                        int pID = processes.get(0).pid;
                        currAppName = getCurrentRunningAppName(pID);
                        Log.i("current appname", currAppName);
                    }
                    else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                        Log.i("SDK Version", "ICE_CREAM_SANDWICH");
                        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                        List<ActivityManager.RunningTaskInfo> tasks = manager.getRunningTasks(1);
                        currAppName = tasks.get(0).topActivity.getPackageName();
                        Log.i("current appname", currAppName);
                    }
                    else {
                        Log.i("SDK Version", "legacy");
                    }

                    lockSchoolApps(currAppName);
                    lockBedApps(currAppName);
                    lockApps(currAppName);
                    lockCustomApps(currAppName);

                    Context context = getApplicationContext();
                    try {
                        if (Settings.System.getInt(context.getContentResolver(), System.AUTO_TIME) == 0) {
                            showTimeChangeDialog();
                            Log.i("change time", "automatische Zeit aus");
                        } else {
                            Log.i("change time", "automatische Zeit an");
                        }
                    } catch (SettingNotFoundException e) {
                        e.printStackTrace();
                    }

                    devicePolicyManager = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
                    devAdmin = new ComponentName(context, DevAdminReceiver.class);
                    if(!isActiveAdmin()) {
                        showAdminDisabledDialog();
                    }
                }
            }, delay, period);
        }
    };

    Thread t = new Thread(r);
    t.start();
    return Service.START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    startService(new Intent(this, ServiceLockApps.class));
}

private boolean isActiveAdmin() {
    Log.i("admin active", Boolean.toString( devicePolicyManager.isAdminActive(devAdmin)));
    return devicePolicyManager.isAdminActive(devAdmin);
}

Und hier die besagte DialogActivity:

public class DialogAdminDisabled extends Activity implements OnClickListener {
SharedPreferences prefs;
// boolean okButton = false;
static final int ACTIVATION_REQUEST = 47; // identifies our request id
DevicePolicyManager devicePolicyManager;
ComponentName devAdmin;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.dialog_admin_disabled);
    prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.admin_enable_button:
        enableAdmin();
        break;
    case R.id.admin_disable_button:
        disableAdmin();
        break;

    default:
        break;
    }
}

private void enableAdmin() {
    devicePolicyManager = (DevicePolicyManager) getApplicationContext()
            .getSystemService(Context.DEVICE_POLICY_SERVICE);
    devAdmin = new ComponentName(getApplicationContext(), DevAdminReceiver.class);
    if (!isActiveAdmin()) {
        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, devAdmin);
        // intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
        startActivityForResult(intent, ACTIVATION_REQUEST);
        this.finish();
    }
}

private void disableAdmin() {
    EditText text = (EditText) findViewById(R.id.edit_admin_password);
    String pass = text.getText().toString();
    Log.i("pref alle", prefs.getAll().toString());
    Log.i("pref pass", prefs.getString(MainActivity.KEY_LOGIN_PASS, null));   <<<------------------- Exception
    if (pass.equals(prefs.getString(MainActivity.KEY_LOGIN_PASS, null))) {
        devicePolicyManager.removeActiveAdmin(devAdmin);
    } else {
        text.setText("");
        Toast.makeText(this, "Ungültiges Passwort. Bitte erneut eingeben oder Admin wieder aktivieren!", Toast.LENGTH_SHORT).show();
    }
    this.finish();
}

private boolean isActiveAdmin() {
    Log.i("admin active", Boolean.toString(devicePolicyManager.isAdminActive(devAdmin)));
    return devicePolicyManager.isAdminActive(devAdmin);
}

}

Im Service wird ebenso der TimeChangeDialog aufgerufen und da klappt mit Passwortabruf alles wunderbar.

— geändert am 29.06.2015, 15:50:31

Antworten
  • Forum-Beiträge: 2.330

01.07.2015, 10:53:08 via Website

Ich würde auch vermuten, dass die Preferences für verschiedene Kontexte geholt werden.
Setz doch mal in beiden Fällen einen Breakpoint und inspiziere im Debugger die Instanz der SharedPrefs im Hinblick auf deren "Domäne".

Siehe http://stackoverflow.com/questions/5946135/difference-between-getdefaultsharedpreferences-and-getsharedpreferences

Falls es das nicht ist, füge mal einen PreferenceListener hinzu und schau wo die Preference vielleicht noch überschrieben/gelöscht wird.
Oder such nach Verwendungen von putString und den anderen schreibenden Methoden. Vielleicht hast ja noch irgendwo was vergessen, was den Wert überschreibt.

Antworten
  • Forum-Beiträge: 4

05.07.2015, 23:47:15 via Website

Sooooo…., habsch jetzt endlich den Fehler gefunden.
Unter aktiviertem und deaktiviertem Device Admin werden zwei verschiedene SharedPreferences angelegt. Da ich immer hin und her gewechselt habe, um Fehlerquellen zu finden, hatte ich natürlich beim einloggen keinen Admin-Status, beim festlegen verschiedener Prefs dann allerdings schon.
Hätte man auch eher drauf kommen können, dass das ja zwei verschiedene User sind.
Trotzdem danke an alle, die sich mit mir den Kopf zerbrochen haben.

Antworten