Mobile Programming Lecture 10 - Florida State...

126
Mobile Programming Lecture 10 ContentProviders

Transcript of Mobile Programming Lecture 10 - Florida State...

Page 1: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Mobile ProgrammingLecture 10

ContentProviders

Page 2: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Lecture 9 Review

● In creating a bound service, why would you choose to use a Messenger over extending Binder?

● What are the differences between using GPS provider and Network provider?

● When should you stop listening for location updates? Why at that point?

● How would you implement turn-by-turn directions?

● When should you disable a Sensor?

Page 3: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Lecture 9 Review

● How do you start an Activity B from and Activity A, and get a result back from Activity B when B has completed?

● How can you find out the structure of the intent filter for a given intent in the system?

Page 4: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Agenda

● ContentProviders○ Querying existing databases

○ Creating a database for your app

○ Inserting data

○ Updating data

○ Deleting data

○ Content provider permissions

● Viewing ContentProvider data

Page 5: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Android Application Components

1. Activity

2. Broadcast Receiver

3. Content Provider

4. Service

Page 6: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Basics

● A Content Provider manages access to a central repository of data

● Content providers are primarily intended to be used by other applications, which access the provider using a provider client object

● A Content Provider presents data to external applications as one or more tables that are similar to the tables found in a relational database

Page 7: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Basics

● When you want to access data in a Content Provider, you use the ContentResolver object in your application's Context to communicate with the provider as a client

● The ContentResolver object communicates with the provider object, an instance of a class that implements ContentProvider

● The provider object receives data requests from clients, performs the requested action, and returns the results.

Page 8: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Basics

● You don't need to develop your own provider if you don't intend to share your data with other applications, instead○ Use SharedPreferences

● The reason you use a ContentProvider is ○ Data is too complex for SharedPreferences○ Expose your data to other applications

Page 9: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Basics

● _ID column serves as the primary key column that the Content Provider automatically maintains

● Here's an example of a table with an _ID column

word app id frequency locale _ID

mapreduce user1 100 en_US 1

precompiler user14 200 fr_FR 2

applet user2 225 fr_CA 3

const user1 255 pt_BR 4

int user5 100 en_UK 5

Page 10: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Contacts ContentProvider

In our examples, we will look at the Contacts ContentProvider

A lot of the work for a query goes into reading the documentation online

http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html

Page 11: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Requesting Permission

In order to read the user's contacts, you need to request permission first

android.permission.READ_CONTACTS

Page 12: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a QueryLet's build several queries for ContractsContract.ContactsThe columns can be found in the documentation hereA few of the columns are ...

_ID long

LOOKUP_KEY String

NAME_RAW_CONTACT_ID long

DISPLAY_NAME_PRIMARY String

PHOTO_ID long

PHOTO_URI long

IN_VISIBLE_GROUP int

HAS_PHONE_NUMBER int

TIMES_CONTACTED int

Page 13: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a QueryWe will use the following fields in our class in our examples

public class ContactsContractExampleActivity extends ListActivity {

Cursor mCursor;

CursorAdapter mCursorAdapter;

String[] mProjection;

String[] mListColumns;

String mSelectionClause;

String[] mSelectionArgs;

String mOrderBy;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

}

Page 14: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a QueryWe will use the following fields in our class in our examples

public class ContactsContractExampleActivity extends ListActivity {

Cursor mCursor;

CursorAdapter mCursorAdapter;

String[] mProjection;

String[] mListColumns;

String mSelectionClause;

String[] mSelectionArgs;

String mOrderBy;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

}

Note that we're extending ListActivity, so we don't need to add a ListView to our XML layout file. We don't even need an XML layout file

Page 15: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query

Consider the following SQL queries

Page 16: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1

SELECT * FROM ContactsContract.Contacts

"Get every column for every contact in this database table"

Page 17: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Page 18: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

When you want to access data in a content provider, you need to use a ContentResolver. You can get the ContentResolver by calling getContentResolver()

Page 19: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

It returns a Cursor object.

Page 20: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Using a Cursor object, you can call the query() method to execute a query on a content provider.

Page 21: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

The second argument is a String array (i.e. String[ ]) of which columns we want to be returned by the query. Passing null means return all columns, i.e. SELECT *

Page 22: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

The first argument to Cursor.query() is a Uri. It specifies the table that you want to access, i.e. SELECT * FROM table

Page 23: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

ContactsContract is a content provider. You can think of it as the database

Page 24: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

ContactsContract.Contacts is a content provider. You can think of it as a table in the database

Page 25: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

This is one of the Uris for the table, which says how you want to access the table. Some tables have multiple Uris

Page 26: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

The third argument is a String. Here you specify the conditions for your query. Passing null means don't specify any conditions

Page 27: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

The fourth argument is a String[ ]. We will get back to this soon

Page 28: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

The fifth argument is a String. It says how we want to sort our results. Passing null means don't specify any sorting

Page 29: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

SELECT * FROM ContactsContract.Contacts

Page 30: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Our query is now complete, and the Cursor can iterate through the results. But since we want to attach our results to a ListView, we need to add a few more lines of code

Page 31: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Although our query was on all columns, here we create a String array of the columns we want to have displayed in our ListView.

Page 32: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

The column names are usually constants that you can reference via the database table

Page 33: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1

● In order to setup our ListView properly, we need to create an XML layout file that can represent each row in the list.

● We create a Layout XML file called query1.xml, which has the following TextView

Page 34: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1<?xml version="1.0" encoding="utf-8"?>

<TextView

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/contact_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Large Text"

android:textAppearance="?android:attr/textAppearanceLarge" />

Page 35: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1

<?xml version="1.0" encoding="utf-8"?>

<TextView

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/contact_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Large Text"

android:textAppearance="?android:attr/textAppearanceLarge"/>

Note the android:id attribute of the TextView

Page 36: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Page 37: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

So, String[ ] mListColumns specifies which columns we want to select

Page 38: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

and int[] mListItems is a corresponding array, telling us where to place the actual value of the DISPLAY_NAME

Page 39: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

It will be placed in this TextView, whose android:id="@+id/contact_name"

Page 40: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

We've been using ArrayAdapters with ListViews in the past, but here we use a SimpleCursorAdapter instead, because we have a Cursor (i.e. mCursor)

Page 41: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

First argument is a Context

Page 42: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Second argument is our Layout XML file resource used to construct the ListView

Page 43: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Third argument is our Cursor object

Page 44: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Fourth argument is our String array of column names

Page 45: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Fifth argument is our int array of TextView resources

Page 46: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1@Override

public void onCreate(Bundle savedInstanceState) {

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, null, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns,

mListItems);

setListAdapter(mCursorAdapter);

}

Finally, we call setListAdapter and pass our SimpleCursorAdapter

Page 47: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 1

See the query1() method inside of ContactsContractQueryExample.tar

This query is inefficient, because we're requesting all columns, but yet only using one column after we get the results

Page 48: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 2

Consider the following SQL query

SELECT _ID, DISPLAY_NAME FROM ContactsContract.Contacts

"Get the _ID and DISPLAY_NAME for all contacts"

Page 49: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 2@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts. _ID,

ContactsContract.Contacts. DISPLAY_NAME };

mCursor = getContentResolver().query(

ContactsContract.Contacts. CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts. DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter( this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Page 50: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 2@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Here we make a String array of the columns that we need.

Page 51: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 2@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Instead of passing null, we pass our String array of column names

Page 52: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 2@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mCursor = getContentResolver(). query(

ContactsContract.Contacts.CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

SELECT _ID, DISPLAY_NAMEFROM ContactsContract.Contacts

Page 53: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 2@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

This hasn't changed

Page 54: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 2

See the query2() method inside of ContactsContractQueryExample.tar

Page 55: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3

Consider the following SQL query

SELECT _ID, DISPLAY_NAME FROM ContactsContract.Contacts WHERE HAS_PHONE_NUMBER = 1

"Get the _ID and DISPLAY_NAME for all contacts that have phone numbers"

Page 56: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts. _ID,

ContactsContract.Contacts. DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts. HAS_PHONE_NUMBER +

" = ?";

mSelectionArgs = new String[]{ "1"};

mCursor = getContentResolver().query(

ContactsContract.Contacts. CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts. DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter( this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Page 57: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.DISPLAY_NAME + " = ? ";

mSelectionArgs = new String[]{"Fred"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

mProjection has not changed

Page 58: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{"1"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Here we use "?" as a placeholder. ContactsContract.Contacts.HAS_PHONE_NUMBER is a String, so we're appending " = ?" to this String0

Page 59: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{"1"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Each "?" will be replaced by an element in this String array, sequentially. In this case we only have one "?"

Page 60: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{"1"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Now instead of passing null for the selection clause, we pass our mSelectionClause String

Page 61: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{"1"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Instead of passing null, we pass our selection args array mSelectionArgs

Page 62: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{"1"};

mCursor = getContentResolver(). query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

SELECT _ID, DISPLAY_NAME FROM ContactsContract.ContactsWHERE HAS_PHONE_NUMBER = 1

Page 63: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{"1"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection, null, null,

null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

The ? is a placeholder here, just as %d or %s is a placeholder when you call printf()

Page 64: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 3

See the query3() method inside of ContactsContractQueryExample.tar

Page 65: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 4

Consider the following SQL query

SELECT _ID, DISPLAY_NAME, TIMES_CONTACTED FROM ContactsContract.Contacts

WHERE HAS_PHONE_NUMBER = 1

AND TIMES_CONTACTED > 5

"Get the _ID and DISPLAY_NAME for all contacts that have a phone number and that I've contacted more than 5 times"

Page 66: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 4@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = ? AND " +

ContactsContract.Contacts.TIMES_CONTACTED + " > ? ";

mSelectionArgs = new String[]{ "1", "5" };

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Page 67: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 4@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = ? AND " +

ContactsContract.Contacts.TIMES_CONTACTED + " > ? ";

mSelectionArgs = new String[]{"1", "5"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

We modify our selection clause slightly, to also have the condition that the contact must have been contacted more than 5 times

Page 68: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 4@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = ? AND " +

ContactsContract.Contacts.TIMES_CONTACTED + " > ? ";

mSelectionArgs = new String[]{"1", "5"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Since we have a new condition, we also add the argument to the condition to our selection arguments String array

Page 69: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 4@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = ? AND " +

ContactsContract.Contacts.TIMES_CONTACTED + " > ? ";

mSelectionArgs = new String[]{"1", "5"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

SELECT _ID, DISPLAY_NAME, TIMES_CONTACTED FROM ContactsContract.Contacts WHERE HAS_PHONE_NUMBER = 1

AND TIMES_CONTACTED > 5

Page 70: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 4@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = ? AND " +

ContactsContract.Contacts.TIMES_CONTACTED + " > ? ";

mSelectionArgs = new String[]{"1", "5"};

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, null);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

The rest hasn't changed

Page 71: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 4

See the query4() method inside of ContactsContractQueryExample.tar

Page 72: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 5

Consider the following SQL query

SELECT _ID, DISPLAY_NAME

FROM ContactsContract.Contacts

WHERE HAS_PHONE_NUMBER = 1

ORDER BY DISPLAY_NAME

"Get the _ID and DISPLAY_NAME for all contacts that have phone numbers, and sort the results by DISPLAY_NAME"

Page 73: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 5

FYI, we will build this query off of query3, not query4

Page 74: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 5@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts. _ID,

ContactsContract.Contacts. DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts. HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{ "1" };

mOrderBy = ContactsContract.Contacts. DISPLAY_NAME;

mCursor = getContentResolver().query(

ContactsContract.Contacts. CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, mOrderBy);

mListColumns = new String[] {

ContactsContract.Contacts. DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter( this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Page 75: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 5@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{"1"};

mOrderBy = ContactsContract.Contacts.DISPLAY_NAME;

mCursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, mOrderBy);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

Here we have a String specifying the column by which we want to sort. In this case, the DISPLAY_NAME

Page 76: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 5@Override

public void onCreate(Bundle savedInstanceState) {

mProjection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };

mSelectionClause = ContactsContract.Contacts.HAS_PHONE_NUMBER +

" = ? ";

mSelectionArgs = new String[]{"1"};

mOrderBy = ContactsContract.Contacts.DISPLAY_NAME;

mCursor = getContentResolver(). query(

ContactsContract.Contacts.CONTENT_URI, mProjection,

mSelectionClause, mSelectionArgs, mOrderBy);

mListColumns = new String[] {

ContactsContract.Contacts.DISPLAY_NAME };

mListItems = new int[] { R.id.contact_name };

mCursorAdapter = new SimpleCursorAdapter(this,

R.layout.query1, mCursor, mListColumns, mListItems);

}

SELECT _ID, DISPLAY_NAME FROM ContactsContract.Contacts WHERE HAS_PHONE_NUMBER = 1 ORDER BY DISPLAY_NAME

Page 77: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Constructing a Query - Query 5

See the query5() method inside of ContactsContractQueryExample.tar

Page 78: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Iterating through query results

You may not always want to add the results from a query to a ListView. Sometimes you just need to go through the results one-by-one

Page 79: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Iterating through query resultsCursor cursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI,

projection,

selectionClause,

selectionArgs,

null);

if (cursor != null) {

while (cursor.moveToNext()) {

cursor.getString(1);

}

}

Page 80: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Iterating through query resultsCursor cursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI,

projection,

selectionClause,

selectionArgs,

null);

if(cursor != null) {

while(cursor.moveToNext()) {

cursor.getString(1);

}

}

After executing the query ...

Page 81: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Iterating through query resultsCursor cursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI,

projection,

selectionClause,

selectionArgs,

null);

if(cursor != null) {

while(cursor.moveToNext()) {

cursor.getString(1);

}

}

Make sure that the Cursor is not null before using it

Page 82: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Iterating through query resultsCursor cursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI,

projection,

selectionClause,

selectionArgs,

null);

if(cursor != null) {

while(cursor.moveToNext()) {

cursor.getString(1);

}

}

This returns true as long as there are more results to be fetched

Page 83: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Iterating through query resultsCursor cursor = getContentResolver().query(

ContactsContract.Contacts.CONTENT_URI,

projection,

selectionClause,

selectionArgs,

null);

if(cursor != null) {

while(cursor.moveToNext()) {

cursor.getString(1);

}

}

Get the String represention of column number 1 (or use another integer if you want a different column value)

Page 84: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Iterating through query results

See ContentProviderExample.tar

Page 85: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

There are two ways to store your data using a Content Provider

1. File data○ photos, audio, video, etc

2. Structured data○ data fit for a database

We will look at structured data using SQLite databases

Page 86: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

Because writing to databases is a sensitive operation, in the next examples we will perform operations on our own SQLite database

Page 87: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

The steps for creating an SQLite DB for your app is not what you're used to, because doing it right means that you also need to understand URIs

Page 88: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

You should add the content provider via the Android Studio menu● Click File > New > Other > Content Provider● Provide a name for the Content Provider● Provide an Authorities URI

○ This should be your package name followed by “.provider”

● Click Finish

Page 89: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

Decide on the name of your database now, and we will add it as a field to the ContentProvider

public class MyProvider extends ContentProvider {

public final static String DBNAME = "NameDatabase";

...

}

Page 90: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

Next we need to add a String containing the SQL query for creating the necessary tables for our database

In our example, we will create a table in our database with the following structure

Column Name Type

_ID Integer PRIMARY KEY

FirstName TEXT

LastName TEXT

Page 91: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Providerpublic class MyProvider extends ContentProvider {

public final static String DBNAME = "NameDatabase";

private static final String SQL_CREATE_MAIN =

"CREATE TABLE Users ( " +

" _ID INTEGER PRIMARY KEY, " +

"FirstName TEXT, " +

"LastName TEXT )";

...

}

If you're unfamiliar with SQL, see this page

Page 92: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

● We will also add the CONTENT_URI Uri as a convenient way to get the URI for our database.

● We make it final because we don't want it to be modified after it has been set

Page 93: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Providerpublic class MyProvider extends ContentProvider {

public final static String DBNAME = "NameDatabase";

private static final String SQL_CREATE_MAIN =

"CREATE TABLE Users ( " +

" _ID INTEGER PRIMARY KEY, " +

"FirstName TEXT, " +

"LastName TEXT )";

public static final Uri CONTENT_URI = Uri.parse("content://my.package.name.provider");

...

}

Page 94: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

Before we implement any of the methods inside of your new ContentProvider, we need to add an inner class which extends SQLiteOpenHelper. This class will take care of

● Opening the database if it exists● Creating it if it does not

Page 95: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Providerpublic class MyProvider extends ContentProvider {

...

protected static final class MainDatabaseHelper extends SQLiteOpenHelper {

MainDatabaseHelper(Context context) {

super(context, "NamesDatabase", null, 1);

}

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL(SQL_CREATE_MAIN);

}

@Override

public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {

}

}

}

Page 96: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Providerpublic class MyProvider extends ContentProvider {

...

protected static final class MainDatabaseHelper extends SQLiteOpenHelper {

MainDatabaseHelper(Context context) {

super(context, "NamesDatabase", null, 1);

}

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL(SQL_CREATE_MAIN);

}

@Override

public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {

}

}

}

The String we created previously are here

Page 97: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Providerpublic class MyProvider extends ContentProvider {

...

protected static final class MainDatabaseHelper extends SQLiteOpenHelper {

MainDatabaseHelper(Context context) {

super(context, "NamesDatabase", null, 1);

}

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL(SQL_CREATE_MAIN);

}

@Override

public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {

}

}

}

Make sure to call super, and pass the name of the database as the second argument

Page 98: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Providerpublic class MyProvider extends ContentProvider {

...

protected static final class MainDatabaseHelper extends SQLiteOpenHelper {

MainDatabaseHelper(Context context) {

super(context, "NamesDatabase", null, 1);

}

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL(SQL_CREATE_MAIN);

}

@Override

public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {

}

}

}

The database will be created when onCreate() is called on our inner class. Note that this onCreate() doesn't get called until you try to access the database

Page 99: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Creating a Content Provider

Now we can implement the methods for our ContentProvider

Page 100: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the onCreate() method

public class MyContentProvider extends ContentProvider {

...

@Override

public boolean onCreate() {

mOpenHelper = new MainDatabaseHelper(getContext());

return true;

}

...

}

Page 101: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the onCreate() method

public class MyContentProvider extends ContentProvider {

...

@Override

public boolean onCreate() {

mOpenHelper = new MainDatabaseHelper(getContext());

return true;

}

...

}

We create an instance of our MainDatabaseHelper so that we can use it later for reading and modifying our NamesDatabase

Page 102: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

Page 103: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

We must return a Uri. We will return a Uri that has the new id of the item that will be inserted in this method

Page 104: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

This Uri can be used to identify the table in our database, but since we only have one table, we don't need to use it in this function

Page 105: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

These are the values that will be inserted. They are key-value pairs

Page 106: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

We get the FirstName and LastName values that were passed in

Page 107: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

Before you call insert() and update(), you should check for invalid values and return null if there is any invalid input. We don't use fname and lname afterward, as we are just trying to illustrate how to use ContentValues

Page 108: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

We need to call getWritableDatabase() to create and/or open our database which will be used for reading and writing

Page 109: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

We can insert() on our Users table, passing the values that need to be inserted

Page 110: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

Because the _ID column is the primary key, we don't need to specify a value for it. It will automatically be added for us

Page 111: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

That _ID value is returned from the call to insert(), we store it in this long int

Page 112: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the insert() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Uri insert(Uri uri, ContentValues values) {

String fname = values.getAsString("FirstName");

String lname = values.getAsString("LastName");

long id = mOpenHelper.getWritableDatabase()

.insert("Users", null, values);

return Uri.withAppendedPath(CONTENT_URI, "" + id);

}

...

}

Here we return the Uri that can be used to identify the row that was just inserted. For examplecontent://my.package.name.provider/Users/1

Page 113: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the update() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public int update(Uri uri, ContentValues values,

String selection, String[] selectionArgs) {

return mOpenHelper.getWritableDatabase().

update("Users", values, selection, selectionArgs);

}

...

}

Page 114: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the update() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public int update(Uri uri, ContentValues values,

String selection, String[] selectionArgs) {

return mOpenHelper.getWritableDatabase().

update("Users", values, selection, selectionArgs);

}

...

}

After checking for invalid values (not shown here), we simply use our mOpenHelper to update the Users table, and return that value. Next we implement the delete() method

Page 115: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the delete() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public int delete(Uri uri, String whereClause,

String[] whereArgs) {

return mOpenHelper.getWritableDatabase().

delete(TABLE_NAMESTABLE, whereClause, whereArgs);

}

...

}

Page 116: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the delete() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public int delete(Uri uri, String whereClause,

String[] whereArgs) {

return mOpenHelper.getWritableDatabase().

delete(TABLE_NAMESTABLE, whereClause, whereArgs);

}

...

}

Next, we implement the query() method

Page 117: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Implementing the delete() methodpublic class MyContentProvider extends ContentProvider {

...

@Override

public Cursor query(Uri table, String[] columns,

String selection, String[] args, String orderBy) {

return mOpenHelper.getReadableDatabase()

.query("Users", columns, selection, args, null, null, orderBy);

}

...

}

Page 118: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Permissions

Now that you've set up your ContentProvider, you will want to have external apps require permission to read/write your data

More on your own permissions here

Page 119: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Permissions

By default, anyone can read from or write to your ContentProvider

Take the steps necessary to protect you data

Page 120: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Permissions

1. Open the AndroidManifest.xml file2. Add a <permission … /> tag above the

<application> tag3. Set the android:name attribute for your permission

○ my.package.name.provider.permission.READ_PERMISSION○ (Create a String resource for this permission String)

4. Save the file

You can add as many permission Strings you want, how you use them is more important

Page 121: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Permissions● Single read-write provider-level permission

○ One permission that controls both read and write access to the entire provider, specified with the

■ android:permission attribute of the <provider> element.

● Separate read and write provider-level permission○ A read permission and a write permission for the entire provider

■ android:readPermission

■ android:writePermission

■ They take precedence over the permission required by android:permission.

Page 122: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Content Provider Permissions

See ContentProviderExternalUserExample.tar

Make sure that you've also installed ContentProviderExample.tar on the same device, so that the external user can use its content provider

Page 123: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

Viewing ContentProvider data

● We want to create a class to view ContentProvider data when an application calls ACTION_VIEW

● Implement getType() in ContentProvider to return MimeType

● Can have multiple Activities○ One displays single entry○ One displays list of entries

Page 124: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

ContentProvider MimeTypes

● vnd.android.cursor.dir ○ Describes multiple entries○ Ex. vnd.android.cursor.dir/edu.fsu.cs.mobile.provider/transactions

● Starts with vnd.android.cursor.item○ Describes one entry

○ Ex. vnd.android.cursor.item/edu.fsu.cs.mobile.provider/transactions

Page 125: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

ContentProvider MimeTypes

● Add intent-filter to view Activity● Add VIEW action● Add supported MimeTypes<action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><data android:scheme="content" /><data android:mimeType="vnd.android.cursor.dir/package.provider/table" /><data android:mimeType="vnd.android.cursor.item/package.provider/table" />

Page 126: Mobile Programming Lecture 10 - Florida State Universityww2.cs.fsu.edu/~yannes/lectures/lect10.ContentProviders.pdfContent Provider Basics When you want to access data in a Content

References

● The Busy Coder's Guide to Android Development - Mark Murphy

● Android Developers● The Mobile Lab at Florida State University