1 / 31

Cosc 5/4730

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

tudor
Télécharger la présentation

Cosc 5/4730

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Cosc5/4730 Android Content Providers and Intents

  2. 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

  3. 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.

  4. 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");

  5. 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()); }

  6. 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.

  7. 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.

  8. 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.

  9. 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.

  10. 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";

  11. UriMatcher private static final int CSTEACH = 1; private static final int CSTEACH_ID = 2; private static final UriMatcheruriMatcher; 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

  12. 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: @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { // get all rows case 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); } }

  13. The Rest @Override public booleanonCreate() { Context context = getContext(); dbHelper = new DatabaseHelper(context); db = dbHelper.getWritableDatabase(); return db != null; } @Override public 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); }

  14. The Rest (2) @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuildersqlBuilder = 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; }

  15. The Rest (3) @Override public 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; }

  16. 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; }

  17. 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>

  18. 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 value ContentValues 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 entries Uri 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()); }

  19. 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

  20. android Intents

  21. 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.

  22. 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

  23. 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>

  24. 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>

  25. Returning data. • Instead of startActivity, use • startActivityForResult(intent, resultCode); • resultCode is a number you pick, that you can identify the callback with. • Override onActivityResult(intrequestCode, intresultCode, Intent data) method.

  26. 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.

  27. Passing data to a new activity. (2) • ActivityTwo • In the onCreate method Bundle 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)

  28. Return data. • When activityTwo finishes, it can return an Intent with data. • In the finish() method @Override public 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.

  29. Return data (2) • In the Calling activity @Override protected void onActivityResult(intrequestCode, intresultCode, 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(); }

  30. 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

  31. Q A &

More Related