510 likes | 565 Views
Android Programming Lecture 7. Data Persistence. What is Persistence?.
E N D
Android Programming Lecture 7 Data Persistence
What is Persistence? Persistence is “the continuance of an effect after its cause is removed”. In the context of storing data in a computer system, this means that the data survives after the process with which it was created has ended. In other words, for a data store to be considered persistent, it must write to non-volatile storage.
Saving Data in Android • App data is private to the application • Internal Storage: Store data on the device memory temporarily • Shared Preferences: Lightweight mechanism to store private primitive data in key-value pairs in hard drive • File: Open and save files on the device or removable storage • SQLite Database: Store structured data in a private database • Network Connection: Store data on the web • Content providerisusedtogivethedatatootherapps
Passing Temporal Data using Intent Intent intent = newIntent(Activity1.this, Activity2.class); Bundle data = new Bundle(); data.putString("key_name", "name"); data.putString("key_age", "age"); intent.putExtras(data); intent.putExtra("key_id", "id"); intent.putExtra("key_address", "address"); startActivity(intent); Activity 1 Intent Activity 2 // In Activity2.java // Retrieve the intent Intent intent = getIntent(); // Retrieve the string data in the intent String name = intent.getStringExtra("key_name"); String age = intent.getStringExtra("key_age"); String id = intent.getStringExtra("key_id"); String address = intent.getStringExtra("key_address");
Data Persistence in Orientation • When screenrotationischanged, theactivityisdestroyedandopenedagain • How to store state information • Store state: – onSaveInstanceState(Bundle) • Read state: – onRestoreInstanceState(Bundle) • This willstoredataonlytemporarilyforapplifetime! • Datawillbeheldinmemoryuntil theappisclosed! Refer to the Android Developer Site: http://developer.android.com/training/basics/activity-lifecycle/recreating.html
Saving Data in Android • Internal Storage • Shared Preferences • File • SQLite Database • Network Connection
Shared Preferences • The SharedPreferences interface (in package android.content) provides a general framework that allows you to save and retrieve persistent key-value pairs of primitive data types and strings. • similar to saving data in a Bundle • Can be used to save the following data types • Boolean – float • int – long • String − Set<String> • Shared preference data will persist across user sessions even if the application is killed.
publicclassExample extends Activity { // Create a preference file with the name specified publicstaticfinal String PREFS_NAME = "MyPrefsFile"; @Override protectedvoidonCreate(Bundle state){ super.onCreate(state); . . . // Restore the preferences // Get the preference with the name specified SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); // Read the stored data from the preference int data = settings.getInt(“key", defaultValue); . . . } @Override protectedvoidonStop(){ super.onStop(); // Store the preferences // We need an Editor object to make preference changes. SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putInt(“key”, value); // Commit the edits! editor.commit(); } }
Overview of Shared Preferences • Examples of data stored in shared preferences: • user name – password • email address – high score • An application can have multiple sets of application preferences, where each set has a name. • Preferences can be stored at the activity level or the application level. In general, they are not shared outside the application. • Application preferences are stored in XML files in the Android file system as follows: /data/data/<package name>/shared_prefs/<pref filename>.xml
Obtaining a SharedPreferences Object Two methods that return a SharedPreferences object: • getSharedPreferences(String name, int mode) • Use if you need multiple preferences files identified by name. • Name is specified as the first parameter. • If a preferences file by this name does not exist, it will be created when you retrieve an editor. • Preferences can be accessed by all activities in the application. • getPreferences(int mode) • Use if you need only one preferences file for your Activity. • Only one preferences file for an Activity – don't supply a name. • Calls method getSharedPreferences(String, int) passing in this activity’s class name as the preferences name. • Preferences are not shared with other activities in the application.
Shared Preference Modes • getSharedPreferences(String name, int mode) • getPreferences(int mode) • Context.MODE_PRIVATE(or 0) • created file can be accessed only by the calling application • generally the only preference mode that you should use • Context.MODE_WORLD_READABLE (or 1, deprecated in API level 17) • other applications have read access to the created file • Context.MODE_WORLD_WRITEABLE (or 2, deprecated in API level 17) • other applications have write access to the created file Context Class Reference: http://developer.android.com/reference/android/content/Context.html
Writing Shared Preferences • To write shared preference values: • Call edit()to get a SharedPreferences.Editor. • Add values with editor “put” methods such as putBoolean()and putString(). • Commit the new values with apply()or commit(). // Store the preferences // We need an Editor object to make preference changes. SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putInt(“key”, value); // Commit the edits! editor.commit();
Reading Shared Preferences • To read shared preference values: • Use SharedPreferences “get” methods such as getBoolean(String key, booleandefValue)and getString(String key, String defValue). • The “get” methods have two parameters • key: the preference key string • defValue: a default value to return if the preference is undefined // Restore the preferences // Get the preference with the name specified SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); // Read the stored data from the preference int data = settings.getInt(“key", defaultValue);
Selected Methods forRetrieving Shared Preferences // in interface SharedPreferences booleangetBoolean(String key, booleandefValue) float getFloat(String key, float defValue) intgetInt(String key, intdefValue) long getLong(String key, long defValue) String getString(String key, String defValue) Set<String> getStringSet(String key, Set<String> defValues) SharedPreferences Class References: http://developer.android.com/reference/android/content/SharedPreferences.html
Selected Methods forSaving Shared Preferences // in interface SharedPreferences.Editor void apply() boolean commit() SharedPreferences.EditorputBoolean(String key, boolean value) SharedPreferences.EditorputFloat(String key, float value) SharedPreferences.EditorputInt(String key, int value) SharedPreferences.EditorputLong(String key, long value) SharedPreferences.EditorputString(String key, String value) SharedPreferences.EditorputStringSet(String key, Set<String> values)SharedPreferences.Editor remove(String key) SharedPreferences Class References: http://developer.android.com/reference/android/content/SharedPreferences.html
Differences Between Methodsapply() and commit() • boolean commit() • Returns a boolean value to indicate if the new values were successfully written to persistent storage. • Writes its preferences out to persistent storage synchronously (can block the UI thread) • void apply() • Commits its changes to the in-memory SharedPreferences immediately but starts an asynchronous commit to disk. • does not block the UI thread, but you won’t be notified of any failures. Use apply() if you don't care about the return value and you’re using this from your application’s UI thread. http://developer.android.com/reference/android/content/SharedPreferences.Editor.html
publicclassExample extends Activity { // Create a preference file with the name specified publicstaticfinal String PREFS_NAME = "MyPrefsFile"; @Override protectedvoidonCreate(Bundle state){ super.onCreate(state); . . . // Restore the preferences // Get the preference with the name specified SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); // Read the stored data from the preference int data = settings.getInt(“key", defaultValue); . . . } @Override protectedvoidonStop(){ super.onStop(); // Store the preferences // We need an Editor object to make preference changes. SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putInt(“key”, value); // Commit the edits! editor.commit(); } }
Android Debugging • ADB (Android Debug Bridge) • A versatile command line tool that lets you communicate with an emulator instance or connected Android-powered device • You can find the adb tool in <sdk>/platform-tools • Device management, moving and syncing files to the emulator (or device), running a UNIX shell on the device or emulator, interacting with SQLite database for an application. • DalvikDebug Monitor Server (DDMS) • Graphical program that communicates with your devices through the ADB. • Capture screenshots, gather thread and stack information, monitor heap, spoof incoming calls and SMS messages, etc. Intro to ADB: http://developer.android.com/tools/help/adb.html
Saving Data in Android • Internal Storage • Shared Preferences • File • SQLite Database • Network Connection
Storage • Internal storage − for private data • By default, files saved to the internal storage are private to your application and other applications cannot access them. • When the user uninstalls an application, files and directories created by that application in internal storage are removed. • External storage − for public shared data • Every Android-compatible device supports a shared “external storage” that can be used to save files. • External storage can be • a removable storage media (such as an SD card) • an internal (non-removable) storage. • Files saved to the external storage are world-readable and can be modified by the user when they enable USB mass storage to transfer files on a computer. Saving Files: http://developer.android.com/training/basics/data-storage/files.html
// Write String FILENAME = “custom_file.txt"; String fileContent= “This is a test!"; // Create a file to write // Two parameters are passed, file name and mode FileOutputStreamfos = openFileOutput(FILENAME, Context.MODE_PRIVATE); fos.write(fileContent.getBytes()); fos.close(); // Read FileInputStreamfis = openFileInput(FILENAME); intbyteChar; while((byteChar = fis.read()) != -1) { System.out.println((char) byteChar); } fis.close()
Using Java I/O for Data Storage • The standard Java I/O capabilities provided in package java.io can be used to read and write data files on an Android device’s internal and external storage. • Android provides several helper methods inherited from android.content.Context that can be used access files on the device. • Application files are saved in the folder /data/data/<package name>/files • DDMS can be used to explore a device’s file system and to transfer files between a computer and an Android device.
Get Access to External Storage • In order to read or write files on the external storage, your app must acquire the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE system permissions. • For example <manifest ...> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ... </manifest>
Helper Methods Inherited Fromandroid.content.Context • FileInputStreamopenFileInput(String name) • Open a private file for reading. • FileOutputStreamopenFileOutput(String name,int mode) • Open a private file for writing or appending. • File getFilesDir() • Get the absolute path to the file system directory where your internal files are saved (i.e., returns a File object for/data/data/<package name>/files/). • File getDir(String name, int mode) • Create (or open an existing) directory within your internal storage space.
Helper Methods Inherited Fromandroid.content.Context • booleandeleteFile(String name) • Delete the given private file associated with this application. • Returns true if the file was successfully deleted; otherwise returns false. • String[] fileList() • Returns an array of strings naming the private files associated with this application.
File Modes FileOutputStreamopenFileOutput(String name, int mode) (Open a private file for writing or appending.) Selected file modes from android.content.Context • MODE_APPEND • If the file already exists, then write data to the end of the existing file instead of erasing it. • MODE_PRIVATE • Created file can only be accessed by the calling application (default mode). • MODE_WORLD_READABLE (deprecated in API level 17) • Allow all other applications read access to the created file. • MODE_WORLD_WRITEABLE (deprecated in API level 17) • Allow all other applications write access to the created file.
Saving Data in Android • Internal Storage • Shared Preferences • File • SQLite Database • Network Connection
SQLite • SQLite is a software library that implements a lightweightSQL database engine. • SQLite is the most widely deployed SQL database engine in the world. • SQLite is an Open Source Database which is embedded into Android. • SQLite is available on every Android device, does not require any database setup or administration. • You only have to define the SQL statements for creating and updating the database.
SQLite • SQLite has the following features: • Database-in-a-file • Self-contained • Serverless • Zero-configuration • Concurrent access • Open source
Intro to Database • What is a database? • An organized collection of data • Database Operations • Insert, delete, query, update data in database • Integer • Data Type • Text (String) • Integer
Table • The data stored in database objects are called tables • Every table is broken up into smaller entities called fields • The table is a collection of related data entries and it consists of columns and rows. +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2000.00 | | 2 | Khilan | 25 | Delhi | 1500.00 | | 3 | kaushik | 23 | Kota | 2000.00 | | 4 | Chaitali | 25 | Mumbai | 6500.00 | | 5 | Hardik | 27 | Bhopal | 8500.00 | | 6 | Komal | 22 | MP | 4500.00 | | 7 | Muffy | 24 | Indore | 10000.00 | +----+----------+-----+-----------+----------+ +-----------+ | ADDRESS | +-----------+ | Ahmedabad | | Delhi | | Kota | | Mumbai | | Bhopal | | MP | | Indore | +----+------+ +----+----------+-----+--------+----------+ | 5 | Hardik| 27 | Bhopal | 8500.00 | +----+----------+-----+--------+----------+
SQL Syntax: Create a Table CREATE TABLE CUSTOMERS( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, ADDRESS CHAR (25) , SALARY DECIMAL (18, 2), PRIMARY KEY (ID) ); CREATE TABLE table_name( column1 datatype, column2 datatype, column3 datatype, ..... columnNdatatype, PRIMARY KEY( one or more columns ) ); +---------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+---------------+------+-----+---------+-------+ | ID | int(11) | NO | PRI | | | | NAME | varchar(20) | NO | | | | | AGE | int(11) | NO | | | | | ADDRESS | char(25) | YES | | NULL | | | SALARY | decimal(18,2) | YES | | NULL | | +---------+---------------+------+-----+---------+-------+
CUSTOMERS table +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2000.00 | | 2 | Khilan | 25 | Delhi | 1500.00 | | 3 | kaushik | 23 | Kota | 2000.00 | | 4 | Chaitali | 25 | Mumbai | 6500.00 | | 5 | Hardik | 27 | Bhopal | 8500.00 | | 6 | Komal | 22 | MP | 4500.00 | | 7 | Muffy | 24 | Indore | 10000.00 | +----+----------+-----+-----------+----------+ WHERE Clause SELECT column1, column2, columnN FROM table_name WHERE [condition] +----+----------+----------+ | ID | NAME | SALARY | +----+----------+----------+ | 4 | Chaitali | 6500.00 | | 5 | Hardik | 8500.00 | | 6 | Komal | 4500.00 | | 7 | Muffy | 10000.00 | +----+----------+----------+ • Fetch ID, Name and Salary fields from the CUSTOMERS table where salary is greater than 2000: SELECT ID, NAME, SALARY FROM CUSTOMERS WHERE SALARY > 2000; • Fetch ID, Name and Salary fields from the CUSTOMERS table for a customer with name Hardik +----+----------+----------+ | ID | NAME | SALARY | +----+----------+----------+ | 5 | Hardik | 8500.00 | +----+----------+----------+ SELECT ID, NAME, SALARY FROM CUSTOMERS WHERE NAME = 'Hardik'; http://www.tutorialspoint.com/sql/sql-where-clause.htm
SQLiteDatabase Class • Exposes methods to manage a SQLite database. • SQLiteDatabase has methods to create, delete, execute SQL commands, and perform other common database management tasks. • void execSQL(String sql): Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data • Cursor query(...): Query the given table, returning a Cursor over the result set
Example Android: SQL Syntax: • void execSQL(“CREATE TABLE CUSTOMERS( • ID INT NOT NULL, • NAME VARCHAR (20) NOT NULL, • AGE INT NOT NULL, • ADDRESS CHAR (25) , • SALARY DECIMAL (18, 2), • PRIMARY KEY (ID) • )”): CREATE TABLE CUSTOMERS( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, ADDRESS CHAR (25) , SALARY DECIMAL (18, 2), PRIMARY KEY (ID) ); +---------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+---------------+------+-----+---------+-------+ | ID | int(11) | NO | PRI | | | | NAME | varchar(20) | NO | | | | | AGE | int(11) | NO | | | | | ADDRESS | char(25) | YES | | NULL | | | SALARY | decimal(18,2) | YES | | NULL | | +---------+---------------+------+-----+---------+-------+
Class SQLiteOpenHelper • Class SQLiteOpenHelper is an abstract helper classin package android.database.sqlite that can be used to manage database creation and versioning. • Class SQLiteOpenHelper will • open the database if it exists • create the database if it does not exist • upgrade the database as necessary • To use class SQLiteOpenHelper, create a subclass that overrides abstract methods onCreate(), onUpgrade(). Note: Database names must be unique within an application, not across all applications.
Selected Methods in ClassSQLiteOpenHelper • SQLiteOpenHelper(Context context, String name,SQLiteDatabase.CursorFactory factory,int version) • constructor to initialize a SQLiteOpenHelper object • the factory parameter can be null for the default value • void close() • close an open database • SQLiteDatabasegetReadableDatabase() • create and/or open a database for reading only • SQLiteDatabasegetWritableDatabase() • create and/or open a database for both reading and writing
Selected Methods in ClassSQLiteOpenHelper • abstract void onCreate(SQLiteDatabase db) • called when the database is created for the first time Note: You can “preload” a set of database values in this method. • void onOpen(SQLiteDatabase db) • called when the database is opened • abstract void onUpgrade(SQLiteDatabase db,intoldVersion, intnewVersion) • called when the database needs to be upgraded
Class SQLiteDatabase • Class SQLiteDatabase (in package android.database.sqlite) exposes methods to manage a SQLite database. • Class SQLiteDatabase has methods to create, delete, execute SQL commands, and to perform other common database management tasks. • Class SQLiteDatabase has several “convenience” methods for constructing SQL queries, inserts, etc. Alternatively, other methods can be used to directly execute SQL commands passed as string parameters.
Selected Methods in ClassSQLiteDatabase • void beginTransaction() • Begins a transaction. • int delete(String table, String whereClause, String[] whereArgs) • Convenience method for deleting rows in the database. • void endTransaction() • End a transaction. • void execSQL(String sql) • Execute a single SQL statement that does not return data. • long insert(String table, StringnullColumnHack, ContentValues values) • Convenience method for inserting a row into the database.
Selected Methods in ClassSQLiteDatabase • Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) • Query the given table, returning a Cursor over the result set. • Cursor rawQuery(String sql, String[] selectionArgs) • Runs the provided SQL and returns a Cursor over the result set. • int update(String table, ContentValues values, String whereClause, String[] whereArgs) • Convenience method for updating rows in the database.
Interface Cursor • Interface Cursor (in package android.database) is used to iterate over the rows returned by a “select” query. • Interface Cursor provides random read-write access to the result set returned by a database query. • Methods in interface Cursor can be used • to position the cursor within the result set (“move” methods) • to retrieve column values from the row (“get” methods) • to provide metadata about the query (e.g., getColumnNames()).
Selected Methods in Interface Cursor • intgetColumnIndex(String columnName) • Returns zero-based index for the given column name • double getDouble(intcolumnIndex) • intgetInt(intcolumnIndex) • long getLong(intcolumnIndex) • String getString(intcolumnIndex) • boolean move(int offset) • booleanmoveToFirst() • booleanmoveToNext() • booleanmoveToPosition(int position) • Returns the value • of the requested • column as the • specified type. • Moves the cursor • as specified.
Using a Cursor • Initially a cursor is positioned before the first row. The various “move” methods can be used to move the cursor to a row. • The moveToNext() method moves the cursor to the next row. Since it returns false when there are no more rows, it can be used in a while loop to iterate through the rows of a cursor. • Example while (cursor.moveToNext()) { ... // retrieve/process data for one row } Cursor
Cursor Cursor Cursor Cursor Cursor Cursor Cursor
Summary • What is purpose of data persistence? • Why would the data persistence be an issue when user changes the orientation in the app? • What can SharedPreferences class do? • How to write data into an SharedPreferences object? • How to read data from an SharedPreferences object? • What is the usage of SQLiteOpenHelperclass?
Video Tutorial • Android Studio Tutorial for Beginners (Step by Step tutorial) • https://www.youtube.com/playlist?list=PLS1QulWo1RIbb1cYyzZpLFCKvdYV_yJ-E • Topics on Android SQLite Database Tutorial