Sharedpreferences von Fragment zu anderer Activity

  • Antworten:20
  • Bentwortet
Manu Schmidt
  • Forum-Beiträge: 12

27.09.2018, 22:46:47 via Website

Hallo an alle.
Ich habe mal eine Frage, ich stehe im Moment etwas auf dem Schlauch.

Ich habe eine MainActivity in der ich einen ViewPager drin habe. In dem ViewPager sind 2 Fragmente.
Im Fragment 1 habe ich ein Edittext der über sharedpreferences in einem String gespeichert werden soll.
Über getActivity().sharedpreferences konnte ich die prefs auch in das Fragment einbinden.
Nun sollen die Daten über Button.setOnClickListener in Sharedpreferences gespeichert werden und dann in einer 2 Aktivity angezeigt werden.
Von Activity1 zu Aktivity 2 funktioniert das auch alles aber bei den Strings aus dem Fragment bleiben die Aussage Felder leer🙁
Muss ich die Daten aus einem Fragment anders in die Aktivity 2 einbinden?
Wäre schön wenn jemand einen Tipp für mich hat.

Danke Gruß Manu

Kommentieren
Beste Antwort
Jokel
  • Forum-Beiträge: 1.530

30.09.2018, 09:33:12 via Website

Also ich benutze immer die default pref und habe da auch keine Probleme .
Pref=PreferenceManager.getDefaultSharedPreferences(this);

Ich brauche meistens keine eigene Fahrer Datei da ich dort wirklich nur Einstellungen speichere die auch nach dem beenden erhalten bleiben sollen.

Dein Problem konnte erstens an deinem Key ligen den da du uns wieder nicht deinen final aufgezeigt hat können wir das auch nicht ausschließen.
Zweitens an dem Parameter MODE_PRIVATE ich weiss jetzt nicht ob das Privatheit auf die activity oder die App bezogen ist.

Hilfreich?
Manu Schmidt
Kommentieren
swa00
  • Forum-Beiträge: 3.704

27.09.2018, 23:04:05 via Website

Hallo Manu,

ohne entsprechenden Code und einen Aufbau kann man nur schlecht effektiv helfen.

Du solltest mal deinen Code debuggen um festzustellen , ob überhaupt dein reading der Shares angestossen wird.

Grundsätzlich solltest du aber eher mit Broadcasts arbeiten , wenn du etwas hin und her schicken möchtest. Das scheint ja bei dir temporär zu sein - Shares sind da eher fehl am Platze.

Oder halt Intents bei der Initalisierung von Activities.

Auch eine elegante Lösung ist die Verwendung von SingleTon-Klassen mit Listener.

— geändert am 27.09.2018, 23:16:04

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Pascal P.
Kommentieren
Bastian Siewers
  • Forum-Beiträge: 9.729

28.09.2018, 10:45:39 via Website

Hallo Manu,

herzlich Willkommen bei AndroidPIT! :)

Ich habe deinen Thread mal in den passenden Bereich verschoben ;)

Hilfreich?
Kommentieren
Manu Schmidt
  • Forum-Beiträge: 12

28.09.2018, 13:30:46 via Website

Hallo, erstmal danke für die schnelle Antwort und natürlich auch fürs verschieben.;-)

Ich habe den Code mal mit dem Debuger überprüft und da werden die Daten auch übernommen.

Hier mal der Code aus Fragment1


public static String PLZ;
public static String Ein001;

SharedPreferences prefs;
SharedPreferences.Editor prefsEditor;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    contentView1 = inflater.inflate( R.layout.fragment1_layout, null );

    E001 = (EditText) contentView1.findViewById(R.id.E001);

    return contentView1;  }


@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {

    SharedPreferences prefs = this.getActivity().getSharedPreferences( "Leerdata", Context.MODE_PRIVATE);
    prefsEditor = prefs.edit();



    ImageButton but =(ImageButton) contentView1.findViewById( R.id.Verwenden1 );

    but.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if(E001.getText().length()==0){
                   E001.setError( "PLZ eingeben" );
                   return;}

            if (E001.getText().length() > 0) {
                Ein001 = E001.getText().toString();
                prefsEditor.putString( PLZ, Ein001 );
                prefsEditor.commit();


        }

        }
    });


    super.onViewCreated( view, savedInstanceState );



}

}


und der Code aus der Output Activity


SharedPreferences prefs;
SharedPreferences.Editor prefsEditor;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.activity_output );

    prefs = this.getSharedPreferences("Leerdata", MODE_PRIVATE);
    prefsEditor = prefs.edit();

    AUS_PLZ = (TextView) findViewById( R.id.AUS_PLZ );



    SharedPreferences result = getSharedPreferences( "Leerdata", Context.MODE_PRIVATE );
    String Ein001 = result.getString( "PLZ","" );
    AUS_PLZ.setText( Ein001 );

Ich hoffe das euch die Daten reichen.

Dank euch:-)

Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

28.09.2018, 14:18:37 via Website

Hallo Manu,
kann es sein dass du hier die Variable PLZ als Key verwendest, aber diese nie initialisierst da:
1. prefsEditor.putString( PLZ, Ein001 );
2. public static String PLZ; // hat keinen default Wert und du setzt auch nie einen.
3. Beim auslesen: String Ein001 = result.getString( "PLZ","" ); // Schreibst du "PLZ" direkt als String rein.., die Keys müssen schon matchen und != null sein

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

Hilfreich?
Kommentieren
Manu Schmidt
  • Forum-Beiträge: 12

28.09.2018, 15:47:32 via Website

Ich habe noch nie einen != null Wert in einen String gesetzt, hat auch bisher immer geklappt zumindest von Aktivity zu Aktivity zu übertragen. Nur wenn ich die Daten aus einem Fragment holen möchte dann gibt er die nicht im der Output Activity aus. Ich habe es gerade getesten von Aktivity Test1 zu Output funktioniert mein Code.
:?

— geändert am 28.09.2018, 15:48:26

Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

28.09.2018, 15:56:18 via Website

Dann musst du jetzt aber auch das Beispiel bei den beiden Activities posten.
Und man muss und sollte als Keys in den Shared Prefs passende String Keys verwenden, sonst kannst du genau 1 Wert mit dem Key null abspeichern (wobei ich bezweifle, das es geht...)

Stell deir den Key als Identifizierer vor. Mit (keine Information)=NULL wie dein angeblicher Key kannst du keine Datensätze identifizieren.
Damit tappst du immer in eine Falle!

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

Hilfreich?
Kommentieren
Manu Schmidt
  • Forum-Beiträge: 12

28.09.2018, 16:12:01 via Website

Hier der Code aus der Test1 Activity


SharedPreferences prefs;
SharedPreferences.Editor prefsEditor;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test1);

    butweiter1 = (Button) findViewById(R.id.butweiter1);
    butweiter1.setOnClickListener(this);

    E001 = (EditText) findViewById(R.id.E001);

    prefs = this.getSharedPreferences("Leerdata", MODE_PRIVATE);
    prefsEditor = prefs.edit();

}


@Override
public void onClick(View v) {


    switch (v.getId()) {



        case R.id.butweiter1: {

            Intent intent = new Intent( Test1.this, Output.class );


           if(E001.getText().length()==0){
              E001.setError( "PLZ eingeben" );
              return;}

                if (E001.getText().length() > 0) {
                Ein001 = E001.getText().toString();
                prefsEditor.putString( PLZ, Ein001 );
                prefsEditor.commit();

            }


            startActivity( intent );

        }





    }
}

@Override
public void onPointerCaptureChanged(boolean hasCapture) {

}

}


an der Output Activity habe ich nichts verändert die ist genau so wie oben.

der einsige Unterschied zwichen Fragment 1 und Test1 eins ist

Fragment1
SharedPreferences prefs = this.getActivity().getSharedPreferences( "Leerdata", Context.MODE_PRIVATE);

Test1
prefs = this.getSharedPreferences("Leerdata", MODE_PRIVATE);

das ich in der Test1 Version das getActivity rausgenommen habe weil es ja kein Fragment ist.

Ich verstehe nicht warum das im Fragment nicht geht aber von einer Activity aus

Gruß Manu

Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

28.09.2018, 16:14:54 via Website

Bekommst du irgend eine Fehlermeldung im Log oder so?

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

Hilfreich?
Kommentieren
Manu Schmidt
  • Forum-Beiträge: 12

28.09.2018, 16:38:41 via Website

nein leider nicht:-(

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

28.09.2018, 21:51:45 via Website

Hallo mische mich mal dazu.
Wie ich aus deinem ersten Post lese arbeitest du mit dem viewpager und zwei Fragmente.
Nun ist es beim viewpager so das er immer die Nachbar Fragmente vorlädt um sie schneller beim swep anzuzeigen.

Es wird somit schon die onCreateView des zweiten fragments zum Zeitpunkt des erstens Fragment durchlaufen . Somit wird beim swep zu Fragment zwei nicht mehr die onCreateView, onResume... Durchlaufen.
Da du nur zwei Fragmente hast werden diese Methoden nur ein mal durchlaufen am Anfang beim App Start danach nicht mehr.

Denke das ist der Fehler. Bei activitys ist das anders. Da wird immer die onCreate durchlaufen. Wenn du die Fragmente selber austauschst geht das auch mit dem viewpager nicht so einfach.
Das ist halt die Eigenart des viewpager.

Eine frage zu deinem Code habe ich noch was ist "PLZ" ?
Ich denke es ist ein final Sring PLZ = "PLZ";

Denn nur so macht dein Code einen Sinn und kann auch laufen was du behauptest.
Denn beim speichern in die Präferenzen benutzt du eine Variable und beim lesen eine Zeichenfolge.
Nur wenn die Variable und ihr Inhalt gleich sind kann dein Code laufen. Aber das hast du uns nicht gezeigt. Deshalb sind auch meine vorredner etwas stutzig geworden.

Dein Hauptproblem ist aber mein erster Ansatz.

LÖsche mal die app und installiere neu nun sind deine Prefs weg schaue ob deine pref nun auch wider geschrieben und gelesen werden.

— geändert am 29.09.2018, 16:56:41

Hilfreich?
Kommentieren
Manu Schmidt
  • Forum-Beiträge: 12

29.09.2018, 14:32:57 via Website

Ja du hast natürlich recht PLZ ist ein Final String der auch im puplic class gesetzt ist.

Ich werde es mal mit einer neuinstallation der App versuchen.

Manu

Hilfreich?
Kommentieren
Manu Schmidt
  • Forum-Beiträge: 12

29.09.2018, 15:47:14 via Website

Neu Installieren hat leider auch keinen erfolg gebacht.
Ich habe nach der deinstallation auch alle dazugehörigrn Ordner gelöscht um wirklich alles sauber zu bekommen. Hat leider nichts gebracht.
Eventuell habt ihr noch andere Ideen bin für alles offen.

Danke Manu

— geändert am 29.09.2018, 16:45:10

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

29.09.2018, 16:53:25 via Website

Das mit der neu Installation war nur dafür gedacht um zu Prüfen ob auch deine Präferenzen geschrieben und gelesen werden. Das eigentliche Problem ist der viewpager und das benachbarte fragmente beim anzeigen nicht neu geladen werden. Wenn du im Fragment 1 etwas in den pref speicherst , wird beim anzeigen des Fragment 2 nicht deine onCreateView durchlaufen auch nicht die onResume. Deshalb kann auch nicht der neue gespeicherte wert an gezeigt werden. Wenn du zb in einem onklick listner deinen Prof abfragen und anzeigen lässt wird der zuvor neue wert auch angezeigt werden.
Das liegt daran das bei nur zwei Fragmente kein automatischer Refresh stattfindet.
Wie ich dir schon sagte ist das die Eigenart des Viewpager. Um mitzubekommen wann das Fragment angezeigt wird, müsstest du einen listner benutzen kann dir aber jetzt nicht aus dem Kopf sagen welchen. Schau dazu mal in die doku.

https://stackoverflow.com/questions/7369978/how-to-force-viewpager-to-re-instantiate-its-items

https://medium.com/@taman.neupane/fragment-refresh-9ba6a6d7b897

— geändert am 29.09.2018, 17:08:02

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

29.09.2018, 17:27:02 via Website

Hi nur nochmal zum richtigen Verständnis.
Oder willst du die in deinem Fragment 1 gespeicherten werte in einer neuen activity wieder anzeigen?
Denn in deinem ersten Code posting hast du erst ein Fragment einspeichern, und beim anzeigen scheinbar eine actifity. Denn deine onCreate Methode gibt es in einem Fragment nicht.

Beschreibe nochmal genau was du machen willst sieht für mich sehr durcheinander aus.

Das alles ändert aber nichts an dem Verhalten des Viewpager.

Zeige uns auch mal den final String.
Wie kommst du von dem Fragment zu der neuen Activity?
Da könntest du auch die werte im bundle übergeben.

Da wir deinen String nicht sehen könne ob du wirklich die gleiche Zeichenfolge benutzt. Arbeite mal ohne konstante.

Also im Fragment prefsEditor.putString( "PLZ" , Ein001 );
In der activity
String Ein001 = result.getString( "PLZ","" );

Beide key müssen hundert Prozent gleich sein.

— geändert am 29.09.2018, 17:48:33

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

29.09.2018, 17:53:38 via Website

Und ich wiederhole meinen Vorschlag von oben, da die Fragmente zeitlich unterschiedlich erstellt werden.
(Eine Eigenart der Fragmente , wenn sie vom System "become visible" erhalten)

Es gibt zwar einige tricky-techniken das Ganze zu forcieren, würde ich aber nicht empfehlen , gerade wenn man nicht 100% fit darin ist.

In dem Falle einfach mit Broadcast arbeiten , 5 Zeilen und fertig.
Und darin kann man immer noch mit den Shares arbeiten , wenn sie permanent sein sollen.

— geändert am 29.09.2018, 18:16:24

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

29.09.2018, 21:59:10 via Website

@saw00 richtig
Aber ich denke sie will die Daten In einem der beiden Fragmente speichern und in einer neuen Activity, nicht die in der der viewpager ist wieder anzeigen. Wenn dem so ist sollte es eigentlich geh'n insofern der key und der Datei Name gleich ist.
Ich dachte auch erst sie will von einen Fragment zum anderen Fragment. n
Nur wenn ich ihre Ausführungen genau lese meine ich sie will von einen Fragment zu ich hoffe zu einer neuen activity gehen. Nicht das sie zu der activty in der der viewpager ist will dann geht es Nicht so einfach da hast du recht.
Jetzt ist sie erst mal am Zug zu antworten .

— geändert am 29.09.2018, 22:19:50

Hilfreich?
Kommentieren
Manu Schmidt
  • Forum-Beiträge: 12

29.09.2018, 22:58:46 via Website

@ Jokel

Genau so ist es:-)
Ich erkläre mal schnell wie der Aufbau ist damit es für alle verständlich ist.

Ich habe eine Activity (Hauptauswahl) in der ist ein ViewPager
in dem ViewPager liegen derzeit 2 Fragmente (sollen mal 4 werden)
in jedem Fragment sollen Daten eingegeben werden die ich dann in eine 2 Activity (Output) übertragen und dort Anzeigen lassen möchte. Die Daten sollen NICHT im Fragment 2 angezeigt werden sondern Ausschlieslich in Activity 2 (Output).

Ich hoffe ich konnte das so gut erklären das dir wisst was ich vorhabe.

Das das eigentlich gehen sollte dachte ich auch da ich die erste Version mit verschidenen Activitys erstellt hatte und dann zu einem Viewpager aumgestiegen bin und den Code einfach nur rüberkopiert habe. ich kann auchüber eine Startseite auf beide Versionen zugreifen und die Activity zu Activity Version funktioniert auch mit den Strings. Nur die Fragmentversion nicht.
Kann es daran liegen das in der Fragment Version der sharedpref befehl mit dem this.getActivity erweitert wurde? Kann ich mir zwar nicht vorstellen aber vieleicht kennt einer das Problem und hat den passenden Tipp für mich.

Danke fürs Helfen
Manu

PS: Manu ist kurz für Manuel;)(laughing)

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

29.09.2018, 23:08:03 via Website

Tja Manuel, jetzt biste ein Mädchen - willkommen bei den Jungs :-)

Grundsätzlich ist die Idee mit den Shares nichts Falsches, allerdings hatte ich ähnliche Probleme
damit und genervt aufgegeben. Mittlerweile arbeite ich schon gar nicht mehr mit den Shares.

Auch wäre jetzt meine Broadcast-Idee wiederum falsch am Platze .

Einen Ansatz könntest du dann eher in einer Singleton-Klasse finden, oder du baust dir eine
schöne SQLITE Klasse , dann bist du dir 100 % Sicher wo was ist.

— geändert am 29.09.2018, 23:10:04

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
Beste Antwort
Jokel
  • Forum-Beiträge: 1.530

30.09.2018, 09:33:12 via Website

Also ich benutze immer die default pref und habe da auch keine Probleme .
Pref=PreferenceManager.getDefaultSharedPreferences(this);

Ich brauche meistens keine eigene Fahrer Datei da ich dort wirklich nur Einstellungen speichere die auch nach dem beenden erhalten bleiben sollen.

Dein Problem konnte erstens an deinem Key ligen den da du uns wieder nicht deinen final aufgezeigt hat können wir das auch nicht ausschließen.
Zweitens an dem Parameter MODE_PRIVATE ich weiss jetzt nicht ob das Privatheit auf die activity oder die App bezogen ist.

Hilfreich?
Manu Schmidt
Kommentieren
Manu Schmidt
  • Forum-Beiträge: 12

30.09.2018, 10:27:17 via Website

Habs hinbekommen!
Es waren tatsechlich die Strings
Ich hatte die Strings im Fragment mit privat angegeben und das wollte er dann wohl nicht.

1000 Dank für die ganzen Tipps und die Anregungen

Besten Dank Manu

Hilfreich?
Kommentieren