网站建设收费标准好么,推广策划,网站建设 前景 html5,网站更换域名 换程序 SEO第一个版本 对android中MIME类型的理解 初始MIME类型#xff0c;是在学习ContentProvider的时候。 当在创建自己的ContentProvider的时#xff0c;需要从抽象类ContentProvider中派生出自己的子类#xff0c;并实现其中5个抽象方法#xff1a; query(Uri, String[], Strin…第一个版本 对android中MIME类型的理解 初始MIME类型是在学习ContentProvider的时候。 当在创建自己的ContentProvider的时需要从抽象类ContentProvider中派生出自己的子类并实现其中5个抽象方法 query(Uri, String[], String, String[], String) which returns data to the caller insert(Uri, ContentValues) which inserts new data into the content provider update(Uri, ContentValues, String, String[]) which updates existing data in the content provider delete(Uri, String, String[]) which deletes data from the content provider getType(Uri) which returns the MIME type of data in the content provider 至于前四个方法不是本文想要讨论的重点就不做冗余的阐述了有意思的是这个方法getType(Uri)根据帮助文档的解释它返回一个MIME类型。 首先先百度了一下MIME类型根据百度百科的解释MIME全称Multipurpose Internet Mail Extensions多功能Internet 邮件扩充服务。它是一种多用途网际邮件扩充协议在1992年最早应用于电子邮件系统但后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型当该扩展名文件被访问的时候浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名以及一些媒体文件打开方式。 看完百度百科的解释相信大家和我一样仍然不解。结合一个例子与老师交流之后我的理解是这样的 在ContentProvider的getType(Uri)方法中可以显示的返回一个MIME类型该方法返回一个字符串可以是任意的字符串当我们显示的返回该MIME类型的时候相当于通过该方法的验证Provider可以识别自身其他方法返回的Cursor的内容不需要在进行更多的验证如果返回其他的字符串(非android能够识别的MIME类型例如直接返回当前的包名)则Provider在执行其他方法后返回Cursor类型的时候需要再次进行验证。 还是云里雾里的下面来看一个使用了MIME类型的自定义ContentProvider的例子 import android.net.Uri; public class Shopping { // 定义数据库的名字 public static final String DATABASE_NAME shopping_db; // 定义数据库的版本 public static final int DATABASE_VERSION 1; // 表的名字 public static final String TABLE_NAME t_shopping; // 定义数据库的字段 public static final String FIELD_ID _id; public static final String FIELE_NAME product_name; // 定义访问的类型 public static final int ITEM 1; public static final int ITEM_ID 2; // 定义MIME类型访问单个记录 public static final String CONTENT_ITEM_TYPE vnd.android.cursor.item/vnd.com.stone.shopping; // 访问数据集 public static final String CONTENT_ITEM vnd.android.cursor.dir/vnd.stone.shopping; // 定义访问ContentProvider权限 public static final String AUTHORITY com.stone.shopping; // 定义URI public static final Uri URI Uri.parse(content:// AUTHORITY /item); } 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() { // 创建数据库 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; switch (mUriMatcher.match(uri)) { case Shopping.ITEM: ount db.delete(Shopping.TABLE_NAME, selection, selectionArgs); break; case Shopping.ITEM_ID: // 通过Uri获取Id,根据主键进行删除 String id uri.getPathSegments().get(1); System.out.println(String.valueOf(uri.getPathSegments().size())); count db.delete(Shopping.TABLE_NAME,Shopping.FIELD_ID id, selectionArgs); 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; 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; 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; 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)方法进行匹配根据不同的匹配值来返回不同的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平台可以识别。 sourceurl:http://blog.csdn.net/h3g2010/article/details/6093366 第二个版本 在Android中,每个程序都在自己的进程中运行,互不干扰.这样的好处不说了,但是带来的问题就是想要在程序之间实现数据共享,在没有其它工具的帮助下,就难以实现了.为了解决这个问题,ContentProvider就派上用场了. 一,说说ContentProvider怎么用. 1,把你想要共享出去的数据用一个URl表示出来.如:content://contacts/people/5(联系人信息中Id位5的联系人记录).或者这样也行:Uri person ContentUris.withAppendedId(People.CONTENT_URI,5);来封装. 2,所有的Content Providers都会实现一些共同的接口,可以通过唯一的ContentResolveer来向外提供数据,冰进行一系列的增删改查;ContentResolver cr getContentResplver(); 3,cr利用定义好的uri(作为参数送给cr封装好的方法里面进行一系列的操作); 至于ContentProvider的实例化,这些不需要我们去做,系统会做这件事.对于ContentProvider,正常情况下,只需一个,但是ContentResolver可以存在多个,在不同进程中的 ContentResolver可以使用同一个ContentProvider. 二,定义自己的ContentProvider 根据我个人的理解,这作用就有点像J2EE里面的DAO的作用. 1,实现一个定义节本字段的类.示例如下: public class NotePad { //ContentProvider的uri public static final String AUTHORITY com.google.provider.NotePad; private NotePad(){} // 定义基本字段 public static final class Notes implements BaseColumns { private Notes(){} public static final Uri CONTENT_URI Uri.parse(content:// AUTHORITY /notes); // 新的MIME类型-多个 public static final String CONTENT_TYPE vnd.android.cursor.dir/vnd.google.note; // 新的MIME类型-单个 public static final String CONTENT_ITEM_TYPE vnd.android.cursor.item/vnd.google.note; public static final String DEFAULT_SORT_ORDER modified DESC; //字段 public static final String TITLE title; public static final String NOTE note; public static final String CREATEDDATE created; public static final String MODIFIEDDATE modified; } } 解释一下MIME类型,假如你要处理的数据类型是新的类型,就得定义一个新的MIME类型,一边ContentProvider.getType(url)来调用; 粉单个与多个; 2,创建自己的ContentProvider 如果要共享的是数据库,我们在这里可以封装一个SqlLiteOpenHelper,以便建库建表 ,对于 SqlLiteOpenHelper 用过数据库的人应该都懂,在这里就不赘述了; 然后在ContentProvider里面实现增删改查,另外如果有自定义类型的话,还的在ContentProvider刘main实现一个方法 public String getType(Uri uri) { switch (sUriMatcher.match(uri)) { case NOTES: return Notes.CONTENT_TYPE; case NOTE_ID: return Notes.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException(Unknown URI uri); } } 实例如下: public class NotePadProvider extends ContentProvider { private static final String TAG NotePadProvider; // 数据库名 private static final String DATABASE_NAME note_pad.db; private static final int DATABASE_VERSION 2; // 表名 private static final String NOTES_TABLE_NAME notes; private static HashMapString, String sNotesProjectionMap; private static final int NOTES 1; private static final int NOTE_ID 2; private static final UriMatcher sUriMatcher; private DatabaseHelper mOpenHelper; //创建表SQL语句 private static final String CREATE_TABLECREATE TABLE NOTES_TABLE_NAME ( Notes._ID INTEGER PRIMARY KEY, Notes.TITLE TEXT, Notes.NOTE TEXT, Notes.CREATEDDATE INTEGER, Notes.MODIFIEDDATE INTEGER );; static { sUriMatcher new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(NotePad.AUTHORITY, notes, NOTES); sUriMatcher.addURI(NotePad.AUTHORITY, notes/#, NOTE_ID); sNotesProjectionMap new HashMapString, String(); sNotesProjectionMap.put(Notes._ID, Notes._ID); sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE); sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE); sNotesProjectionMap.put(Notes.CREATEDDATE, Notes.CREATEDDATE); sNotesProjectionMap.put(Notes.MODIFIEDDATE, Notes.MODIFIEDDATE); } private static class DatabaseHelper extends SQLiteOpenHelper { //构造函数-创建数据库 DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } //创建表 Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE); } //更新数据库 Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(DROP TABLE IF EXISTS notes); onCreate(db); } } Override public boolean onCreate() { mOpenHelper new DatabaseHelper(getContext()); return true; } Override //查询操作 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb new SQLiteQueryBuilder(); switch (sUriMatcher.match(uri)) { case NOTES: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap); break; case NOTE_ID: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap); qb.appendWhere(Notes._ID uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException(Unknown URI uri); } String orderBy; if (TextUtils.isEmpty(sortOrder)) { orderBy NotePad.Notes.DEFAULT_SORT_ORDER; } else { orderBy sortOrder; } SQLiteDatabase db mOpenHelper.getReadableDatabase(); Cursor c qb.query(db, projection, selection, selectionArgs, null, null, orderBy); c.setNotificationUri(getContext().getContentResolver(), uri); return c; } Override // 如果有自定义类型必须实现该方法 public String getType(Uri uri) { switch (sUriMatcher.match(uri)) { case NOTES: return Notes.CONTENT_TYPE; case NOTE_ID: return Notes.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException(Unknown URI uri); } } Override //插入数据库 public Uri insert(Uri uri, ContentValues initialValues) { if (sUriMatcher.match(uri) ! NOTES) { throw new IllegalArgumentException(Unknown URI uri); } ContentValues values; if (initialValues ! null) { values new ContentValues(initialValues); } else { values new ContentValues(); } Long now Long.valueOf(System.currentTimeMillis()); if (values.containsKey(NotePad.Notes.CREATEDDATE) false) { values.put(NotePad.Notes.CREATEDDATE, now); } if (values.containsKey(NotePad.Notes.MODIFIEDDATE) false) { values.put(NotePad.Notes.MODIFIEDDATE, now); } if (values.containsKey(NotePad.Notes.TITLE) false) { Resources r Resources.getSystem(); values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled)); } if (values.containsKey(NotePad.Notes.NOTE) false) { values.put(NotePad.Notes.NOTE, ); } SQLiteDatabase db mOpenHelper.getWritableDatabase(); long rowId db.insert(NOTES_TABLE_NAME, Notes.NOTE, values); if (rowId 0) { Uri noteUri ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new SQLException(Failed to insert row into uri); } Override //删除数据 public int delete(Uri uri, String where, String[] whereArgs) { SQLiteDatabase db mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { case NOTES: count db.delete(NOTES_TABLE_NAME, where, whereArgs); break; case NOTE_ID: String noteId uri.getPathSegments().get(1); count db.delete(NOTES_TABLE_NAME, Notes._ID noteId (!TextUtils.isEmpty(where) ? AND ( where ) : ), whereArgs); break; default: throw new IllegalArgumentException(Unknown URI uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } Override //更新数据 public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { SQLiteDatabase db mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { case NOTES: count db.update(NOTES_TABLE_NAME, values, where, whereArgs); break; case NOTE_ID: String noteId uri.getPathSegments().get(1); count db.update(NOTES_TABLE_NAME, values, Notes._ID noteId (!TextUtils.isEmpty(where) ? AND ( where ) : ), whereArgs); break; default: throw new IllegalArgumentException(Unknown URI uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } } 这样我们就实现了一个自定义的ContentProvider,档然最后不要忘记一件事情了,在AndroidMinifest.xml中声明我们定义好的ContentProvider provider android:nameNotePadProvider android:authoritiescom.google.provider.NotePad/ 好了,一切OK!