Tampa Bay Android Developers Group Learn about Android Content Providers and SQLite Scott A. Thisse March 20, 2012
Learn about Android Content Providers and SQLite What are they? How are they defined? How are they called? What do they return? SQLite March 20, 2012 Tampa Bay Android Developers Group 2 of 32
What Are They? Mechanism used to encapsulate data into services Required when sharing data between apps Use REST-like URIs March 20, 2012 Tampa Bay Android Developers Group 3 of 32
How Are They Defined? Registered in AndroidManifest.xml Name is called an authority 3 rd Party ones have FQNs Example: <provider android:name="myprovider" android:authorities="org.tbadg.myprovider" /> March 20, 2012 Tampa Bay Android Developers Group 4 of 32
How Are They Called? URIs are used Authority is used as a base name similar to how a domain name is used content:// is used as the scheme URI can identify an individual item or an entire collection March 20, 2012 Tampa Bay Android Developers Group 5 of 32
How Are They Called? Input parameters are embedded in URI Each URI path segment must be predefined, documented, and interpreted by the provider Examples: content://org.tbadg.myprovider/ content://contacts/people/ content://contacts/people/13/ March 20, 2012 Tampa Bay Android Developers Group 6 of 32
What Do They Return? Data returned as an Android cursor Callers expected to know structure of the returned data Returned data structured with a predefined MIME type MIME type returned for a given URI if requested via gettype() March 20, 2012 Tampa Bay Android Developers Group 7 of 32
MIME Types Work similar as they do in HTTP MIME type returned as 2-part string in the form <type>/<subtype> Type part for indivual items is always vnd.android.cursor.item Type part for collections is always vnd.android.cursor.dir March 20, 2012 Tampa Bay Android Developers Group 8 of 32
MIME Types Subtypes are more flexible Prefix with vnd for nonstandard, vendor-specific types Examples: vnd.android.cursor.item/ vnd.tbadg.info vnd.android.cursor.dir/ vnd.tbadg.info March 20, 2012 Tampa Bay Android Developers Group 9 of 32
Accessing Data To reiterate, all access is thru URIs Base URIs (and columns) are usually defined with Java constants Easiest access is via managed query Built-in data requires a permissions entry in AndroidManifest.xml March 20, 2012 Tampa Bay Android Developers Group 10 of 32
Managed Query Takes 5 parameters: Base URI Optional Array of properties (columns) Optional Constraint clause (where) Optional replacement values Optional sort statement Returns a Cursor object March 20, 2012 Tampa Bay Android Developers Group 11 of 32
Managed Query Examples With URI based constraint: Cursor cur = managedquery( com.someprovider.app/entries/13, null, null, null, null); Without constraints or sort: Cursor cur = managedquery(android.provider.browser.bookmarks_uri, null, null, null, null); With a property (columns) array: new String[] {"title"}, null, null, null); March 20, 2012 Tampa Bay Android Developers Group 12 of 32
Managed Query Examples (cont) With constraints (where) clause: null, Browser.BookmarkColumns.BOOKMARK + " = 1", null, null); With replacement value: null, "bookmark =?", new String[] {"1"}, null); With sort statement: null, null, null, "bookmark ASC title DESC"); March 20, 2012 Tampa Bay Android Developers Group 13 of 32
Cursors Need to know names and type of columns Columns are identified by number in methods Random access collection of data rows Use movetofirst() first and then movetonext() and isafterlast() to navigate thru data March 20, 2012 Tampa Bay Android Developers Group 14 of 32
Inserts, Updates, Deletes (oh my) Handled via a ContentResolver and a ContentValues dictionary Populate ContentValues with row's new or changed values, then Call appropriate ContentResolver method Example: ContentValues cv = new ContentValues(); ContentResolver cr = getcontentresolver(); Uri uri = cr.insert(some_provider_uri, cv); March 20, 2012 Tampa Bay Android Developers Group 15 of 32
Extending/Building Content Providers Future presentation(s) will show extending and building custom content providers See references for assistance before then March 20, 2012 Tampa Bay Android Developers Group 16 of 32
Live Example AndroidManifest.xml main.xml strings.xml ContentProviders.java March 20, 2012 Tampa Bay Android Developers Group 17 of 32
AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.tbadg" android:versioncode="1" android:versionname="1.0"> <uses-sdk android:minsdkversion="7" /> <uses-permission android:name="com.android.browser.permission.read_history_bookmarks" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".contentproviders" android:label="@string/app_name"> <intent-filter> <category android:name="android.intent.category.launcher" /> <action android:name="android.intent.action.main" /> </intent-filter> </activity> </application> </manifest> March 20, 2012 Tampa Bay Android Developers Group 18 of 32
main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> continued... <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ToggleButton android:id="@+id/bookmarks" android:layout_width="0dp" android:layout_weight="33" android:layout_height="wrap_content" android:texton="@string/show_bookmarks_str" android:textoff="@string/noshow_bookmarks_str" android:onclick="onclick"> </ToggleButton> March 20, 2012 Tampa Bay Android Developers Group 19 of 32
main.xml (cont)...continued <ToggleButton android:id="@+id/history" android:layout_width="0dp" android:layout_weight="33" android:layout_height="wrap_content" android:texton="@string/show_history_str" android:textoff="@string/noshow_history_str" android:onclick="onclick"> </ToggleButton> <ToggleButton android:id="@+id/sort" android:layout_width="0dp" android:layout_weight="33" android:layout_height="wrap_content" android:texton="@string/sorted_str" android:textoff="@string/unsorted_str" android:onclick="onclick"> </ToggleButton> </LinearLayout> continued... March 20, 2012 Tampa Bay Android Developers Group 20 of 32
main.xml (cont)...continued <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/output_str" /> <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/output" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </ScrollView> </LinearLayout> March 20, 2012 Tampa Bay Android Developers Group 21 of 32
strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">contentproviders</string> <string name="show_bookmarks_str">bookmarks</string> <string name="noshow_bookmarks_str">no Bookmarks</string> <string name="show_history_str">history</string> <string name="noshow_history_str">no History</string> <string name="sorted_str">sorted</string> <string name="unsorted_str">unsorted</string> <string name="output_str"><b><u>output:</u></b></string> </resources> March 20, 2012 Tampa Bay Android Developers Group 22 of 32
package org.tbadg; ContentProviders.java import android.app.activity; import android.database.cursor; import android.os.bundle; import android.provider.browser; import android.view.view; import android.widget.textview; import android.widget.togglebutton; public class ContentProviders extends Activity { // Some handles to UI components: TextView _outputtvw = null; ToggleButton _bookmarksbtn = null; ToggleButton _historybtn = null; ToggleButton _sortbtn = null; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); } // Set up UI component handles: _outputtvw = (TextView)findViewById(R.id.output); _bookmarksbtn = (ToggleButton)findViewById(R.id.bookmarks); _historybtn = (ToggleButton)findViewById(R.id.history); _sortbtn = (ToggleButton)findViewById(R.id.sort); continued... March 20, 2012 Tampa Bay Android Developers Group 23 of 32
ContentProviders.java (cont)...continued continued... public void onclick(view v) { String where = null; String sort = null; // Reset the output: _outputtvw.settext(null); // Determine (a bit redundantly) the data wanted: if (_bookmarksbtn.ischecked()) if (_historybtn.ischecked()) // Both wanted where = null; else // Just bookmarks where = Browser.BookmarkColumns.BOOKMARK + " = 1"; else // Just history if (_historybtn.ischecked()) where = Browser.BookmarkColumns.BOOKMARK + " <> 1"; else // neither return; March 20, 2012 Tampa Bay Android Developers Group 24 of 32
ContentProviders.java (cont)...continued // Determine whether to sort the output (via the query): if (_sortbtn.ischecked()) sort = Browser.BookmarkColumns.TITLE + " ASC"; else sort = null; // Get the data from the browser content provider: Cursor cur = managedquery(android.provider.browser.bookmarks_uri, null, where, null, sort); int titleindx = cur.getcolumnindex(browser.bookmarkcolumns.title); } } // Walk thru the data and add it to the output: cur.movetofirst(); while (!cur.isafterlast()) { _outputtvw.append(cur.getstring(titleindx) + "\n"); cur.movetonext(); } March 20, 2012 Tampa Bay Android Developers Group 25 of 32
Screenshot March 20, 2012 Tampa Bay Android Developers Group 26 of 32
SQLite Most common CP data store Installed on all Android devices Open source, embedded database Databases implemented as flat-files Executable is named sqlite3 March 20, 2012 Tampa Bay Android Developers Group 27 of 32
Some Built-in Databases AlarmClock Browser CallLog Contacts MediaStore Settings March 20, 2012 Tampa Bay Android Developers Group 28 of 32
Some Useful SQLite Commands.mode column enable column output.headers on enable column headers.output <file> redirect output to file.output stdout redirect output to screen.show display current options.help display command help March 20, 2012 Tampa Bay Android Developers Group 29 of 32
Some Useful SQLite Commands (cont).schema display all database info.tables display table info.indexes display index info.dump export database objects.read <file> import dumped data.exit exit the interpreter March 20, 2012 Tampa Bay Android Developers Group 30 of 32
Q & A Questions? March 20, 2012 Tampa Bay Android Developers Group 31 of 32
References Allen, G. and Owens M. (2010). The Definitive Guide to SQLite, Second Edition. New York, New York: Apress Content Providers (n.d.). Retrieved March 8, 2012, from http://developer.android.com/guide/topics/providers/content-providers.html Komatineni, S. et al. (2011). Pro Android 3. New York, New York: Apress Murphy, M. (2012). The Busy Coder's Guide to Advanced Android Development. Retrieved March 8, 2012 from http://commonsware.com March 20, 2012 Tampa Bay Android Developers Group 32 of 32