Back to project page streaming_project.
The source code is released under:
GNU General Public License
If you think the Android project streaming_project listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.example.streaming.streaming; //from w w w . j a va2s .c o m import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; /* The content provider manages access to a central repository of data (e.g. SQLite database) by other applications or activities within the provider's application. It serves as an interface to data saved in a structured format. It uses an SQLite database API to store the media information with the help of the SQLiteOpenHelper. All other parts of the app can only access through the Content Resolver. Six abstract methods from the abstract class ContentProvider must be implemented: query(), insert(), update(), delete(), getType(), and onCreate(). However, your code doesn't to do anything in each method except return the expected data type. onCreate() is the only method that is not called by the application client that is attempting to access the content provider. TODO: This provider will combine table data and files since it will be serving media-related data TODO: (videos and music). NOTE 1: Queries must not be performed on the UI thread. They should be done asynchronously on a separate thread. CursorLoader or AsyncQueryHandler can be used to accomplish that. NOTE 2: All the methods except onCreate() can be called by multiple threads at once, so they must be thread-safe NOTE 3: This provider is defined in the manifest, just like we do for Activity and Service components. NOTE 4: since permission to use the provider is not added in the manifest, all applications can read from or write to the provider References: http://blog.stylingandroid.com/adapters-part-5/ http://developer.android.com/guide/topics/providers/content-provider-basics.html http://developer.android.com/guide/topics/providers/content-provider-creating.html */ public class MediaProvider extends ContentProvider { private static final int ITEMS = 1; private static final int ITEM_ID = 2; private static final String AUTHORITY = "com.example.streaming.streaming"; private static final String BASE_PATH = MediaDatabaseHelper.TABLE_MEDIA; public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/items"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/item"; // A "projection" defines the columns that will be returned for each row by the query public static final String[] PROJECTION = { MediaDatabaseHelper.COLUMN_MEDIA_ID, MediaDatabaseHelper.COLUMN_MEDIA_ARTIST }; // Content URI of the com.example.streaming.streaming's "media" table // It is a URI that identifies data in the provider. It includes the AUTHORITY which is the // symbolic name of the entire provider and a PATH which is a name that points to a table // NOTE 1: the string content:// (the scheme) is always present, and identifies this as a // content URI // NOTE 2: The optional id part points to an individual row in a table public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH); // Handle to the database helper object private MediaDatabaseHelper helper; // TODO: How does UriMatcher works? private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sURIMatcher.addURI(AUTHORITY, BASE_PATH, ITEMS); sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", ITEM_ID); } @Override // Initializes the provider. It is called by the OS after the provider is created. // NOTE 1: The provider is not created until ContentResolver object tries to access it // NOTE 2: Avoid doing lengthy computations in onCreate() public boolean onCreate() { // Create a new helper object // NOTE: the database itself isn't created or opened until // SQLiteOpenHelper.getWritableDatabase is called helper = new MediaDatabaseHelper(getContext()); return helper != null; } @Override // Retrieves data from the provider and returns a Cursor object over the result set // The built query is analogous to the SQL statement: // SELECT column_name FROM table_name WHERE column_name = val ORDER BY column_name ASC; // NOTE: It returns null if there is an internal error public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); queryBuilder.setTables(MediaDatabaseHelper.TABLE_MEDIA); int uriType = sURIMatcher.match(uri); switch (uriType) { case ITEMS: break; case ITEM_ID: queryBuilder.appendWhere(MediaDatabaseHelper.COLUMN_ID + "=" + uri.getLastPathSegment()); break; default: // The provider received an invalid content URI // NOTE: Android can communicate the following exceptions across process boundaries: // IllegalArgumentException and NullPointerException throw new IllegalArgumentException("Unknown URI: " + uri); } SQLiteDatabase db = helper.getWritableDatabase(); // A cursor is a list of rows and it can be linked to a ListView via a SimpleCursorAdapter // to display its contents // NOTE: To back a ListView with a Cursor, the cursor must contain a column named _ID // TODO: Make sure that if the query doesn't match any rows, a Cursor instance whose getCount() method returns 0 Cursor cursor = queryBuilder.query( db, // Database to query on projection, // The columns to return for each row selection, // Setting the selection clause to null will return all words selectionArgs, // Selection arguments array null, // GROUP BY clause. null will cause the rows to not be grouped null, // having clase. null will cause all row groups to be included sortOrder); // ORDER BY cluase. null will use the default sort order, which may // be unordered cursor.setNotificationUri(getContext().getContentResolver(), uri); // Some providers return null if an error occurs, others throw an exception return cursor; } @Override // Returns the MIME type of the content URI public String getType(Uri uri) { return null; } @Override // Inserts a new row in the provider and returns a content URI for the new row. // NOTE: "values" defines an object to contain the new values to insert // TODO: If a column name is not in the ContentValues argument, provide a default value for it // TODO: either in provider code or in the database schema public Uri insert(Uri uri, ContentValues values) { int uriType = sURIMatcher.match(uri); SQLiteDatabase sqlDB = helper.getWritableDatabase(); long id = 0; switch (uriType) { case ITEMS: // TODO: Why do we add the size of values? Should not values.size be 1 since we are inserting just one row at a time? if(getRowCount() + values.size() <= MediaDatabaseHelper.MAX_ROWS) { id = sqlDB.insert( MediaDatabaseHelper.TABLE_MEDIA, // The table to query on null, // nullColumnHack values); // The values to insert } break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); // The content URI returned identifies the newly-added row, with the following format: // content://<authority>/<table_name>/<id_value> // where id_value is the contents of _ID for the new row // TODO: Use withAppendedId() to append the new row's _ID value to the table's content URI // TODO: see "Implementing the insert() method" in http://developer.android.com/guide/topics/providers/content-provider-creating.html#ContentProvider return Uri.parse(BASE_PATH + "/" + id); } @Override // Deletes rows from the provider and returns the number of deleted rows public int delete(Uri uri, String selection, String[] selectionArgs) { int uriType = sURIMatcher.match(uri); SQLiteDatabase sqlDB = helper.getWritableDatabase(); int rowsDeleted = 0; switch (uriType) { case ITEMS: rowsDeleted = sqlDB.delete( MediaDatabaseHelper.TABLE_MEDIA, // The table to query on selection, // The column to select on selectionArgs); // The value to compare to break; case ITEM_ID: String id = uri.getLastPathSegment(); if (TextUtils.isEmpty(selection)) { rowsDeleted = sqlDB.delete(MediaDatabaseHelper.TABLE_MEDIA, MediaDatabaseHelper.COLUMN_ID + "=" + id, null); } else { rowsDeleted = sqlDB.delete(MediaDatabaseHelper.TABLE_MEDIA, MediaDatabaseHelper.COLUMN_ID + "=" + id + " and " + selection, selectionArgs); } break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return rowsDeleted; } @Override // Updates existing rows in the provider and returns the number of rows updated // NOTE 1: "values" defines an object that contains the updated values // NOTE 2: "selection" and "selectionArgs" define selection criteria for the rows to be updated public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int uriType = sURIMatcher.match(uri); SQLiteDatabase sqlDB = helper.getWritableDatabase(); int rowsUpdated = 0; switch (uriType) { case ITEMS: rowsUpdated = sqlDB.update( MediaDatabaseHelper.TABLE_MEDIA, // The table to query on values, // The columns to update selection, // The columns to select on selectionArgs); // The value to compare to break; case ITEM_ID: String id = uri.getLastPathSegment(); if (TextUtils.isEmpty(selection)) { rowsUpdated = sqlDB.update( MediaDatabaseHelper.TABLE_MEDIA, values, MediaDatabaseHelper.COLUMN_ID + "=" + id, null); } else { rowsUpdated = sqlDB.update( MediaDatabaseHelper.TABLE_MEDIA, values, MediaDatabaseHelper.COLUMN_ID + "=" + id + " and " + selection, selectionArgs); } break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return rowsUpdated; } // Returns number of rows in the table private long getRowCount() { return DatabaseUtils.queryNumEntries(helper.getReadableDatabase(), MediaDatabaseHelper.TABLE_MEDIA); } }