Version 2.5
Copyright © 2010, 2011, 2012 Lars Vogel
16.04.2012
| Revision History | ||
|---|---|---|
| Revision 0.1 | 05.09.2010 | Lars Vogel |
| Created | ||
| Revision 0.2 - 2.5 | 21.09.2010 - 16.04.2012 | Lars Vogel |
| bugfixes and enhancements | ||
Table of Contents
Android allows to store local data as files. Android uses file based storage for handling application settings (Preferences) and instances of the SQLite database.
For each application the Android system creates a "data/data/package.of.the.application" directory.
Files are saved in the "files" folder and application settings are saved as XML files in the "shared_prefs" folder.
If your application creates an SQLite database this database is saved in the main application directory under the "databases" folder.
The following screenshot shows a filesystem which contains file, cache files and preferences.

Only the application can write into its application directory. It can create additional subdirectories in this application directory. For these subdirectories, the application can grant read or write permissions for other applications.
Android has internal storage and external storage. External storage is not private and may not always be available.
As of Android 8 it is possible to define that the application
can or
should be placed on external storage. For this set the
android:installLocation
to preferExternal or auto.
In this case certain application components may be stored on an encrypted external mount point. Database and other private data will still be stored in the internal storage system.
Android supports the usage of Preferences to allow you to save data for your application. Preferences are stored as key values. The definition of Preferences can also be done via an XML resource.
The
PreferenceManager
gives access to the preference values. The following code snippets
shows how to access your default preferences.
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Values can get accessed via the key of the preference setting.
String username = preferences.getString("username", "n/a");
To create or change preferences you have to call the edit()
method on
the
SharedPreferences
object. Once you have changed the value you have to call the
commit()
to
apply your changes.
Editor edit = preferences.edit(); edit.putString("username", "new_value_for_user"); edit.commit();
Android provides the
PreferenceActivity
class which extends the
Activity
class.
PreferenceActivity
supports the simple handling of
preferences. It can load a preference
definition resources
via the method
addPreferencesFromResource().
To
communicate between different components Android uses
Intents.
Typically the
PreferenceActivity
is started from another
Activity
via
an
Intent.
You can listen to changes in the preferences via the
registerOnSharedPreferenceChangeListener()
method on
SharedPreferences.
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(this);
// Instance field for listener
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// Your Implementation
}
};
prefs.registerOnSharedPreferenceChangeListener(listener);
One watch out is that
SharedPreferences
keeps listeners in a
WeakHashMap
hence listener may be recycled if your code does not hold a reference
to it.
.
The following tutorial is based on the "de.vogella.android.socialapp" example from Android ActionBar Tutorial .
We will continue using the example project "de.vogella.android.social".
Create an Android XML resource "preferences.xml" of type "PreferenceScreen".

Open the file via right-mouse click and → . Press Add, add a "PreferenceCategory" and add two preferences "EditTextPreferences" to this category : "User" and "Password".



You can also enter values for other properties of
EditTextField, e.g. the inputMethod.
Add the following attribute to
the
XML definition of your
password field
to make the input quoted with
*.
android:inputType="textPassword"
Create the class
MyPreferencesActivity
which extends
PreferenceActivity. This
Activity
will load the "preference.xml" file and will allow the user to change
the values.
package de.vogella.android.socialapp; import android.os.Bundle; import android.preference.PreferenceActivity; public class MyPreferencesActivity extends PreferenceActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } }
To make this class available as an activity for Android you need to register it in your "AndroidManifest.xml" file. Select "AndroidManifest.xml" and the tab "Application". Scroll to the botton of the view and add your new activity via the button.

To make use of our new preference activity and the preference values we adjust the "OverviewActivity". The first button will show the current values of the preferences via a Toast and the second button will revert the maintained user name to demonstrate how you could change the preferences via code.
package de.vogella.android.socialapp; import android.app.Activity; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class OverviewActivity extends Activity { SharedPreferences preferences; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button) findViewById(R.id.Button01); // Initialize preferences preferences = PreferenceManager.getDefaultSharedPreferences(this); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { String username = preferences.getString("username", "n/a"); String password = preferences.getString("password", "n/a"); showPrefs(username, password); } }); Button buttonChangePreferences = (Button) findViewById(R.id.Button02); buttonChangePreferences.setOnClickListener(new OnClickListener() { public void onClick(View v) { updatePreferenceValue(); } }); } private void showPrefs(String username, String password){ Toast.makeText( OverviewActivity.this, "Input: " + username + " and password: " + password, Toast.LENGTH_LONG).show(); } private void updatePreferenceValue(){ Editor edit = preferences.edit(); String username = preferences.getString("username", "n/a"); // We will just revert the current user name and save again StringBuffer buffer = new StringBuffer(); for (int i = username.length() - 1; i >= 0; i--) { buffer.append(username.charAt(i)); } edit.putString("username", buffer.toString()); edit.commit(); // A toast is a view containing a quick little message for the // user. We give a little feedback Toast.makeText(OverviewActivity.this, "Reverted string sequence of user name.", Toast.LENGTH_LONG).show(); }
To open the new preference
Activity
we will use the
onOptionsItemSelected()
method. Even though we currently have only one option in our
menu we
use a switch to be ready for several new menu
entries. To see the
current values of the preferences we
define a button and use the class
PreferenceManager
to get the sharedPreferences.
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.mainmenu, menu); return true; } // This method is called once the menu is selected @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // We have only one menu option case R.id.preferences: // Launch Preference activity Intent i = new Intent(OverviewActivity.this, MyPreferencesActivity.class); startActivity(i); // Some feedback to the user Toast.makeText(OverviewActivity.this, "Enter your user credentials.", Toast.LENGTH_LONG).show(); break; } return true; }
Run your application. Press the "menu" hardware button and then select your menu item "Preferences". You should be able to enter your user settings then press the back hardware button to return to your main activity. The saved values should be displayed in a small message windows (Toast) if you press your first button. If you press the second button the username should be reversed.

Access to the file system is performed via the standard
java.io
classes.
Android provides also helper classes for creating and
accessing new
files and directories.
For example the
getDir(String, int)
method
would create or
access a directory. The
openFileInput(String s)
method
would
open
a file for input
and
openFileOutput(String s, int)
would
create a
file.
int specifies the permissions which are:
MODE_PRIVATE - No access for other applications
MODE_WORLD_READABLE - Read access for other applications
MODE_WORLD_WRITABLE - Write access for other applications
MODE_WORLD_READABLE | MODE_WORLD_WRITABLE - Read / Write access
The following example shows the API usage.
private void writeFileToInternalStorage() { String eol = System.getProperty("line.separator"); BufferedWriter writer = null; try { writer = new BufferedWriter(new OutputStreamWriter(openFileOutput( "myfile", MODE_WORLD_WRITEABLE))); writer.write("This is a test1." + eol); writer.write("This is a test2." + eol); } catch (Exception e) { e.printStackTrace(); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }
private void readFileFromInternalStorage() { String eol = System.getProperty("line.separator"); BufferedReader input = null; try { input = new BufferedReader(new InputStreamReader( openFileInput("myfile"))); String line; StringBuffer buffer = new StringBuffer(); while ((line = input.readLine()) != null) { buffer.append(line + eol); } } catch (Exception e) { e.printStackTrace(); } finally { if (input != null) { try { input.close(); } catch (IOException e) { e.printStackTrace(); } } } }
Another application can access a file, which has been created with
the
MODE_WORLD_READABLE
model.
For this, it need to knows the package and file name. The
following
example shows this.
FileInputStream openFileInput = createPackageContext( "the_package", 0).openFileInput("thefile");
Android supports also access to an external storage system e.g. the SD card. All files and directories on the external storage system are readable for all applications.
To
write to
the external storage system your application needs the
android.permission.WRITE_EXTERNAL_STORAGE
permission. You get the path to the
external storage system via the
Environment.getExternalStorageDirectory()
method.
Via the following method call you can check the state of the external storage system. If the Android device is connected via USB to a computer, a SD card which might be used for the external storage system is not available.
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
The following shows an example for reading from the external storage system.
private void readFileFromSDCard() { File directory = Environment.getExternalStorageDirectory(); // Assumes that a file article.rss is available on the SD card File file = new File(directory + "/article.rss"); if (!file.exists()) { throw new RuntimeException("File not found"); } Log.e("Testing", "Starting to read"); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(file)); StringBuilder builder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { builder.append(line); } } catch (Exception e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.
Eclipse RCP Training (German) Eclipse RCP Training with Lars Vogel
Android Tutorial Introduction to Android Programming
GWT Tutorial Program in Java and compile to JavaScript and HTML
Eclipse RCP Tutorial Create native applications in Java
JUnit Tutorial Test your application
Git Tutorial Put everything you have under distributed version control system