Eng. Jaffer M. El-Agha Android Programing Discussion Islamic University of Gaza Data persistence
Shared preferences A method to store primitive data in android as key-value pairs, these saved data will be located at somewhere in the app, and it will be available after the app killed. Note: you can use preferences in the same activity which you use, or you can use it in the overall app (Shared). To use shared preferences in your app, you can use: getsharedpreferences():used when you need multiple preferences identified by name, as its name, used to retrieve the shared preferences object, which is shared in the app, this method must takes the preferences name and mode to retrieve it. PreferenceManager.getDefaultSharedPreferences():this is like the first one, but retrieves the default shared preferences in a context, which the app creates it and assign a {packagename_preferences as a default name and PRIVATE_MODE as a default mode. So you don t need to pass a name and mode. getpreferences(): used when you need only one preferences for your activity, so you can call it only with mode parameter, without name because it have a name. How to use When you need to use shared preferences, then you need to read and write primitive values on it, so To write values you must call the editor of shared preferences, which is a class used to make edits on shared preferences, you can call it like: Editor edit = getsharedpreferences(this).edit() Then you can add and edit values using this class, for example: edit.putboolean() and so on. Note: you must save your edits by calling edit.commit().
Example: To read values you can use the shared preferences methods such getboolean() and so on. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:background="#ffffff" android:layout_height="match_parent"> <TextView android:id="@+id/tv_lastshow" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:background="@color/coloraccent" android:textcolor="#ffffff" android:padding="8dp" android:textsize="22sp" /> </RelativeLayout> public class MainActivity extends Activity { String FILE_NAME = "storage"; String LAST_SHOW = "lastshow"; SharedPreferences sp; SharedPreferences.Editor spedit; TextView tv_lastshow; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); sp = getsharedpreferences(file_name,mode_private); spedit = sp.edit(); tv_lastshow= (TextView)findViewById(R.id.tv_lastShow); tv_lastshow.settext(sp.getstring(last_show,"first time")); protected void onpause() { super.onpause(); spedit.putstring(last_show, Calendar.getInstance().getTime().toString()); spedit.commit();
Result: Internal storage Another way to save your data in your app, using it you can save your files directly at the internal storage of the device, and you can read/write as you need. This files remains alive until the app uninstalled, when the app uninstalled these files are removed. Note: no one can access these files, even the user. Example: read/write a text on file public class MainActivity extends Activity { String FILE_NAME = "file_1"; TextView tv_lastshow; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main);
tv_lastshow = (TextView) findviewbyid(r.id.tv_lastshow); FileInputStream fis = null; try { fis = openfileinput(file_name); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readline())!= null) { sb.append(line); fis.close(); tv_lastshow.settext(sb.tostring()); catch (IOException e) { e.printstacktrace(); protected void onpause() { super.onpause(); try { FileOutputStream fos = openfileoutput(file_name, Context.MODE_PRIVATE); String time = Calendar.getInstance().getTime().toString(); fos.write(time.getbytes()); fos.close(); catch (IOException e) { e.printstacktrace();
Note: you can put your file manually in assets folder or in raw folder, and read it from java code as input stream, but you can t write! Saving cash files Sometimes, you don t need to make a persistent file, for this case, you can make a temporary file (cash file), so it will be available while the internal space available, or until cash directory reaches to 1 MB. Example: cash file File f = File.createTempFile(filename, null, getcachedir()); Or File f = new File(getCacheDir(), filename); Note: when there is no available space in your app, the app may delete your cash files to gets more space. External storage Is the storage outside the application, and it is found in all devices either as internal storage (for the device itself) or external storage (SD card). In order to read/write data on external storage, you must have a permission for each operation. READ_EXTERNAL_STORAGE for read operation. WRITE_EXTERNAL_STORAGE for write operation. And as we know we will declare it in the manifest file as the following: <uses-permission android:name="android.permission.write_external_storage" /> Note: if you need to use read and write, you does not need to make two permissions, just declare write permission because it is implicitly requests read permission.
Firstly, and before using external storage, you should to check whether the media is available, readable, writable, missing, or other states, and to make this operation you can use Environment.getExternalStorageState(). Example: to check whether the media is available for reading or not. String state = Environment.getExternalStorageState(); if(state.equals(environment.media_mounted_read_only)){ // make your logic Also there are many states for external storage. Example: to make a directory in a public folder. File file = new File(Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES), "My Images"); file.mkdir(); Here I made a directory in a public pictures folder. Q) What if you want to save external files which are private to your app? By using getexternalfilesdir() for example: getexternalfilesdir(environment.directory_pictures); Which is a pictures folder that your app owns, this is means that this folder does not appear for media store content provider. If you need to show it for media store content provider, put it on public storage. Note: this type of storage after android 4.4 does not need to declare write/read permissions, because it owned by your app, so you can make the following: <uses-permission android:name="android.permission.write_external_storage" android:maxsdkversion="18" />
Saving cash files As the internal storage, you can save cash files using getexternalcashdir(). Example: the same with internal storage example Database Android provides full support of SQLite databases, so you can create your own database within the app, no one can use this database except the app classes. To create SQLite database, you should create instance of SQLiteOpenHelper and override oncreate() method, this class is a helper class to create database and manage versions. Example: this example explains overall database, more details in video. We will make a cars database to store cars, each car has a NAME and IDENTIFIER. So firstly, we will make a car object. public class Car { private int id; private String name; public Car(int id, String name) { this.id = id; this.name = name; public void setid(int id) { this.id = id; public void setname(string name) { this.name = name; public int getid() { return id; public String getname() { return name;
Now, we will create database handler to make it and handle operations. public class DBHelper extends SQLiteOpenHelper { private static final int DATABASE_VERSION = 2; private static final String DATABASE_NAME = "cars_database"; private static final String CARS_TABLE_NAME = "cars"; private static final String CARS_COLUMN_ID = "id"; private static final String CARS_COLUMN_NAME = "name"; private static final String CARS_TABLE_CREATE = "CREATE TABLE " + CARS_TABLE_NAME + " (" + CARS_COLUMN_ID + " INTEGER, " + CARS_COLUMN_NAME + " TEXT);"; public DBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); public void oncreate(sqlitedatabase db) { db.execsql(cars_table_create); public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { // put your code to upgrade, example: drop database, add columns, etc. public long insertcar(int id, String name) { SQLiteDatabase db = getwritabledatabase(); ContentValues values = new ContentValues(); values.put(cars_column_id, id); values.put(cars_column_name, name); return db.insert(cars_table_name, null, values); public Car getcar(int id) { SQLiteDatabase db = getreadabledatabase(); String[] args = {id + ""; Car car = null; Cursor c = db.rawquery("select * from " + CARS_TABLE_NAME + " where id=?", args, null); try { if (c!= null && c.movetofirst()) { car = new Car(c.getInt(c.getColumnIndex(CARS_COLUMN_ID)), c.getstring(c.getcolumnindex(cars_column_name))); catch (SQLiteException e) { e.printstacktrace(); finally { if (db!= null)
db.close(); return car; public ArrayList<Car> getcars() { SQLiteDatabase db = getreadabledatabase(); ArrayList<Car> list = new ArrayList<Car>(); Cursor c = db.rawquery("select * from " + CARS_TABLE_NAME, null); try { if (c!= null && c.movetofirst()) { do { list.add(new Car(c.getInt(c.getColumnIndex(CARS_COLUMN_ID)), c.getstring(c.getcolumnindex(cars_column_name)))); while (c.movetonext()); catch (SQLiteException e) { e.printstacktrace(); finally { if (db!= null) db.close(); return list; public long deletecar(int id) { SQLiteDatabase db = getreadabledatabase(); String[] args = {id + ""; return db.delete(cars_table_name,"id=?",args); Now, to use this database in your activity public class MainActivity extends Activity { protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); // write to database DBHelper db = new DBHelper(this); db.insertcar(1,"honda"); db.insertcar(2,"kia"); db.insertcar(3,"golf"); // read from database ArrayList<Car> list = db.getcars(); for(car c: list){ // prints three added cars, Honda, KIA, Golf Toast.makeText(this, c.getname(),
Toast.LENGTH_LONG).show(); // get specified car Car c = db.getcar(2); Toast.makeText(this,c.getName(),Toast.LENGTH_LONG).show(); // prints KIA // delete car db.deletecar(1); ArrayList<Car> l = db.getcars(); Toast.makeText(this, l.size()+"", Toast.LENGTH_LONG).show(); // prints 2 HW using the same homework of the last lab, create additional register screen to allow users to register their data (into database), then when they login, you must verify their data, and after login, the last login date time will be stored in shared preferences. Note: don t use URI for images, I want to show the image even it was deleted from gallery