- 浏览: 396051 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
surpassno:
南冠楚囚 写道如果是复制一个一位数组,那么改变复制后的数组并不 ...
java的system.arraycopy()方法 -
南冠楚囚:
如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。你 ...
java的system.arraycopy()方法 -
wxq5513866:
有密码,大家不要下载了,下载也解压不了,别上当了
android中调用webservice -
wxq5513866:
happyhan 写道还要密码啊 能否告知密码
android中调用webservice -
happyhan:
还要密码啊 能否告知密码
android中调用webservice
内容提供者(content provider)使一个应用程序的指定数据集提供给其他应用程序。这些数据可以存储在文件系统中、在一个SQLite数据库、或以任何其他合理的方式。内容提供者继承自ContentProvider 基类并实现了一个标准的方法集,使得其他应用程序可以检索和存储数据。然而,应用程序并不直接调用这些方法。相反,替代的是它们使用一个ContentResolver对象并调用它的方法。ContentResolver能与任何内容提供者通信,它与提供者合作来管理参与进来的进程间的通信。
在 Android 中,每个应用程序都是用自己的用户 ID 并在自己的进程中运行。这样的好处是,可以有效地保护系统及应用程序,避免被其他不正常德应用程序所影响,每个进程都拥有当数据需要在应用程序间共享时,我们就可以利用 ContentProvider 为数据定义一个 URI 。之后,其他应用程序对数据进行查询或者修改时,只需要从当前上下文对象获得一个 ContentResolver, 然后传入响应的 URI 就可以了。
ContentResolver 类为应用程序提供了接入 Content 机制的方法。要构造一个 ContentResolver 对象可以为构造方法 ContentResolver(Context context) 传入一个 Context 对象,也可以直接通过 Context 对象调用 getContentResolver() 方法获得 —— 有的 ContentResolver 对象后,就可以通过调用其 query() 、 insert() 、 update() 等方法来对数据进行操作了。
关于contentProvider中的MIME数据类型的分析
当在创建自己的ContentProvider的时,需要从抽象类ContentProvider中派生出自己的子类,并实现其中5个抽象方法:
其中getType(Uri) which returns the MIME type of data in the content provider根据帮助文档的解释,它返回一个MIME类型。
根据百度百科的解释:MIME:全称Multipurpose Internet Mail Extensions,多功能Internet 邮件扩充服务。它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
在ContentProvider的getType(Uri)方法中,可以显示的返回一个MIME类型,该方法返回一个字符串,可以是任意的字符串,当我们显示的返回该MIME类型的时候,相当于通过该方法的验证,Provider可以识别自身其他方法返回的Cursor的内容,不需要在进行更多的验证;如果返回其他的字符串(非android能够识别的MIME类型,例如直接返回当前的包名),则Provider在执行其他方法后,返回Cursor类型的时候,需要再次进行验证。
在上面的例子中,首先有一个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类使我们的重头戏,首先我们来看这一段代码:
UriMatcher表示一个Uri的匹配器,它会对我们请求的Uri进行匹配,而匹配的格式就是这里我们通过addURI()方法添加格式。
接下来,首先执行的就是getType(Uri)方法,下面来看该方法体中的代码:
当请求过来的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平台可以识别。
下半文来自CSDN博客感谢!
在 Android 中,每个应用程序都是用自己的用户 ID 并在自己的进程中运行。这样的好处是,可以有效地保护系统及应用程序,避免被其他不正常德应用程序所影响,每个进程都拥有当数据需要在应用程序间共享时,我们就可以利用 ContentProvider 为数据定义一个 URI 。之后,其他应用程序对数据进行查询或者修改时,只需要从当前上下文对象获得一个 ContentResolver, 然后传入响应的 URI 就可以了。
ContentResolver 类为应用程序提供了接入 Content 机制的方法。要构造一个 ContentResolver 对象可以为构造方法 ContentResolver(Context context) 传入一个 Context 对象,也可以直接通过 Context 对象调用 getContentResolver() 方法获得 —— 有的 ContentResolver 对象后,就可以通过调用其 query() 、 insert() 、 update() 等方法来对数据进行操作了。
关于contentProvider中的MIME数据类型的分析
当在创建自己的ContentProvider的时,需要从抽象类ContentProvider中派生出自己的子类,并实现其中5个抽象方法:
其中getType(Uri) which returns the MIME type of data in the content provider根据帮助文档的解释,它返回一个MIME类型。
根据百度百科的解释:MIME:全称Multipurpose Internet Mail Extensions,多功能Internet 邮件扩充服务。它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
在ContentProvider的getType(Uri)方法中,可以显示的返回一个MIME类型,该方法返回一个字符串,可以是任意的字符串,当我们显示的返回该MIME类型的时候,相当于通过该方法的验证,Provider可以识别自身其他方法返回的Cursor的内容,不需要在进行更多的验证;如果返回其他的字符串(非android能够识别的MIME类型,例如直接返回当前的包名),则Provider在执行其他方法后,返回Cursor类型的时候,需要再次进行验证。
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平台可以识别。
下半文来自CSDN博客感谢!
发表评论
-
android中调用webservice
2011-12-05 14:40 8241上篇文章发布的webservice ... -
android wifi开发
2011-11-29 09:52 2276最近做了个小项目,用到了wifi连接,通过wifi去控制一个w ... -
android读写文件
2011-11-22 09:24 1409android中读写文件分两部分。 1.手机flash读写 ... -
android adt myeclipse8.5离线安装
2011-11-14 15:51 5390Myeclipse 8.6 离线安装ADT 最近想在Myec ... -
android网络与通信
2011-03-31 10:52 1601三种网络接口简述 标准Java接口 java.net.*提 ... -
android多媒体
2011-03-31 09:47 1606OpenCore的另外一个 ... -
数据存储 shared preference
2011-03-30 20:32 1677Android中一共提供了四种数据存储方式: Shared P ... -
双缓冲技术
2011-03-30 19:30 1760java双缓冲技术是 ... -
Android的view重绘
2011-03-30 15:18 4723android中实现view的更新有两组方法,一组是inval ... -
Android中采用的MVC框架
2011-03-30 15:02 1900MVC是当前比较流行的框 ... -
Android单线程模型
2011-03-29 21:32 2995当第一次启动一个Android程序时,Android会自动创建 ... -
TabWidget
2011-03-26 10:03 1427Android TabWidget/TabHost有两种使用方 ... -
状态栏提示Notification
2011-03-26 09:33 1482当有未接电话或者短信时,在手机顶部状态栏就会出现一个小图标,提 ... -
Gallery 拖动效果
2011-03-26 09:01 1219public class Activity01 exten ... -
Android Contentresolver的使用
2011-03-24 16:44 2102Android提供了ContentProvider,一个程序可 ... -
Android SQLite
2011-03-24 10:36 2095SQLite 是一款非常流行的 ... -
android map的使用方法
2011-03-23 16:06 60581 Android Add-ons是Android中的可 ... -
android sdk的快速安装法
2011-03-23 14:53 20451.下载相关文件 下面的7个文件(当然,可以只下载其中一个) ... -
android的位置服务和地图
2011-03-22 19:21 1502实现位置服务的技术有GPS和google网络地图,将这些不同的 ... -
android 使用DOM解析xml
2011-03-22 16:52 1445美国地震信息网http://earthquake.usgs.g ...
相关推荐
在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享和访问的重要角色。ContentProvider使得应用程序可以将自己的数据结构暴露给其他应用,同时也能够访问其他应用公开的数据。本篇文章将全面解析...
在Android开发中,ContentProvider是一种重要的组件,它允许应用程序之间共享数据。本示例"android ContentProvider Demo"将深入探讨如何创建和使用ContentProvider来实现跨应用的数据交换。ContentProvider作为...
在Android开发中,ContentProvider是四大组件之一,它充当了数据共享的桥梁,使得不同的应用程序之间可以安全地访问和共享数据。本篇文章将详细介绍如何在Android中实现一个简单的ContentProvider。 首先,理解...
在Android应用开发中,数据持久化是一个至关重要的环节,而Android Room和ContentProvider是其中的两个关键组件。本文将深入探讨这两个技术,并结合实际案例,解释如何在Android应用中使用它们来管理和共享SQLite...
### android ContentProvider 详解 #### 一、ContentProvider 概述 ContentProvider 是 Android 四大组件之一,它主要用于在不同的应用程序之间实现数据共享。在 Android 中,每个应用程序都有自己的私有存储空间...
【Android ContentProvider详解】 ContentProvider是Android系统提供的一种机制,使得不同应用程序之间可以安全地共享数据。通过ContentProvider,开发者可以将自己的数据集暴露出来,供其他应用查询、添加、删除和...
在Android应用开发中,ContentProvider是一个至关重要的组件,它扮演着数据共享的角色,使得不同的应用程序之间可以安全地读写共享数据。"android contentprovider的例子"这个主题将带你深入理解ContentProvider的...
在Android开发中,ContentProvider是四大组件之一,它充当了一个数据共享的桥梁,使得不同的应用程序之间可以安全地访问和操作数据。本篇文章将深入探讨如何使用ContentProvider进行数据库的增删改查操作,并结合...
在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享和跨应用数据访问的角色。ContentProvider使得应用程序可以将自己的数据结构公开,让其他应用程序能够按照统一的方式进行读写操作,实现了不同...
在Android系统中,ContentProvider是一种核心组件,它允许应用程序之间共享数据,而无需直接访问对方的内部存储。在本教程中,我们将深入探讨如何利用ContentProvider来操作文件,以及其在跨应用数据传输中的作用。 ...
在Android开发中,ContentProvider是四大组件之一,它充当了数据共享的桥梁,使得不同的应用程序之间可以安全地访问和操作数据。本示例将详细解释如何在Android中使用ContentProvider。 1. **ContentProvider基本...
在Android系统中,ContentProvider是实现跨应用数据共享的关键组件,它允许应用程序暴露自己的数据集,使得其他应用可以通过标准的接口进行访问。本教程将深入解析ContentProvider的使用及其源码,结合SQLite数据库...
### Android ContentProvider 总结 #### 一、ContentProvider 概述 ContentProvider 是 Android 四大组件之一,主要用于在不同的应用程序之间实现数据共享。它通过定义一套标准接口,允许其他应用通过这些接口来...
在Android应用开发中,ContentProvider是一个非常重要的组件,它扮演着数据共享和访问的角色。ContentProvider使得不同应用程序之间可以安全地共享数据,就像数据库一样,但又超越了数据库的范畴,因为它提供了统一...
在Android开发中,ContentProvider是Android四大组件之一,它的主要职责是实现应用程序间的数据共享。ContentProvider通过统一的接口让其他应用能够访问和修改特定的数据集,这些数据可能存储在SQLite数据库、文件...
在Android开发中,ContentProvider是四大组件之一,它充当了应用程序间数据共享的桥梁。ContentProvider使得一个应用的数据可以被其他应用访问,同时也为数据提供了统一的接口。本篇文章将深入探讨ContentProvider的...
在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享的角色,使得不同应用程序间可以安全地交换数据。本示例将深入讲解如何创建和使用ContentProvider。 首先,我们来理解ContentProvider的基本概念...