Mobile Programming Lecture 10
description
Transcript of Mobile Programming Lecture 10
![Page 1: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/1.jpg)
Mobile ProgrammingLecture 10
ContentProviders
![Page 2: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/2.jpg)
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?
• When should you disable a Sensor?
![Page 3: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/3.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/4.jpg)
Agenda
• ContentProviders
• Querying existing databases
• Creating a database for your app
• Manipulating data: insert, update, and delete
• Content provider permissions
![Page 5: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/5.jpg)
Android Application Components
1. Activity
2. Broadcast Receiver
3. Content Provider
4. Service
![Page 6: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/6.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/7.jpg)
Content Provider Basics
• When you want to access data in a content provider, you must 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/8.jpg)
Content Provider Basics
• You don't need to develop your own provider if you don't intend to share your data with other applications, insteado Use SharedPreferences
• The reason you use a ContentProvider is o data is too complex for SharedPreferenceso expose your data to other applications
![Page 9: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/9.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/10.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/11.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/12.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/13.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/14.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/15.jpg)
Constructing a Query
Consider the following SQL queries
![Page 16: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/16.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/17.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/18.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/19.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/20.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/21.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/22.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/23.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/24.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/25.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/26.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/27.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/28.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/29.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/30.jpg)
Constructing a Query - Query 1@Overridepublic 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 now. 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/31.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/32.jpg)
Constructing a Query - Query 1@Overridepublic 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](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/33.jpg)
Constructing a Query - Query 1@Overridepublic 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 34: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/34.jpg)
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 as has following TextView
![Page 35: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/35.jpg)
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 36: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/36.jpg)
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 37: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/37.jpg)
Constructing a Query - Query 1@Overridepublic 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 38: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/38.jpg)
Constructing a Query - Query 1@Overridepublic 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 39: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/39.jpg)
Constructing a Query - Query 1@Overridepublic 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 40: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/40.jpg)
Constructing a Query - Query 1@Overridepublic 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 41: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/41.jpg)
Constructing a Query - Query 1@Overridepublic 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 42: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/42.jpg)
Constructing a Query - Query 1@Overridepublic 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 43: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/43.jpg)
Constructing a Query - Query 1@Overridepublic 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 44: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/44.jpg)
Constructing a Query - Query 1@Overridepublic 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 45: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/45.jpg)
Constructing a Query - Query 1@Overridepublic 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 46: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/46.jpg)
Constructing a Query - Query 1@Overridepublic 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 47: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/47.jpg)
Constructing a Query - Query 1@Overridepublic 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 48: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/48.jpg)
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 49: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/49.jpg)
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 50: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/50.jpg)
Constructing a Query - Query 2@Overridepublic 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 51: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/51.jpg)
Constructing a Query - Query 2@Overridepublic 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 52: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/52.jpg)
Constructing a Query - Query 2@Overridepublic 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 53: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/53.jpg)
Constructing a Query - Query 2@Overridepublic 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 54: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/54.jpg)
Constructing a Query - Query 2@Overridepublic 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 55: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/55.jpg)
Constructing a Query - Query 2
See the query2() method inside of ContactsContractQueryExample.tar
![Page 56: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/56.jpg)
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 57: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/57.jpg)
Constructing a Query - Query 3@Overridepublic 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 58: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/58.jpg)
Constructing a Query - Query 3@Overridepublic 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);}
mProjection has not changed
![Page 59: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/59.jpg)
Constructing a Query - Query 3@Overridepublic 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 String
![Page 60: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/60.jpg)
Constructing a Query - Query 3@Overridepublic 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 61: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/61.jpg)
Constructing a Query - Query 3@Overridepublic 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 62: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/62.jpg)
Constructing a Query - Query 3@Overridepublic 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 63: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/63.jpg)
Constructing a Query - Query 3@Overridepublic 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 64: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/64.jpg)
Constructing a Query - Query 3@Overridepublic 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 65: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/65.jpg)
Constructing a Query - Query 3
See the query3() method inside of ContactsContractQueryExample.tar
![Page 66: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/66.jpg)
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 67: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/67.jpg)
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,
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 68: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/68.jpg)
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,
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);
}
We modify our selection clause slightly, to also have the condition that the contact must have been contacted more than 5 times
![Page 69: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/69.jpg)
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,
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);
}
Since we have a new condition, we also add the argument to the condition to our selection arguments String array
![Page 70: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/70.jpg)
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,
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_NAME, TIMES_CONTACTED FROM ContactsContract.Contacts WHERE HAS_PHONE_NUMBER = 1
AND TIMES_CONTACTED > 5
![Page 71: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/71.jpg)
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);}
This rest hasn't changed
![Page 72: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/72.jpg)
Constructing a Query - Query 4
See the query4() method inside of ContactsContractQueryExample.tar
![Page 73: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/73.jpg)
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 74: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/74.jpg)
Constructing a Query - Query 5
FYI, we will build this query off of query3, not query4
![Page 75: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/75.jpg)
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,
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 76: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/76.jpg)
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,
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 have a String specifying the column by which we want to sort. In this case, the DISPLAY_NAME
![Page 77: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/77.jpg)
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,
null, null, 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 78: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/78.jpg)
Constructing a Query - Query 5
See the query5() method inside of ContactsContractQueryExample.tar
![Page 79: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/79.jpg)
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 80: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/80.jpg)
Iterating through query resultsCursor cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, projection, selectionClause, null, null);
if(cursor != null) {while(cursor.moveToNext()) {
cusor.getString(1);}
}
![Page 81: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/81.jpg)
Iterating through query resultsCursor cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, projection, selectionClause, null, null);
if(cursor != null) {while(cursor.moveToNext()) {
cusor.getString(1);}
}
After executing the query ...
![Page 82: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/82.jpg)
Iterating through query resultsCursor cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, projection, selectionClause, null, null);
if(cursor != null) {while(cursor.moveToNext()) {
cusor.getString(1);}
}
Make sure that the Cursor is not null before using it
![Page 83: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/83.jpg)
Iterating through query resultsCursor cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, projection, selectionClause, null, null);
if(cursor != null) {while(cursor.moveToNext()) {
cusor.getString(1);}
}
This returns true as long as there are more results to be fetched
![Page 84: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/84.jpg)
Iterating through query resultsCursor cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, projection, selectionClause, null, null);
if(cursor != null) {while(cursor.moveToNext()) {
cusor.getString(1);}
}
Get the String represention of column number 1 (or use another integer if you want a different column value)
![Page 85: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/85.jpg)
Iterating through query results
See ContentProviderExample.tar
![Page 86: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/86.jpg)
Creating a Content Provider
There are two ways to store your data using a content provider
1. File data: photos, audio, video, etc2. Structured data
o data fit for a database
We will look at structured data using SQLite databases
![Page 87: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/87.jpg)
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 88: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/88.jpg)
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 89: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/89.jpg)
Creating a Content Provider
You should add the content provider via the Manifest file
• Open the Manifest file and click on the Application Tab
• Under Application Nodes, click Add ...
• Select Provider
• Under Attributes for Provider, click on the Name* link
• Enter the name for your Provider and press Enter
• Mouseover the class name in the new fileo Select add unimplemented methods
• Go back to the Manifest file
• Under Attributes for Provider, go to the Authorities* field and click Browse
• Click on New String...
• Enter a resource name for your string in the R.string field, e.g. "authority"
• Enter your package name in the String field, followed by ".provider“, done!
![Page 90: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/90.jpg)
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 91: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/91.jpg)
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 92: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/92.jpg)
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 93: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/93.jpg)
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 94: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/94.jpg)
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 95: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/95.jpg)
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 96: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/96.jpg)
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 97: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/97.jpg)
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 98: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/98.jpg)
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 99: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/99.jpg)
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 100: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/100.jpg)
Creating a Content Provider
Now we can implement the methods for our ContentProvider
![Page 101: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/101.jpg)
Implementing the onCreate() method
public class MyContentProvider extends ContentProvider {...@Overridepublic boolean onCreate() {
mOpenHelper = new MainDatabaseHelper(getContext());
return true;}
...}
![Page 102: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/102.jpg)
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 103: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/103.jpg)
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 104: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/104.jpg)
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 105: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/105.jpg)
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 106: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/106.jpg)
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 107: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/107.jpg)
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 108: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/108.jpg)
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 109: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/109.jpg)
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 110: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/110.jpg)
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 111: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/111.jpg)
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 112: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/112.jpg)
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 113: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/113.jpg)
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 114: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/114.jpg)
Implementing the update() methodpublic class MyContentProvider extends ContentProvider {
...@Overridepublic int update(Uri uri, ContentValues values,
String selection, String[] selectionArgs) {
return mOpenHelper.getWritableDatabase().update("Users", values, selection, selectionArgs);
}
...}
![Page 115: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/115.jpg)
Implementing the update() methodpublic class MyContentProvider extends ContentProvider {
...@Overridepublic 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 116: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/116.jpg)
Implementing the delete() methodpublic class MyContentProvider extends ContentProvider {
...@Overridepublic int delete(Uri uri, String whereClause, String[] whereArgs) {
return mOpenHelper.getWritableDatabase().delete(TABLE_NAMESTABLE, whereClause, whereArgs);
}
...}
![Page 117: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/117.jpg)
Implementing the delete() methodpublic class MyContentProvider extends ContentProvider {
...@Overridepublic int delete(Uri uri, String whereClause, String[] whereArgs) {
return mOpenHelper.getWritableDatabase().delete(TABLE_NAMESTABLE, whereClause, whereArgs);
}
...}
Next, we implement the query() method
![Page 118: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/118.jpg)
Implementing the delete() methodpublic class MyContentProvider extends ContentProvider {
...@Overridepublic Cursor query(Uri table, String[] columns, String selection,
String[] args, String orderBy) {
return mOpenHelper.getReadableDatabase().query("Users", columns, selection, args, null, null, orderBy);
}...
}
![Page 119: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/119.jpg)
Implementing the delete() methodpublic class MyContentProvider extends ContentProvider {
...@Overridepublic Cursor query(Uri table, String[] columns, String selection,
String[] args, String orderBy) {
return mOpenHelper.getReadableDatabase().query("Users", columns, selection, args, null, null, orderBy);
}...
}
![Page 120: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/120.jpg)
Content Provider Permissions
Now that you've set up your content provider, you will want to have external apps require permission to read/write your data
More on your own permissions here
![Page 121: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/121.jpg)
Content Provider Permissions
By default, anyone can read from or write to your content provider
Take the steps necessary to protect you data
![Page 122: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/122.jpg)
Content Provider Permissions
1. Open the Manifest file2. Click on the Permissions tab3. Click Add ... Permission4. In the Name field, enter
o my.package.name.provider.permission.READ_PERMISSIONo (Create a String resource for this permission String)
5. Done
You can add many permission Strings
![Page 123: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/123.jpg)
Content Provider Permissions
• Single read-write provider-level permissiono 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 permissiono 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 124: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/124.jpg)
Content Provider Permissions
See ContentProviderExternalUserExample.tar
Make sure that you've also installed ContenProviderExample.tar on the same device, so that the external user can use its content provider
![Page 125: Mobile Programming Lecture 10](https://reader035.fdocuments.in/reader035/viewer/2022062302/56816690550346895dda6ad2/html5/thumbnails/125.jpg)
References
• The Busy Coder's Guide to Android Development - Mark Murphy
• Android Developers
• The Mobile Lab at Florida State University