package com.camnter.newlife.component.contentprovider;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.support.annotation.NonNull;
/**
* Description:BaseContentProvider
* Created by:CaMnter
* Time:2015-11-12 16:31
*/
public abstract class BaseContentProvider extends ContentProvider {
// 单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头
protected static final String MIME_SINGLE = "vnd.android.cursor.item/";
// 数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头
protected static final String MIME_MULTIPLE = "vnd.android.cursor.dir/";
/**
* Implement this to initialize your content provider on startup.
* This method is called for all registered content providers on the
* application main thread at application launch time. It must not perform
* lengthy operations, or application startup will be delayed.
* <p/>
* <p>You should defer nontrivial initialization (such as opening,
* upgrading, and scanning databases) until the content provider is used
* (via {@link #query}, {@link #insert}, etc). Deferred initialization
* keeps application startup fast, avoids unnecessary work if the provider
* turns out not to be needed, and stops database errors (such as a full
* disk) from halting application launch.
* <p/>
* <p>If you use SQLite, {@link SQLiteOpenHelper}
* is a helpful utility class that makes it easy to manage databases,
* and will automatically defer opening until first use. If you do use
* SQLiteOpenHelper, make sure to avoid calling
* {@link SQLiteOpenHelper#getReadableDatabase} or
* {@link SQLiteOpenHelper#getWritableDatabase}
* from this method. (Instead, override
* {@link SQLiteOpenHelper#onOpen} to initialize the
* database when it is first opened.)
*
* @return true if the provider was successfully loaded, false otherwise
*/
@Override public abstract boolean onCreate();
/**
* Implement this to handle query requests from clients.
* This method can be called from multiple threads, as described in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
* and Threads</a>.
* <p/>
* Example client call:<p>
* <pre>// Request a specific record.
* Cursor managedCursor = managedQuery(
* ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
* projection, // Which columns to return.
* null, // WHERE clause.
* null, // WHERE clause value substitution
* People.NAME + " ASC"); // Sort order.</pre>
* Example implementation:<p>
* <pre>// SQLiteQueryBuilder is a helper class that creates the
* // proper SQL syntax for us.
* SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
* <p/>
* // Set the table we're querying.
* qBuilder.setTables(DATABASE_TABLE_NAME);
* <p/>
* // If the query ends in a specific record number, we're
* // being asked for a specific record, so set the
* // WHERE clause in our query.
* if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
* qBuilder.appendWhere("_id=" + uri.getPathLeafId());
* }
* <p/>
* // Make the query.
* Cursor c = qBuilder.query(mDb,
* projection,
* selection,
* selectionArgs,
* groupBy,
* having,
* sortOrder);
* c.setNotificationUri(getContext().getContentResolver(), uri);
* return c;</pre>
*
* @param uri The URI to query. This will be the full URI sent by the client;
* if the client is requesting a specific record, the URI will end in a record number
* that the implementation should parse and add to a WHERE or HAVING clause, specifying
* that _id value.
* @param projection The list of columns to put into the cursor. If
* {@code null} all columns are included.
* @param selection A selection criteria to apply when filtering rows.
* If {@code null} then all rows are included.
* @param selectionArgs You may include ?s in selection, which will be replaced by
* the values from selectionArgs, in order that they appear in the selection.
* The values will be bound as Strings.
* @param sortOrder How the rows in the cursor should be sorted.
* If {@code null} then the provider is free to define the sort order.
* @return a Cursor or {@code null}.
*/
@Override public abstract Cursor query(@NonNull
Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder);
/**
* Implement this to handle requests for the MIME type of the data at the
* given URI. The returned MIME type should start with
* <code>vnd.android.cursor.item</code> for a single record,
* or <code>vnd.android.cursor.dir/</code> for multiple items.
* This method can be called from multiple threads, as described in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
* and Threads</a>.
* <p/>
* <p>Note that there are no permissions needed for an application to
* access this information; if your content provider requires read and/or
* write permissions, or is not exported, all applications can still call
* this method regardless of their access permissions. This allows them
* to retrieve the MIME type for a URI when dispatching intents.
*
* @param uri the URI to query.
* @return a MIME type string, or {@code null} if there is no type.
*/
@Override public abstract String getType(@NonNull Uri uri);
/**
* Implement this to handle requests to insert a new row.
* As a courtesy, call {@link ContentResolver#notifyChange(Uri, ContentObserver)
* notifyChange()}
* after inserting.
* This method can be called from multiple threads, as described in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
* and Threads</a>.
*
* @param uri The content:// URI of the insertion request. This must not be {@code null}.
* @param values A set of column_name/value pairs to add to the database.
* This must not be {@code null}.
* @return The URI for the newly inserted item.
*/
@Override public abstract Uri insert(@NonNull Uri uri, ContentValues values);
/**
* Implement this to handle requests to delete one or more rows.
* The implementation should apply the selection clause when performing
* deletion, allowing the operation to affect multiple rows in a directory.
* As a courtesy, call {@link ContentResolver#notifyChange(Uri, ContentObserver)
* notifyChange()}
* after deleting.
* This method can be called from multiple threads, as described in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
* and Threads</a>.
* <p/>
* <p>The implementation is responsible for parsing out a row ID at the end
* of the URI, if a specific row is being deleted. That is, the client would
* pass in <code>content://contacts/people/22</code> and the implementation is
* responsible for parsing the record number (22) when creating a SQL statement.
*
* @param uri The full URI to query, including a row ID (if a specific record is requested).
* @param selection An optional restriction to apply to rows when deleting.
* @return The number of rows affected.
* @throws SQLException
*/
@Override public abstract int delete(
@NonNull Uri uri, String selection, String[] selectionArgs);
/**
* Implement this to handle requests to update one or more rows.
* The implementation should update all rows matching the selection
* to set the columns according to the provided values map.
* As a courtesy, call {@link ContentResolver#notifyChange(Uri, ContentObserver)
* notifyChange()}
* after updating.
* This method can be called from multiple threads, as described in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
* and Threads</a>.
*
* @param uri The URI to query. This can potentially have a record ID if this
* is an update request for a specific record.
* @param values A set of column_name/value pairs to update in the database.
* This must not be {@code null}.
* @param selection An optional filter to match rows to update.
* @return the number of rows affected.
*/
@Override public abstract int update(
@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs);
}