数据集的MIME类型字符串
?初始MIME类型,是在学习ContentProvider的时候。
? ?? ? 当在创建自己的ContentProvider的时,需要从抽象类ContentProvider中派生出自己的子类,并实现其中5个抽象方法:
query(Uri, String[], String, String[], String)}
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
public class MyDbHelper extends SQLiteOpenHelper {
public MyDbHelper(Context context, String name, CursorFactory factory,
? ? int version) {
? ?super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
? ?String sql = "CREATE TABLE " + Shopping.TABLE_NAME + " ( "
? ???+ Shopping.FIELD_ID + " INTEGER primary key autoincrement, "
? ???+ " " + Shopping.FIELE_NAME + " TEXT)";
? ?db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
? ?String sql = "DROP TABLE IF EXISTS " + Shopping.TABLE_NAME;
? ?db.execSQL(sql);
? ?onCreate(db);
}
}
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;
public class MyProvider extends ContentProvider {
private MyDbHelper myDbHelper;
private static final UriMatcher mUriMatcher; // 进行匹配的Uri的设定
static {
? ?mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
? ?mUriMatcher.addURI(Shopping.AUTHORITY, "item", Shopping.ITEM);
? ?mUriMatcher.addURI(Shopping.AUTHORITY, "item/#", Shopping.ITEM_ID);
}
@Override
public boolean onCreate() {
? ?System.out.println("onCreate");
? ?// 创建数据库
? ?myDbHelper = new MyDbHelper(getContext(), Shopping.DATABASE_NAME, null,
? ???Shopping.DATABASE_VERSION);
? ?return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
? ?SQLiteDatabase db = myDbHelper.getWritableDatabase();
? ?int count = 0;
? ?System.out.println("delete");
? ?switch (mUriMatcher.match(uri)) {
? ?case Shopping.ITEM:
? ? count = db.delete(Shopping.TABLE_NAME, selection, selectionArgs);
? ? break;
? ?case Shopping.ITEM_ID:
? ? // 通过Uri获取Id,根据主键进行? ? break;
? ?default:
? ? throw new IllegalArgumentException();
? ?}
? ?// 通知数据发生改变
? ?getContext().getContentResolver().notifyChange(uri, null);
? ?return count;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
? ?SQLiteDatabase db = myDbHelper.getWritableDatabase();
? ?long row = 0;
? ?System.out.println("insert");
? ?if (mUriMatcher.match(uri) != Shopping.ITEM) {
? ? throw new IllegalArgumentException();
? ?}
? ?row = db.insert(Shopping.TABLE_NAME, Shopping.FIELD_ID, values);
? ?if (row > 0) {
? ? Uri noteUri = ContentUris.withAppendedId(Shopping.URI, row);
? ? getContext().getContentResolver().notifyChange(uri, null);
? ? return noteUri;
? ?}
? ?return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
? ? String[] selectionArgs, String sortOrder) {
? ?SQLiteDatabase db = myDbHelper.getReadableDatabase();
? ?Cursor cursor = null;
? ?System.out.println("query");
? ?switch (mUriMatcher.match(uri)) {
? ?case Shopping.ITEM:
? ? cursor = db.query(Shopping.TABLE_NAME, projection, selection,
? ?? ?selectionArgs, null, null, sortOrder);
? ? break;
? ?case Shopping.ITEM_ID:
? ? String id = uri.getPathSegments().get(1);
? ? cursor = db.query(Shopping.TABLE_NAME, projection,
? ?? ?Shopping.FIELD_ID
? ?? ???+ "="
? ?? ???+ id
? ?? ???+ (!TextUtils.isEmpty(selection) ? " AND ("
? ?? ?? ? + selection + ')' : ""), selectionArgs,
? ?? ?null, null, sortOrder);
? ? break;
? ?default:
? ? throw new IllegalArgumentException();
? ?}
??
? ?cursor.setNotificationUri(getContext().getContentResolver(), uri);
? ?return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
? ? String[] selectionArgs) {
? ?SQLiteDatabase db = myDbHelper.getWritableDatabase();
? ?int count = 0;
? ?System.out.println("update");
??
? ?switch (mUriMatcher.match(uri)) {
? ?case Shopping.ITEM:
? ? count = db.update(Shopping.TABLE_NAME, values, selection,
? ?? ?selectionArgs);
? ? break;
? ?case Shopping.ITEM_ID:
? ? String id = uri.getPathSegments().get(1);
? ? count = db.update(Shopping.TABLE_NAME, values, Shopping.FIELD_ID
? ?? ?+ "="
? ?? ?+ id
? ?? ?+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
? ?? ???+ ')' : ""), selectionArgs);
? ? break;
? ?default:
? ? throw new IllegalArgumentException();
? ?}
? ?getContext().getContentResolver().notifyChange(uri, null);
? ?return count;
}
@Override
public String getType(Uri uri) {
? ?// 进行Uri匹配完成不同的处理工作
? ?switch (mUriMatcher.match(uri)) {
? ?case Shopping.ITEM:
? ?return Shopping.CONTENT_ITEM;
? ?case Shopping.ITEM_ID:
? ? return Shopping.CONTENT_ITEM_TYPE;
? ?default:
? ? throw new IllegalArgumentException();
? ?}
}
}
? ???在上面的例子中,首先有一个Shopping类,定义了一系列的常量。包括访问的数据库的相关信息和URI的定义,其中最重要的就是下面的两句,MIME类型的定义:
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.stone.shopping";
public static final String CONTENT_ITEM = "vnd.android.cursor.dir/vnd.stone.shopping";
? ? 其次是一个MyDbHelper类,继承自SQLiteOpenHelper类,用于一些数据库相关操作,这里就不赘述了。
? ? 最后的MyProvider类使我们的重头戏,首先我们来看这一段代码:
private static final UriMatcher mUriMatcher; // 进行匹配的Uri的设定
static {
? ?mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
? ?mUriMatcher.addURI(Shopping.AUTHORITY, "item", Shopping.ITEM);
? ?mUriMatcher.addURI(Shopping.AUTHORITY, "item/#", Shopping.ITEM_ID);
}
? ? UriMatcher表示一个Uri的匹配器,它会对我们请求的Uri进行匹配,而匹配的格式就是这里我们通过addURI()方法添加格式。
? ? 接下来,首先执行的就是getType(Uri)方法,下面来看该方法体中的代码:
switch (mUriMatcher.match(uri)) {
? ?case Shopping.ITEM:
? ? return Shopping.CONTENT_ITEM;
? ?case Shopping.ITEM_ID:
? ? return Shopping.CONTENT_ITEM_TYPE;
? ?default:
? ? throw new IllegalArgumentException();
? ?}
? ? 当请求过来的Uri通过mUriMatcher.match(uri)方法进行匹配,根据不同的匹配值(Shopping.CONTENT_ITEM 或者 Shopping.CONTENT_ITEM_TYPE)来返回不同的MIME类型。
? ? 下面我们来结合query(Uri, String[], String, String[], String)?这个方法来解释一下:
? ?? ???在这个方法中,返回的是一个Cursor游标对象。而Cursor中是单条的记录还是一个集合,需要和在getType()方法中返回的类型保持一致。当返回的MIME类型是Shopping.CONTENT_ITEM时,Cursor应该是一个集合;当返回的MIME类型是Shopping.CONTENT_ITEM_TYPE时,Cursor应该是单条记录。
? ? 由于在getType()方法里面,我们显示的返回了android平台可以识别的MIME类型,所以在执行query方法返回Cursor对象的时候,系统将不需要再进行验证,从而可以说是节省了系统开销。
? ?? ? 话已至此,那么何谓android平台可以识别的MIME类型呢?下面来分析一下MIME类型的结构:
? ?? ? 其实,MIME类型其实就是一个字符串,中间有一个 “/” 来隔开,“/”前面的部分是系统识别的部分,就相当于我们定义一个变量时的变量数据类型,通过这个“数据类型”,系统能够知道我们所要表示的是个什么东西。至于 “/” 后面的部分就是我们自已来随便定义的“变量名”了。
? ?? ? 那么,既然MIME类型就是一个字符串,那么我们的getType( )自然也可以随便返回一个系统不能识别的字符串啦?没错,有些时候我们确实也这样处理,比如说可以这样写:
? ???public String getType(Uri uri) {
? ?? ?return getContext().getPackageName();?
? ? }
? ? 这里,我们把当前上下文的包名返回了。这样处理的结果是怎样的呢?
? ? 简单的说,系统不能够识别它了,也就不会做任何处理。仍然以query方法来说,当执行完方法体(这里需要注意一下:在这种情况下,即使我们没有通过返回MIME类型字符串来进行验证处理,但是在query方法中再次对Uri进行了匹配并根据不同的Uri类型进行了不同的操作)返回Cursor对象的时候,这时候系统不能肯定返回的Cursor对象是否合法,因此需要对其进行验证,这样对系统资源算是一个浪费了吧。所以,我们最好还是显示的返回一个MIME类型吧,当然要写正确了,让我们android平台可以识别。