Learn about Android Content Providers and SQLite Scott A. Thisse March 20, 2012 Tampa Bay Android Developers Group
Learn about Android Content Providers and SQLite
Scott A. ThisseMarch 20, 2012
Tampa Bay Android Developers Group
March 20, 2012 Tampa Bay Android Developers Group 2 of 32
Learn about Android Content Providersand 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 3 of 32
What Are They?
● Mechanism used to encapsulatedata into services
● Required when sharing data between apps
● Use REST-like URIs
March 20, 2012 Tampa Bay Android Developers Group 4 of 32
How Are They Defined?
● Registered in AndroidManifest.xml
● Name is called an authority
● 3rd Party ones have FQNs
● Example:<provider
android:name="MyProvider"android:authorities="org.tbadg.MyProvider" />
March 20, 2012 Tampa Bay Android Developers Group 5 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 itemor an entire collection
March 20, 2012 Tampa Bay Android Developers Group 6 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 7 of 32
What Do They Return?
● Data returned as an Android cursor
● Callers expected to knowstructure of the returned data
● Returned data structured witha predefined MIME type
● MIME type returned for a given URI if requested via getType()
March 20, 2012 Tampa Bay Android Developers Group 8 of 32
MIME Types
● Work similar as they do in HTTP
● MIME type returned as 2-part stringin the form <type>/<subtype>
● Type part for indivual items is alwaysvnd.android.cursor.item
● Type part for collections is alwaysvnd.android.cursor.dir
March 20, 2012 Tampa Bay Android Developers Group 9 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 10 of 32
Accessing Data
● To reiterate, all access is thru URIs
● Base URIs (and columns) are usuallydefined with Java constants
● Easiest access is via managed query
● Built-in data requires a permissionsentry in AndroidManifest.xml
March 20, 2012 Tampa Bay Android Developers Group 11 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 12 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 13 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 14 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 15 of 32
Inserts, Updates, Deletes (oh my)
● Handled via a ContentResolver and a ContentValues dictionary
● Populate ContentValues with row'snew 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 16 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 17 of 32
Live Example
● AndroidManifest.xml
● main.xml
● strings.xml
● ContentProviders.java
March 20, 2012 Tampa Bay Android Developers Group 18 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 19 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">
<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>
continued...
March 20, 2012 Tampa Bay Android Developers Group 20 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 21 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 22 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 23 of 32
ContentProviders.javapackage org.tbadg;
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 24 of 32
ContentProviders.java (cont)
...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; continued...
March 20, 2012 Tampa Bay Android Developers Group 25 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 26 of 32
Screenshot
March 20, 2012 Tampa Bay Android Developers Group 27 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 28 of 32
Some Built-in Databases
● AlarmClock
● Browser
● CallLog
● Contacts
● MediaStore
● Settings
March 20, 2012 Tampa Bay Android Developers Group 29 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 30 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 31 of 32
Q & A
Questions?
March 20, 2012 Tampa Bay Android Developers Group 32 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