cosc 5/4730 android content providers and intents

31
Cosc 5/4730 Android Content Providers and Intents

Post on 20-Dec-2015

239 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Cosc 5/4730 Android Content Providers and Intents

Cosc 5/4730

Android Content Providers and

Intents

Page 2: Cosc 5/4730 Android Content Providers and Intents

Content Providers

• Any Uri that begins with content:// is retrieved with a content provider.– The data is encapsulated using a Uri instance– You don't know where it is, nor care actually– Could be a SQLite database, files, or retrieved

from off the device• With a Uri, you perform basic CRUD

operations using the content provider– CRUD = create, read, update, delete

Page 3: Cosc 5/4730 Android Content Providers and Intents

URI• Examples:• content://media/internal/images

– return the list of all internal images on the device.• content://contacts/people/

– return the list of all contact names on the device.• content://contacts/people/45

– return the single result row, the contact with ID=45.• content://mms

– returns a list of the mms messages (content://mms/part/<partID> gets the message)

• content://constants/5– return the constant number 5

• content://edu.cs4730.provider.csteach/csteach– a custom content provider covered later in the lecture.

Page 4: Cosc 5/4730 Android Content Providers and Intents

URI (2)

• android.providers package provide some ready made URIs, example:– ContactsContract.Contacts.CONTENT_URI– MediaStore.Images.Media.INTERNAL_CONTENT_

URI • Otherwise, use Uri.parse(String);Uri CONTENT_URI = Uri.parse("content://"+ PROVIDER_NAME + "/test");

Page 5: Cosc 5/4730 Android Content Providers and Intents

Contacts Example• Simple code to read the contacts• Note, need at least these permissions

– <uses-permission android:name="android.permission.GET_ACCOUNTS" />– <uses-permission android:name="android.permission.READ_CONTACTS" />

Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;String[] projection = new String[] { ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME };Cursor c = managedQuery(CONTENT_URI, projection, null, null, null); if (c.moveToFirst()) {

do {String str = "Id: " + c.getString(0);str += "Name: " + c.getString(1);

} while (c.moveToNext());}

Page 6: Cosc 5/4730 Android Content Providers and Intents

Custom Content Providers

• SQLite databases are private only to the application that created it.

• While custom content providers are way to make them accessible to other app's.

Page 7: Cosc 5/4730 Android Content Providers and Intents

Custom Content Providers (2)

• Extend the ContentProvider class and implement the required methods.– getType(): Returns the MIME type of the data at the given URI.– onCreate(): Called when the provider is being started.– query(): Receives a request from a client. The result is

returned as a Cursor object.– insert(): Inserts a new record into the content provider.– delete(): Deletes an existing record from the content provider.– update(): Updates an existing record from the content

provider.

Page 8: Cosc 5/4730 Android Content Providers and Intents

Custom Content Providers (3)

• With our content provider we can choose how to store the data:– file system, xml, database, or on the internet

• For this lecture example, we use a database, based of the sqlite lecture previously.– The example code for sqlite is on the website as

well as this example.

Page 9: Cosc 5/4730 Android Content Providers and Intents

Creating a Custom Content Provider

• create a class that extends ContentProvider– Using eclipse you can also have to create the necessary

methods.– In our case:

• public class cpProvider extends ContentProvider {

– Most of the methods inside, we implement as a pass through allowing the user to access the database.• They maybe a security risk and for sensitive info, a really bad

idea and probably not public anyway.

– We also need the some constants the database and the DatabaseHelper (not shown in these slides) for database.

Page 10: Cosc 5/4730 Android Content Providers and Intents

Constants we need

public static final String PROVIDER_NAME = "edu.cs4730.provider.csteach";public static final Uri CONTENT_URI = Uri.parse("content://"+ PROVIDER_NAME +

"/csteach");public static final String _ID = "_id";public static final String NAME = "name";public static final String IP = "ip";public static final String OWNER = "owner";

Page 11: Cosc 5/4730 Android Content Providers and Intents

UriMatcherprivate static final int CSTEACH = 1;private static final int CSTEACH_ID = 2; private static final UriMatcher uriMatcher;static{ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(PROVIDER_NAME, "csteach", CSTEACH); uriMatcher.addURI(PROVIDER_NAME, "csteach/#", CSTEACH_ID);}• Observe from the code above that you use a UriMatcher object to parse the

content URI that is passed to the content provider through a Content Resolver. For example, the following content URI represents a request for all rows in the content provider:

content://edu.cs4730.provider.csteach/csteach• In contrast, the following represents a request for a particular row with _id=5:content://edu.cs4730.provider.csteach/csteach/5

Page 12: Cosc 5/4730 Android Content Providers and Intents

override getType()• You'll need to override the getType() method so it uniquely describes the data type for your

content provider. Using the UriMatcher object, you will return "vnd.android.cursor.item/vnd.cs4730.csteach" for a single row, and "vnd.android.cursor.dir/vnd.cs4730.csteach" for multiple rows:

@Overridepublic String getType(Uri uri) {

switch (uriMatcher.match(uri)) {// get all rowscase CSTEACH:

return "vnd.android.cursor.dir/vnd.cs4730.csteach "; // get a particular row

case CSTEACH_ID:return "vnd.android.cursor.item/vnd.csc4730.csteach ";

default:throw new IllegalArgumentException("Unsupported URI: " + uri);

}}

Page 13: Cosc 5/4730 Android Content Providers and Intents

The Rest@Overridepublic boolean onCreate() { Context context = getContext(); dbHelper = new DatabaseHelper(context); db = dbHelper.getWritableDatabase(); return db != null;}@Overridepublic Uri insert(Uri uri, ContentValues values) { //add a new entry long rowID = db.insert(DATABASE_TABLE, "", values); //check for success if (rowID>0){ Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID); getContext().getContentResolver().notifyChange(_uri, null); return _uri; } throw new SQLException("Failed to insert row into " + uri);}

Page 14: Cosc 5/4730 Android Content Providers and Intents

The Rest (2)@Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder(); sqlBuilder.setTables(DATABASE_TABLE); if (uriMatcher.match(uri) == CSTEACH_ID) //if a particular row sqlBuilder.appendWhere( _ID + " = " + uri.getPathSegments().get(1)); if (sortOrder==null || sortOrder=="") //set a default sort order if none is provided. sortOrder = NAME; //then pass everything to the query builder. Cursor c = sqlBuilder.query( db, projection, selection, selectionArgs,

null, null, sortOrder); //---register to watch a content URI for changes--- c.setNotificationUri(getContext().getContentResolver(), uri); return c;}

Page 15: Cosc 5/4730 Android Content Providers and Intents

The Rest (3)@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; switch (uriMatcher.match(uri)){ case CSTEACH:count = db.update(DATABASE_TABLE, values, selection, selectionArgs); break; case CSTEACH_ID: count = db.update(DATABASE_TABLE, values, _ID + " = " + uri.getPathSegments().get(1)+ (!TextUtils.isEmpty(selection) ? " AND (" + selection+ ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException( "Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count;}

Page 16: Cosc 5/4730 Android Content Providers and Intents

The Rest (4)@Override

public int delete(Uri uri, String selection, String[] selectionArgs) {int count = 0;switch (uriMatcher.match(uri)) {case CSTEACH:

count = db.delete(DATABASE_TABLE, selection, selectionArgs);break;

case CSTEACH_ID:String id = uri.getPathSegments().get(1);count = db.delete(DATABASE_TABLE, _ID + " = " + id+ (!TextUtils.isEmpty(selection) ? " AND (" + selection+ ')' : ""), selectionArgs);break;

default:throw new IllegalArgumentException("Unknown URI " + uri);

}getContext().getContentResolver().notifyChange(uri, null);return count;

}

Page 17: Cosc 5/4730 Android Content Providers and Intents

Register the provider

• In the AndroidManifest.xml file– add the class the is the provider and register the content string

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".cpDemo" android:label="@string/app_name">

…</activity>

<provider android:name="cpProvider" android:authorities="edu.cs4730.provider.csteach" /> </application>

Page 18: Cosc 5/4730 Android Content Providers and Intents

Activity class

• Now in the activity class we can use it.• The example code has more examples, but two to give you a

favor//add a valueContentValues values = new ContentValues();values.put("name", "k2");values.put("ip", "129.72.216.12");values.put("owner", "cosc");Uri uri = getContentResolver().insert(Uri.parse("content://edu.cs4730.provider.csteach/csteach"), values);

// list all the entriesUri allrows = Uri.parse("content://edu.cs4730.provider.csteach/csteach");Cursor c = managedQuery(allrows, null, null, null, null);if (c.moveToFirst()) {

do {output.append("\n" + c.getString(0) + ", " + c.getString(1) + ", "+ c.getString(2) + ", " + c.getString(3));

} while (c.moveToNext());}

Page 19: Cosc 5/4730 Android Content Providers and Intents

References

• Android developer pages– http://developer.android.com/intl/zh-CN/

reference/android/provider/package-summary.html

• Using and Implementing Content Providers in Android– http://www.devx.com/wireless/Article/

41133/1763/page/1

Page 20: Cosc 5/4730 Android Content Providers and Intents

INTENTSandroid

Page 21: Cosc 5/4730 Android Content Providers and Intents

Intents

• As we saw in the Android GUI lecture intents can be used for message passing between activities.– Used to launch an Activity as well.– Also used to launch services and broadcast receives

too.• An Intent is a message object holding passive

data about an operation to be performed– Or with broadcast receives about something that has

already happened.

Page 22: Cosc 5/4730 Android Content Providers and Intents

Making a call example

• The intent is pretty simple Intent dialIntent = new Intent( "android.intent.action.CALL", Uri.parse("tel:3075555555"));

– Use “android.intent.action.DIAL”• To just bring up the dialer, but not call.

startActivity(dialIntent);

• Needs <uses-permission android:name= "android.permission.CALL_PHONE"> </uses-permission>– In the manifest.xml file.

http://developer.android.com/reference/android/Manifest.permission.html

Page 23: Cosc 5/4730 Android Content Providers and Intents

Web browser intent

• To start up the browser with a page location you specify– Intent dialIntent = new

Intent( "android.intent.action.VIEW", Uri.parse("http://www.cs.uwyo.edu"));

– startActivity(dialIntent);

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Page 24: Cosc 5/4730 Android Content Providers and Intents

Other “standard” intents

• You can start up the maps with an intent– intent = new Intent(Intent.ACTION_VIEW,

Uri.parse("geo:41.312927,105.587251?z=19"));• Should show Laramie on the map, but force closes on the simulator.

• Launch the camera– intent = new Intent("android.media.action.IMAGE_CAPTURE");

– <uses-permission android:name="android.permission.CAMERA"></uses-permission>

• Show contacts– intent = new Intent(Intent.ACTION_VIEW,

Uri.parse("content://contacts/people/"));– <uses-permission

android:name="android.permission.READ_CONTACTS"></uses-permission>

Page 25: Cosc 5/4730 Android Content Providers and Intents

Returning data.

• Instead of startActivity, use – startActivityForResult(intent, resultCode);• resultCode is a number you pick, that you can identify

the callback with.

• Override onActivityResult(int requestCode, int resultCode, Intent data) method.

Page 26: Cosc 5/4730 Android Content Providers and Intents

Passing data to a new activity.

• Create an intent– Intent i = new Intent(this, ActivityTwo.class);– i.putExtra(“key1”, “Some data”);– i.putExtra(“key2”, “more data”);• Where key1, key2 are names both activities know.

– startActivityForResult(i, REQUEST_CODE);• Assumes we want return data, otherwise use

startActivity.

Page 27: Cosc 5/4730 Android Content Providers and Intents

Passing data to a new activity. (2)

• ActivityTwo– In the onCreate methodBundle extras = getIntent().getExtras();//Make sure the activity was called correctly.if (extras == null) {return;}String value1 = extras.getString(“key1");String value2 = extras.getString(“key2");• Like others, many getX methods, like getInt(String key)

Page 28: Cosc 5/4730 Android Content Providers and Intents

Return data.• When activityTwo finishes, it can return an Intent with data.• In the finish() method@Overridepublic void finish() {

Intent data = new Intent();data.putExtra("returnKey1", “some data ");data.putExtra("returnKey2", “more data");setResult(RESULT_OK, data);super.finish();

}• Result: constants are RESULT_OK, RESULT_CANCELED, but you can also

use any custom result with an int.– When an activity fails, crashes, the result will be RESULT_CANCELED.

Page 29: Cosc 5/4730 Android Content Providers and Intents

Return data (2)• In the Calling activity@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) { //remember if RESULT_CANCELED, likely no data in the intent! if (data.hasExtra("returnKey1")) { Toast.makeText(this, data.getExtras().getString("returnKey1"),

Toast.LENGTH_SHORT).show(); } } else if (resultCode == RESULT_CANCELED && requestCode == REQUEST_CODE}

Toast.makeText(this, “ActivityTwo canceled!”,Toast.LENGTH_SHORT).show();

}

Page 30: Cosc 5/4730 Android Content Providers and Intents

Finally.

• You can see these intents working in the code provided with the lecture.

• For more of google applications intents see– http://developer.android.com/guide/appendix/g-

app-intents.html

Page 31: Cosc 5/4730 Android Content Providers and Intents

QA&