Title: PowerPoint Template
1Programming with Android Data management
Luca Bedogni Marco
Di Felice Dipartimento di Scienze
dellInformazione Università di
Bologna
2Data outline
- Data Management in Android
- Preferences
- Text Files
- XML Files
- SQLite Database
- Content Provider
3Managing Data
- Preferences Key/Value pairs of data
- Direct File I/O Read/write files onboard or on
SD cards. Remember to req uest permission for
writing, for instance, on SD card - Database Tables SQL Lite
- Application Direct Access Read only access from
res assets/raw directories - Increase functionality
- Content Providers expose data to other
applications - Services background processes that run detached
from any view
4Preference system
- Preferences are a convenient way to store
configuration parameters - Structured with a key-value mode
Preference TAG
Preference VALUE
Preference TAG
Preference VALUE
Preferences
Preference TAG
Preference VALUE
Preference TAG
Preference VALUE
5Preferences types
- Preferences could be either private or shared
- Shared means that other applications could
potentially read such preferences - Private means that they could be restricted at
- Application level
- Activity level
6Preferences types
- Shared preferences
- getSharedPreferences(String name,
Context.MODE_WORLD_READABLE) - getSharedPreferences(String name,
Context.MODE_WORLD_WRITABLE) - Private at application level
- getSharedPreferences(String name,
Context.MODE_PRIVATE) - Private at activity level
- getPreferences(int mode)
7Preference example
- public void onCreate(Bundle savedInstanceState)
- Super.onCreate(savedInstanceState)
- setContentView(R.layout.main)
- SharedPreferences pref getSharedPreferences(MY_T
AG, Context.MODE_PRIVATE) - String myData pref.getString(MY_KEY, No
pref) - TextView myView (TextView)findViewById(R.id.myTe
xtView) - myView.setText(myData)
8Preferences editor
- How to edit preferences?
- You need to a SharedPreferences.Editor
- SharedPreferences.Editor editor pref.edit()
- editor.putString("mydata", et.getText().toString
()) - editor.commit()
- Be sure to commit operations at the end
9Preferences screens
- Could be defined via XML
- Some specializations to ease the process
- CheckBoxPreference
- EditTextPreference
- ListPreference
- RingtonePreference
- Create a class that extends PreferenceActivity
and call - addPreferencesFromResource(R.xml.mypreferences
)
10The Android FileSystem
- Linux architecture
- User privileges
- Quite limited
- Onboard data
- Application's reserved data
- External data
- SD card (/mnt/sdcard)
11File I/O
- Onboard
- Write to a designated place for each application
- Where? /data/data/ltpackagegt/files
- How? Use standard java I/O classes
- SD card
- Where? Environment.getExternalStorageDirectory()
- How? Use standard java I/O classes
- Permissions? android.permission.WRITE_EXTERNAL_STO
RAGE
12Raw Text Files how?
- Raw Text File
- Place it under res/raw/ directory
- Fill it with the text you like
- Populate a TextView with its content inside the
code
TextView tv (TextView)findViewById(R.id.tv_main)
tv.setText(streamToString(R.raw.myfile))
13streamToString()
private String streamToString(int id)
InputStream file getResources().openRawResou
rce(id) StringBuffer data new
StringBuffer() DataInputStream dataIO new
DataInputStream(file) String line
null try while ((line
dataIO.readLine()) ! null) data.append(line
"\n") dataIO.close() file.close()
catch (IOException e) return
data.toString()
14XML Files how?
- XML File
- Place it under res/xml/ directory
- Start the file with
- lt?xml version1.0 encodingutf-8?gt
- Add whatever you want with ltmytaggtvaluelt/mytaggt
15XML Files example
- We want to visualize all the grades of this class
- Our XML file is like this
- ltstudent
- nameStudents name
- classLaboratorio di Applicazioni Mobili
- year2012
- grade30L /gt
16XML Files code example
XmlResourceParser grades getResources().getXml(R
.xml.myxmlfile) LinearLayout ll
(LinearLayout)findViewById(R.id.myLL) int tag
-1 while (tag ! XmlResourceParser.END_DOCUMENT)
if (tag XmlResourceParser.START_TAG)
String name grades.getName() if
(name.equals("student")) TextView tv
new TextView(this) LayoutParams lp
new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT) tv.setLay
outParams(lp) String toWrite
grades.getAttributeValue(null, "name")
tv.setText(toWrite) ll.addView(tv)
try tag grades.next()
catch (Exception e)
17SQLite
- General purpose solution
- Lightweight database based on SQL
- Standard SQL syntax
- SELECT name FROM table WHERE name
Luca - Android gives a standard interface to SQL tables
of other apps - For application tables no content providers are
needed
18SQLite how?
- A database to store information
- Useful for structured informations
- Create a DBHelper which extends SQLiteOpenHelper
- Fill it with methods for managing the database
- Better to use constants like
- TABLE_GRADES
- COLUMN_NAME
- .
19SQLite example
- Our database will look like this
- grade table
- id integer, primary key, auto increment
- firstName text, not null
- lastName text, not null
- class text, not null
- grade integer, not null
20SQLite better to use constants
- Useful for query definition
- Our constants?
- private static final String DB_NAME
grades.db - private static final int DB_VERSION 1
- public static final String TABLE_GRADES
grades - public static final String COL_ID id
- public static final String COL_FIRSTNAME
firstName - public static final String COL_LASTNAME
lastName - public static final String COL_CLASS class
- public static final String COL_GRADE grade
21SQLite creation code
- Constructor call the superconstructor
- Public mySQLiteHelper(Context context)
- super(context, DB_NAME, null, DB_VERSION)
-
- onCreate(SQLiteDatabase db) create the tables
- String sql_grade create table TABLE_GRADES
( - COL_ID integer primary key autoincrement,
- COL_FIRSTNAME text not null,
- COL_LASTNAME text not null,
- COL_CLASS text not null,
- COL_GRADE text not null )
- db.execSQL(sql_grade)
22SQLite insert code
- Create a public method, like insertDb()
- mySQLiteHelper sql new mySQLiteHelper(InsertAct
ivity.this) - SQLiteDatabase db mySQLiteHelper.getWritableDat
abase() - ContentValues cv new ContentValues()
- cv.put(mySQLiteHelper.COL_FIRSTNAME, firstName)
- cv.put(mySQLiteHelper.COL_LASTNAME, flastName)
- cv.put(mySQLiteHelper.COL_FIRSTNAME, firstName)
- cv.put(mySQLiteHelper.COL_FIRSTNAME, firstName)
- long id db.insert(mySQLiteHelper.TABLE_GRADES,
null, values)
23SQLite delete code
- Create a public method, like deleteDb()
- The delete method returns the number of rows
affected - Example
- db.delete(mySQLiteHelper.TABLE_GRADES, id ?,
new String - Integer.toString(id_to_delete))
24SQLite update code
- Create a public method, like updateDb()
- ContentValues cv new ContentValues()
- values.put(mySQLiteHelper.FIRSTNAME, firstName)
- values.put(mySQLiteHelper.LASTNAME, lastName)
- db.update(mySQLiteHelper.TABLE_GRADES, values,
id ?, new String - Integer.toString(id_to_update))
25SQLite search code
- Create a public method, like getFromDb()
- Cursor gradeCursor db.query(mySQLiteHelper.TABLE
_GRADES, - new StringmySQLiteHelper.COL_GRADE,
mySQLiteHelper.COL_ID - id_to_search_for, null, null, null, null)
26Cursors handlers for data
- A Cursor stores data given by a DB query
- Some methods
- getCount()
- moveToFirst,Next,Last,Position,Previous()
- close()
- You need to look inside the Cursor to see querys
results - while (gradeCursor.moveToNext())
- Log.v(GRADES,gradeCursor.getString(0))
-
27Authorities / URI
- Purpose to publish application SQL tables and
data for external access - Where AndroidManifest.xml
- Activity access
- content//com.mycontentprovider.Provider/myTable
- content//com.mycontentprovider.Provider/myTable/m
yField
28MIME Types
- Purpose to indicate on what data a Content
Provider can operate - Syntax Two text strings separated by slashes
- First part (category) application, audio, image,
text, video ... - Second Part (codec) html, css, xml, pdf, rtf ...
- Examples text/htm, application/pdf, image/jpeg,
audio/mpeg, etc.
29Content Provider Framework
- An application registers its content provider
using its manifest - The code for the content provider is written
- Application request data using a MIME type
- Android looks through the registered manifests
for an appropriate provider - The provider activity is launched to manipulate
or return data - Android Built-in content providers
content//media/internal/images/,
content//media/external/images/,content//contac
ts/people/
30Register the Provider
- ltprovider androidname"NotePadProvider"
- androidauthorities"com.google.provid
er.NotePad" /gt - ltactivity androidname"NotesList"
androidlabel"_at_string/title_notes_list"gt - ltintent-filtergt
- ltaction androidname"android.intent.action
.MAIN" /gt - ltcategory androidname"android.intent.cate
gory.LAUNCHER" /gt - lt/intent-filtergt
- ltintent-filtergt
- ltaction androidname"android.intent.action.VIEW"
/gt - ltdata androidmimeType"vnd.android.cursor.dir/vn
d.google.note" /gt - lt/intent-filtergtltintent-filtergt
- ltaction androidname"android.intent.action.
GET_CONTENT" /gt - ltdata androidmimeType"vnd.android.cursor.item/v
nd.google.note" gt - lt/intent-filtergt lt/activitygt
31Implement the Provider
Plan the Database Extend the ContentProvider
class Fill in a variety of methods to be
overloaded onCreate() When the database is
created onUpgrade() When the database layout
changes getType() Return the MIME data
type query() Handle queries to the
data insert(), remove(), and update() methods
32A Managed Query
Purpose Query a content provider for relevant
data (cursor) Definition An Android cursor is a
collection of rows of data
string projection new string
People._ID, People.NAME, People.NUMBER //
Specify needed columns Uri mContactsUri
Contacts.People.CONTENT_URI // Get Contacts
URI // Invoke a content provider query Cursor
cursor managedQuery( mContactsUri, projection,
//Which columns to return null, null, //
Selection and WHERE clauses Contacts.People.NAME
" ASC") // Order-by clause (ascending by
name) Create a where clause using a standard SQL
where clause SQLiteQueryBuilder queryBuilder
new SQLiteQueryBuilder() queryBuilder.appendWhere
("People.NUMBER555-1212") A managedQuery
example public final Cursor managedQuery(Uri
uri , String projection, String selection,
String selectionArgs, String sortOrder)
33Navigating through a cursor
Manipulate the cursor (row pointer) if
(cursor.moveToFirst() false) cursor.isBeforeFir
st(), cursor.isAfterLast, cursor.isClosed() while
(cursor.moveToNext()) / code here / for
(cursor.moveToFirst() !cursor.isAfterLast()
cur.moveToNext) Get column numbers from
names int nameColumn cursor.getColumnIndex(Peopl
e.NAME) int phoneColumn cursor.getColumnIndex(P
eople.NUMBER) Get Data from column String name
cursor.getString(nameColumn) String number
cursor.getString(phoneColumn) Prerequisites
Know column names, data types, column name to
index relationship
34Other Access Methods
- Add
- ContentValues values new ContentValues()
- values.put(BookProviderMetaData.BookTableMetaData.
BOOK_NAME, "book1") - values.put(BookProviderMetaData.BookTableMetaData.
BOOK_AUTHOR, "author-1") - ContentResolver resolve context.getContentResolv
er() - URI uri BookProviderMetaData.BookTableMetaData.C
ONTENT.URI - Uri inserted resolve.insert(uri, values)
- Delete Assume that bookIndex is pre-defined
- ContentResolver resolve context.getContentResolv
er() - URI uri BookProviderMetaData.BookTableMetaData.C
ONTENT.URI - Uri delURI uri.withAppendedPath(uri,
Integer.toString(bookIndex)) - resolve.delete(delUri, null, null)
- Count
- URI uri BookProviderMetaData.BookTableMetaData.C
ONTENT.URI - Cursor cursor activity.managedQuery(uri, null,
null, null, null) - Int numberOfRecords cursor.getCount()
- cursor.close()
See Next slide
35BookProviderMetaData class
36Store Files in an SQLite Database
Using the reserved column name _data
- Steps
- Create the SQLite table with a column called
_data - Get a writeable output stream
- Write the file to the _data column
- I/O Example
- //Use a content resolver to insert the record
- ContentResolver contentResolver
activity.getContentResolver() - Uri newUri contentResolver.insert(Notepad.Notes
.CONTENT_URI, values) - //Use the content resolver to get an output
stream directly - OutputStream outStream contentResolver().openOu
tputStream(newUri) - writeFileToRecord(outStream)
- outStream.close()
- ContentValues object
- Contains a set of values
37Code Example (Two tables Employees, Department)
This application will need to override onCreate
and onUpgrade
public class DatabaseHelper extends
SQLiteOpenHelper static final String
dbName"demoDB" static final String
employees"Employees" static final String
colID"EmployeeID" static final String
colName"EmployeeName" static final String
colAge"Age" static final String
colDept"Dept" static final String
depts"Department" static final String
colDeptID"DeptID" static final String
colDeptName"DeptName" static final String
viewEmps"ViewEmps" public DatabaseHelper(Conte
xt context) // Constructor super(context,
dbName, null / Extension to cursor class /, 1
/ version /)
38Code Example (cont.)
public void onCreate(SQLiteDatabase db)
db.execSQL("CREATE TABLE " "depts " ("
colDeptID " INTEGER PRIMARY KEY , "
colDeptName " TEXT)") db.execSQL("CREATE
TABLE "employees " (" colID " INTEGER
PRIMARY KEY AUTOINCREMENT, " colName "
TEXT, " colAge " Integer, " colDept "
INTEGER NOT NULL , FOREIGN KEY (" colDept ")
REFERENCES " deptTable" ("colDeptID"))")
db.execSQL("CREATE TRIGGER fk_empdept_deptid
"" BEFORE INSERT ON "employees " FOR EACH ROW
BEGIN" " SELECT CASE WHEN ( (SELECT "
colDeptID " FROM " depts " WHERE "
colDeptID "new." colDept " ) IS NULL)"
" THEN RAISE (ABORT, 'Foreign Key Violation')
END" " END") db.execSQL("CREATE VIEW "
viewEmps " AS SELECT " employees "."
colID " AS _id," " " employees "."
colName ", " employees "." colAge ",
" depts "." colDeptName "" " FROM "
employees " JOIN " depts " ON "
employees "." colDept" " depts "."
colDeptID )
39Code Example (cont.) Upgrading the DB
Called when the version number in the constructor
changes
public void onUpgrade(SQLiteDatabase db, int
oldVersion, int newVersion) db.execSQL("DROP
TABLE IF EXISTS "employees) db.execSQL("DROP
TABLE IF EXISTS "depts) db.execSQL("DROP
TRIGGER IF EXISTS dept_id_trigger")
db.execSQL("DROP TRIGGER IF EXISTS
dept_id_trigger22") db.execSQL("DROP TRIGGER
IF EXISTS fk_empdept_deptid") db.execSQL("DROP
VIEW IF EXISTS "viewEmps) onCreate(db)
Note The activity can respond to menu selections
to insert, remove, and update rows