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

Android und ResourceBundle

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von leder, 12.02.2010.

  1. leder, 12.02.2010 #1
    leder

    leder Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    09.02.2010
    Phone:
    Motorola Milestone
    Hallo,

    ich programmiere ein HelloWorld namens GPS.java. GPS.java für Android funktioniert auf dem Emulator. Aber wenn ich versuche ein ResourceBundle (s. TODO) mit Namen settings.properties einzulesen bekomme ich ein "Sorry! ..." im Emulator. Ich habe die Datei traces.txt gesichert, s. Anhang.

    Die Exceptions sagen mir nichts und auch wenn ich den DDMS anwerfe, springt der Debugger immer direkt in irgendwelche Bibiliotheksklassen ohne Sourcen... :confused:

    Hat jemand einen Tipp?

    Hier mein GPS.java

    Code:
    package net.learn2develop.GPS;
    
    import java.util.ResourceBundle;
    
    import android.app.Activity;
    import android.content.Context;
    import android.location.Location;
    import android.location.LocationListener;
    import android.location.LocationManager;
    import android.os.Bundle;
    import android.widget.Toast;
    
    public class GPS extends Activity 
    {
        private LocationManager lm;
        private LocationListener locationListener;
    	private ResourceBundle settings;
    	private int mTourId;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main); 
            
    //TODO:
            settings =
    	    ResourceBundle.getBundle("settings");
    	String value = settings.getString("TourId");
    	mTourId = Integer.parseInt(value);
    ///////        
    
            //---use the LocationManager class to obtain GPS locations---
            lm = (LocationManager) 
                getSystemService(Context.LOCATION_SERVICE);    
            
            locationListener = new MyLocationListener();
            
            lm.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, 
                0, 
                0, 
                locationListener);        
        }
        
        private class MyLocationListener implements LocationListener 
        {
            @Override
            public void onLocationChanged(Location loc) {
                if (loc != null) {
                    Toast.makeText(getBaseContext(), 
                        "Location changed : Lat: " + loc.getLatitude() + 
                        " Lng: " + loc.getLongitude(), 
                        Toast.LENGTH_SHORT).show();
                }
            }
    
            @Override
            public void onProviderDisabled(String provider) {
                // TODO Auto-generated method stub
            }
    
            @Override
            public void onProviderEnabled(String provider) {
                // TODO Auto-generated method stub
            }
    
            @Override
            public void onStatusChanged(String provider, int status, 
                Bundle extras) {
                // TODO Auto-generated method stub
            }
        }        
        
    }
     

    Anhänge:

  2. garak, 12.02.2010 #2
    garak

    garak Ehrenmitglied

    Beiträge:
    8,270
    Erhaltene Danke:
    4,794
    Registriert seit:
    12.12.2009
    Ich verstehe nicht ganz, wozu du eine settings.properties aufrufen willst.
    Das SDK hat seine eigenen Regeln für Properties, da wird alles in Dateien mit der Endung .xml abgelegt, funktioniert letztendlich jedoch genauso.
    Vielleicht kannst du mal näher erläutern was der Zweck sein soll.

    Gruß
    Chris

    Nachtrag: Nachdem ich einen Blick auf deinen Sourcecode geworfen habe, ist es klar:

    Also, im Verzeichnis "res/values" kannst du Xml-Dateien z.B. string.xml anlegen. Dort hinterlegst du alle Texte der Default-Sprache, nämlich Englisch. Möchtest du zusätzlich auch die deutsche Sprache oder eine andere unterstützen, dann erstellt du ein Verzeichnis "res/values_de". In dieses Verzeichnis hinterlegst du ebenfalls eine Datei, in diesem Fall string.xml.

    Um jetzt in deinem Programm auf die Werte zugreifen zu können, einfach "getString(R.string.das_ist _der_Bezeichner)" eingeben und fertig. Je nachdem was der Benutzer hinterher für eine Sprache auf seinem Gerät eingestellt hat, bekommt er entweder die Resource aus Default oder der eingestellten Sprache zu sehen. Für alle Werte für die es keine Sprachübersetzung gibt, wird auch immer der Defaultwert genommen.
     
    Zuletzt bearbeitet: 12.02.2010
    leder bedankt sich.
  3. leder, 12.02.2010 #3
    leder

    leder Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    09.02.2010
    Phone:
    Motorola Milestone
    Hab jetzt die xml Datei gefunden und in res/values/strings.xml den Wert tourId=3 angelegt.

    Ich möchte über den App Lifecycle hinaus einen Wert ein und auslesen können!

    Jetzt kann ich auf die Variable zugreifen mit:

    Code:
    		settings = getResources();
    		    
    		String value = settings.getString(R.string.tourId);
    		mTourId = Integer.parseInt(value);
    	//	Toast.makeText(getBaseContext(), "TourId: "+ mTourId, Toast.LENGTH_LONG).show();
    	
    
    Danke für den Tipp!

    Nachtrag:

    jetzt fehlt mir aber um die Resource aus dem Programm heraus zu verändern ein:
    Code:
    settings.setString(...)
     
    Zuletzt bearbeitet: 12.02.2010
  4. garak, 12.02.2010 #4
    garak

    garak Ehrenmitglied

    Beiträge:
    8,270
    Erhaltene Danke:
    4,794
    Registriert seit:
    12.12.2009
    Dafür stehen dir die Shared Preferences zur Verfügung.

    Um einen Wert zu speichern:
    Code:
    SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
    editor.putString(MEINE_VALUE, "blah blah");
    
    Um ihn wieder einzulesen:
    Code:
    SharedPreferences prefs = getPreferences(MODE_PRIVATE);
    String blahblah = prefs.getString(MEIN_VALUE, "Default Wert")
    Du kannst auch Werte Applikationsübergreifend speichern, wenn du den Modus entsprechend änderst.

    Gruß
    Chris
     
    leder bedankt sich.
  5. SeraphimSerapis, 12.02.2010 #5
    SeraphimSerapis

    SeraphimSerapis Android-Guru

    Beiträge:
    3,072
    Erhaltene Danke:
    1,138
    Registriert seit:
    27.02.2009
    Geht auch so sehr gut: SharedPreferences xy = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
     
  6. leder, 12.02.2010 #6
    leder

    leder Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    09.02.2010
    Phone:
    Motorola Milestone
    Danke Chris,

    wenn die App läuft kann ich jetzt Werte lesen und schreiben. Wenn ich die App beende und neu starte wird der letzte geschrieben Wert nicht gespeichert. Ich such so etwas wie eine "properties" Datei in die ich auch persistent schreiben kann.

    Viele Grüße
    Gerrit
     
  7. garak, 12.02.2010 #7
    garak

    garak Ehrenmitglied

    Beiträge:
    8,270
    Erhaltene Danke:
    4,794
    Registriert seit:
    12.12.2009
    Diese Werte sind persistent und ich nutze sie um z.B. aktuelle Eingaben bei einer Pause (z.B. Telefon klingelt) zu sichern. Also über "onPause" die Werte aller Eingabefelder sichern und mittels "onResume" wieder herstellen.

    Da diese Funktionen auch beim Starten und Beenden aufgerufen werden, setze ich mir im "onCreate" ein Flag und kann dadurch alles abwicklen.
     
    leder bedankt sich.
  8. garak, 12.02.2010 #8
    garak

    garak Ehrenmitglied

    Beiträge:
    8,270
    Erhaltene Danke:
    4,794
    Registriert seit:
    12.12.2009
    Hat jedoch den Nachteil, dass du nicht verschiedene Blöcke und instanzübergreifend speichern kannst.

    Gruß
    Chris
     
  9. leder, 12.02.2010 #9
    leder

    leder Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    09.02.2010
    Phone:
    Motorola Milestone
    Danke all!

    Jetzt funktioniert es wie erwartet auch über das Ende der Applikation hinaus.
    Habe noch eine Ergänzung nach dem schreiben gemacht:
    Code:
    editor.commit();
    :D
     
  10. garak, 12.02.2010 #10
    garak

    garak Ehrenmitglied

    Beiträge:
    8,270
    Erhaltene Danke:
    4,794
    Registriert seit:
    12.12.2009
    Ja klar, komitten muss natürlich immer ;)
     
  11. leder, 04.03.2010 #11
    leder

    leder Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    09.02.2010
    Phone:
    Motorola Milestone
    Noch eine Frage zu Bundle ist aufgetaucht:

    Wenn ich die Applikation beende möchte ich ein anderes Verhalten haben, als bei z.B. einer Unterbrechung durch Telefonklingeln.

    Dafür ruft onSaveInstanceState (Bundle outstate) meine Routine saveInstance(Bundle outstate) auf:

    Code:
    	private void saveInstance(Bundle outState) {
    	Log.d(TAG, "saveInstance(Bundle) called");
    	if (outState != null) {
    		outState.putInt("tourId", ++mTourId);
    		setResult(RESULT_OK);
            finish();
    			
    		}
    	}
    Aber der Log Eintrag fehlt: saveInstance wird bei einem Stop des Emulators-Threads nie aufgerufen!

    Der umgekehrte Fall sieht, der Vollständigkeit halber, so aus, dass onCreate() restoreInstance(Bundle savedInstanceState) aufruft, was auch in dem LogCat erscheint:

    Code:
    	private void restoreInstance(Bundle savedInstanceState) {
    		Log.d(TAG, "restoreInstance(Bundle) called");
    		if (savedInstanceState != null) {
    		mTourId = savedInstanceState.getInt("tourId");
    		}
    	}
    
    
    Weiterhin ist Bundle savedInstanceState==null, bei jedem neuen Programmstart!

    Wie bekomme ich ein sauberes herunterfahren der Applikation mit speichern der Member-Variablen mTourId hin? Und wie teste ich das im Emulator?

    Vielen Dank im voraus
    Gerrit
     

Diese Seite empfehlen