- 浏览: 263426 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (88)
- JAVA / base (26)
- JAVA / web (12)
- JAVA / Lib-tools (5)
- SERVER / tomcat (4)
- DB / mysql (4)
- DB / mongodb (2)
- DB / memcached (2)
- DB / redis (2)
- WEB / Front-end (3)
- WEB / security (4)
- WEB / css (2)
- WEB / js (4)
- OS / linux (3)
- IT / Architecture (4)
- IT / other (2)
- Android (9)
- Go (1)
- Other (1)
- OS / Mac (2)
最新评论
-
Zero2Max:
哈哈,马士兵老师也发现了。
java实现接口的bug -
xly1981:
能像CSRF攻击一样带个图就更棒了
XSS跨站攻击 -
xmong:
df274119386 写道在javascript中看到下面的 ...
CSRF攻击与防御策略 -
df274119386:
在javascript中看到下面的语句 e.value = t ...
CSRF攻击与防御策略 -
xmong:
yzxqml 写道xmong 写道yzxqml 写道tomca ...
Tomcat集群
android数据存储之ContentProvider
在android中应用的数据一般都是私有的,如果两个应用之间要共享数据,可以通过Content provider来实现。即是,如果一个应用实现了ContentProvider接口,就可以将自己的数据暴露出去,其他应用就可以通过ContentResolver来获取ContentProvider提供的接口服务,只是这种数据访问是通过RUI来表示的,这样就实现应用之间的数据共享。
在android中提供两类数据共享,一类是系统应用的数据共享,即系统应用已经实现了ContentProvider接口,只需要在其他应用中调用ContentResolver就可以访问。另一类是自定义数据共享,需要自己去实现ContentProvider接口。
(1)ContentProvider(android.content.ContentProvider),实现这个接口可以将应用的数据服务分布出去供其他应用访问。ContentProvider为存储和获取数据提供统一的接口。实现这个接口需要实现下面几个方法。
ContentProvider中对数据操作的方法都有一个android.net.Uri类型的参数,该参数代表操作数据的唯一标识。
content://com.example.MyDatabase/users/#
URI由三部分组成格式为:scheme+authority+path,scheme是content://表示移动的协议标识。authority用于唯一标识这个ContentProvider,一般以类的全名命名。path是/user/#可以用来表示我们要操作的数据。
Android提供了两个工具类来对Uri进行操作:UriMatcher的Uri进行注册和匹配,ContentUris对Uri进行组装。
基于前面sqlite的列子我们可以通过实现下面的列子来叙述android中ContentProvider的创建和使用。
设计如下:
MyDatabase:数据库结构类,是一个常量类存储数据库结构信息。
MysqliteDatabase:sqlite数据库操作类,通过该类构建获取SQLiteDatabase对象操作数据库。
MyContentProvider:继承ContentProvider类,实现ContentProvider类的方法。
Activity4:Activity类。
MyDatabase实现如下:
MySqliteDatabase实现如下:
MyContentProvider实现如下:
Activity4实现如下:
修改AndroidManifest.xml文件,分布ContentProvider服务。
上面的配置是name属性是指向自定义ContentProvider类,authorities属性是配置该ContentProvider uri的authority。
运行程序:
后台输出:
contentProvider create
在输入框中输入“xmong”,点击insert按钮,后台输出:
contentProvider insert
content://com.contentProvider.MyDatabase/users/1
清空输入框,点击query按钮,后台输出:
contentProvider query
_id:1,name:xmong
……
从操作结果我们可以知道ContentProvider的分布成功,调用也成功。
源代码下载:http://xmong.iteye.com/blog/1852204
在android中应用的数据一般都是私有的,如果两个应用之间要共享数据,可以通过Content provider来实现。即是,如果一个应用实现了ContentProvider接口,就可以将自己的数据暴露出去,其他应用就可以通过ContentResolver来获取ContentProvider提供的接口服务,只是这种数据访问是通过RUI来表示的,这样就实现应用之间的数据共享。
在android中提供两类数据共享,一类是系统应用的数据共享,即系统应用已经实现了ContentProvider接口,只需要在其他应用中调用ContentResolver就可以访问。另一类是自定义数据共享,需要自己去实现ContentProvider接口。
(1)ContentProvider(android.content.ContentProvider),实现这个接口可以将应用的数据服务分布出去供其他应用访问。ContentProvider为存储和获取数据提供统一的接口。实现这个接口需要实现下面几个方法。
public Uri insert(Uri uri, ContentValues values);//插入数据 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder);//查去数据 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs); //更新数据 public int delete(Uri uri, String selection, String[] selectionArgs) ; //删除数据 public String getType(Uri uri); //获取数据的mime类型 public boolean onCreate(); //创建ContentProvider时回调该方法
ContentProvider中对数据操作的方法都有一个android.net.Uri类型的参数,该参数代表操作数据的唯一标识。
content://com.example.MyDatabase/users/#
URI由三部分组成格式为:scheme+authority+path,scheme是content://表示移动的协议标识。authority用于唯一标识这个ContentProvider,一般以类的全名命名。path是/user/#可以用来表示我们要操作的数据。
Android提供了两个工具类来对Uri进行操作:UriMatcher的Uri进行注册和匹配,ContentUris对Uri进行组装。
基于前面sqlite的列子我们可以通过实现下面的列子来叙述android中ContentProvider的创建和使用。
设计如下:
MyDatabase:数据库结构类,是一个常量类存储数据库结构信息。
MysqliteDatabase:sqlite数据库操作类,通过该类构建获取SQLiteDatabase对象操作数据库。
MyContentProvider:继承ContentProvider类,实现ContentProvider类的方法。
Activity4:Activity类。
MyDatabase实现如下:
package com.contentProvider; import android.net.Uri; import android.provider.BaseColumns; /** * 常量类表示数据库表结构 * @author xmong */ public class MyDatabase { //数据库名 public final static String DB_NAME = "db_test"; //数据库版本 public final static int DB_VERSION = 1; // public final static String AUTHORITY = "com.contentProvider.MyDatabase"; /** * User表结构, * 实现BaseColumns常量接口,包含两个默认属性_ID和_COUNT */ public static class User implements BaseColumns{ public final static String TAB_NAME = "user"; //表名 public final static String COL_NAME = "name"; //用户名 //访问该ContentProvider的URI public static final Uri CONTENT_URI = Uri.parse("content://"+AUTHORITY+"/users"); //该ContentProvider所返回的数据类型 public static final String CONTENT_TYPE_DIR = "vnd.android.cursor.dir/vnd.mydatabase.user"; public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.mydatabase.user"; //该ContentProvider的RUI匹配类型 public static final int URI_TYPE_DIR = 1; public static final int URI_TYPE_ITEM = 2; }
MySqliteDatabase实现如下:
package com.contentProvider; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; /** * @author xmong */ public class MySqliteDatabase{ //sqlite数据库对象 private SQLiteDatabase sqliteDatabase = null; /** * 数据库帮助类,继承SQLiteOpenHelper */ static class DatabaseHelper extends SQLiteOpenHelper{ /** * 构造数据库对象 * @param context context对象 * @param name 数据库名 * @param factory 可选游标工厂,通常可是null * @param version 当前数据库版本 */ public DatabaseHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } //根据context构建数据库帮助对象 public DatabaseHelper(Context context) { //调用自身构造方法 this(context, MyDatabase.DB_NAME, null, MyDatabase.DB_VERSION); } /** * 该函数是在第一次创建数据库的时候执行,即第一次调用SQLiteOpenHelper对象的 * getWritableDatabase()或getReadableDatabase()方法时才执行该方法 * 可用于执行数据库初始化工作 */ @Override public void onCreate(SQLiteDatabase db) { System.out.println("create table:"+ MyDatabase.User.TAB_NAME); //创建表sql语句 String sql = "create table "+MyDatabase.User.TAB_NAME +" ("+MyDatabase.User._ID+" integer primary key autoincrement," +MyDatabase.User.COL_NAME+" varchar(20))"; //执行sql语句 db.execSQL(sql); } /** * 第一个参数是SQLiteDatabase对象,第二个参数是旧的数据库版本,第三个参数是新的数据库版本号, * 可用于执行数据库的升级,将一个数据库从旧版本转变到新版本执行相应的操作 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //可执行一些升级或修改数据库操作 System.out.println("update database"); } } /** * 根据context构建sqlite数据库对象 * @param context */ public MySqliteDatabase(Context context) { /** * 通过调用数据库帮助对象SQLiteOpenHelper的getWritableDatabase()方法 * 获取一个可读写的数据库对象sqliteDatabase */ sqliteDatabase = (new DatabaseHelper(context)).getWritableDatabase(); } /** * 关闭数据库,数据库操作完后需要释放资源 */ public void close() { sqliteDatabase.close(); } /** * 获取sqliteDatabase对象 * @return */ public SQLiteDatabase getSqliteDatabase(){ return sqliteDatabase; } } }
MyContentProvider实现如下:
package com.contentProvider; import java.util.HashMap; import java.util.Map; 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.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; public class MyContentProvider extends ContentProvider{ private SQLiteDatabase sqLiteDatabase; //sqlite数据库对象 private static UriMatcher uriMatcher; private static Map<String, String> userProjectionMap; static { //注册需要匹配的uri,将uri与匹配码相匹配 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); //注册调用match()方法时,匹配content://com.contentProvider.MyDatabase/user路径,则返回匹配码1 uriMatcher.addURI(MyDatabase.AUTHORITY, "users", MyDatabase.User.URI_TYPE_DIR); uriMatcher.addURI(MyDatabase.AUTHORITY, "users/#", MyDatabase.User.URI_TYPE_ITEM); userProjectionMap = new HashMap<String, String>(); userProjectionMap.put(MyDatabase.User._ID, MyDatabase.User._ID); userProjectionMap.put(MyDatabase.User.COL_NAME, MyDatabase.User.COL_NAME); } //根据传入的URI,返回该URI所表示的数据MIME类型 @Override public String getType(Uri uri) { System.out.println("contentProvider getType"); switch(uriMatcher.match(uri)){ case MyDatabase.User.URI_TYPE_DIR: return MyDatabase.User.CONTENT_TYPE_DIR; case MyDatabase.User.URI_TYPE_ITEM: return MyDatabase.User.CONTENT_TYPE_ITEM; default: throw new IllegalArgumentException("Unknown URI:" + uri); } } //插入数据 @Override public Uri insert(Uri uri, ContentValues values) { System.out.println("contentProvider intert"); Uri insertUri = null; long id = sqLiteDatabase.insert(MyDatabase.User.TAB_NAME, null, values); if(id>0){ //生成uri:content://com.contentProvider.MyDatabase/user/id insertUri = ContentUris.withAppendedId(MyDatabase.User.CONTENT_URI, id); //通知监听器,数据已经改变 getContext().getContentResolver().notifyChange(insertUri, null); return insertUri; } return insertUri; } //查去数据 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { System.out.println("contentProvider query"); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); /** * 调用UriMatcher匹配uri类型,返回匹配码 * 根据不同的uri类型构建不同的sqlQuery */ switch (uriMatcher.match(uri)) { case MyDatabase.User.URI_TYPE_DIR: qb.setTables(MyDatabase.User.TAB_NAME); qb.setProjectionMap(userProjectionMap); break; case MyDatabase.User.URI_TYPE_ITEM: qb.setTables(MyDatabase.User.TAB_NAME); qb.setProjectionMap(userProjectionMap); qb.appendWhere(MyDatabase.User._ID+"="+uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("Unknown URI:" + uri); } //设置order by参数 Cursor cursor = qb.query(sqLiteDatabase, projection, selection, selectionArgs, null, null, null); return cursor; } //修改数据 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { System.out.println("contentProvider update"); switch (uriMatcher.match(uri)) { case MyDatabase.User.URI_TYPE_DIR: return sqLiteDatabase.update(MyDatabase.User.TAB_NAME, values, selection, selectionArgs); case MyDatabase.User.URI_TYPE_ITEM: String uid = uri.getPathSegments().get(1); return sqLiteDatabase.update(MyDatabase.User.TAB_NAME, values, MyDatabase.User._ID+"="+uid +(!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); default: throw new IllegalArgumentException("Unknown URI:" + uri); } } //删除数据 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { System.out.println("contentProvider delete"); switch (uriMatcher.match(uri)) { case MyDatabase.User.URI_TYPE_DIR: return sqLiteDatabase.delete(MyDatabase.User.TAB_NAME, selection, selectionArgs); case MyDatabase.User.URI_TYPE_ITEM: String uid = uri.getPathSegments().get(1); return sqLiteDatabase.delete(MyDatabase.User.TAB_NAME, MyDatabase.User._ID+"="+uid +(!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); default: throw new IllegalArgumentException("Unknown URI:" + uri); } } //该方法在ContentProvider创建时被执行 @Override public boolean onCreate() { System.out.println("contentProvider create"); //获取sqLiteDatabase对象 sqLiteDatabase = (new MySqliteDatabase(getContext())).getSqliteDatabase(); return false; } }
Activity4实现如下:
package com.contentProvider; import com.example.R; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; public class Activity4 extends Activity { private EditText editText; //输入框 private Button insertBtn; //插入按钮 private Button queryBtn; //查询按钮 private Button updateBtn; //更新按钮 private Button deleteBtn; //删除按钮 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity3); //从视图中获取控件对象 editText = (EditText)findViewById(R.id.text); insertBtn = (Button)findViewById(R.id.insert); queryBtn = (Button)findViewById(R.id.query); updateBtn = (Button)findViewById(R.id.update); deleteBtn = (Button)findViewById(R.id.delete); //为按钮对象设置点击事件 insertBtn.setOnClickListener(insertBtnClick); queryBtn.setOnClickListener(queryBtnClick); updateBtn.setOnClickListener(updateBtnClick); deleteBtn.setOnClickListener(deleteBtnClick); } //插入按钮点击事件监听器 OnClickListener insertBtnClick = new OnClickListener() { @Override public void onClick(View v) { String text = editText.getText().toString().trim(); ContentValues cv = new ContentValues(); cv.put(MyDatabase.User.COL_NAME, text); Uri uri = getContentResolver().insert(MyDatabase.User.CONTENT_URI, cv); System.out.println(uri.toString()); } }; //查取按钮点击事件监听器 OnClickListener queryBtnClick = new OnClickListener() { @Override public void onClick(View v) { //根据输入框中是否输入id号来构建content的uri String text = editText.getText().toString().trim(); String uidUri = TextUtils.isEmpty(text)? "":"/"+text; Uri uri = Uri.parse(MyDatabase.User.CONTENT_URI+uidUri); Cursor cursor = getContentResolver().query(uri, new String[]{MyDatabase.User._ID, MyDatabase.User.COL_NAME}, null, null, null); //遍历游标输出查取的数据 for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){ String str = MyDatabase.User._ID+":"+cursor.getInt(cursor.getColumnIndex(MyDatabase.User._ID)) +","+MyDatabase.User.COL_NAME+":"+cursor.getString(cursor.getColumnIndex(MyDatabase.User.COL_NAME)); System.out.println(str); } } }; //修改按钮点击事件监听器 OnClickListener updateBtnClick = new OnClickListener() { @Override public void onClick(View v) { String text = editText.getText().toString().trim(); String[] arr = text.split(","); ContentValues cv = new ContentValues(); cv.put(MyDatabase.User.COL_NAME, arr[1]); String uidUri = TextUtils.isEmpty(arr[0])? "":"/"+arr[0]; Uri uri = Uri.parse(MyDatabase.User.CONTENT_URI+uidUri); getContentResolver().update(uri, cv, null, null); } }; //删除按钮点击事件监听器 OnClickListener deleteBtnClick = new OnClickListener() { @Override public void onClick(View v) { String text = editText.getText().toString().trim(); String uidUri = TextUtils.isEmpty(text)? "":"/"+text; Uri uri = Uri.parse(MyDatabase.User.CONTENT_URI+uidUri); getContentResolver().delete(uri, null, null); } }; //按键事件 public boolean onKeyUp(int keyCode, KeyEvent event) { //当按键为回退键是结束这个activity if (keyCode == KeyEvent.KEYCODE_BACK) { Activity4.this.finish(); } return true; }; }
修改AndroidManifest.xml文件,分布ContentProvider服务。
<provider android:name="com.contentProvider.MyContentProvider" android:authorities="com.contentProvider.MyDatabase"></provider>
上面的配置是name属性是指向自定义ContentProvider类,authorities属性是配置该ContentProvider uri的authority。
运行程序:
后台输出:
contentProvider create
在输入框中输入“xmong”,点击insert按钮,后台输出:
contentProvider insert
content://com.contentProvider.MyDatabase/users/1
清空输入框,点击query按钮,后台输出:
contentProvider query
_id:1,name:xmong
……
从操作结果我们可以知道ContentProvider的分布成功,调用也成功。
源代码下载:http://xmong.iteye.com/blog/1852204
发表评论
-
android数据存储之Network
2013-04-24 00:00 1121android数据存储之Network ... -
android数据存储之SDCard
2013-04-24 00:00 1568android数据存储之SDCard 我们都知道androi ... -
android数据存储之Sqlite
2013-04-23 23:05 1929android数据存储之Sqlite Sqlite是轻量级的 ... -
android数据存储之Files
2013-04-23 23:03 1523android数据存储之Files Files存储可以通过A ... -
android数据存储之SharedPreferences
2013-04-23 23:01 1506android数据存储之SharedPreferences ... -
android数据存储
2013-04-23 17:55 1359Android的数据存储 在Android中提供了6种数据存 ... -
Android和Handler那些事
2013-04-16 18:59 1340Android和Handler那些事 目录 1 HANDL ... -
从java web到android
2013-04-16 15:15 1472几年来一直从事java web的开发,最近组里开始接手一些an ...
相关推荐
ContentProvider提供了一种标准化的机制,使得不同的应用程序可以安全、有序地访问和共享数据,无论这些数据是存储在SQLite数据库、文件系统还是其他持久化存储中。下面我们将深入探讨ContentProvider的工作原理及其...
在Android系统中,ContentProvider是一种核心组件,它允许应用程序之间共享数据,而无需直接访问对方的内部存储。在本教程中,我们将深入探讨如何利用ContentProvider来操作文件,以及其在跨应用数据传输中的作用。 ...
总结来说,SQLite是Android应用中的主要数据存储方式,而ContentProvider则提供了一种安全、标准化的方式来管理和共享这些数据。开发者应熟悉这两者,以便在实际项目中有效地进行数据库操作。通过熟练掌握...
在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享和跨应用数据访问的角色。自定义ContentProvider允许开发者创建自己的数据存储解决方案,并与其他应用程序无缝交互。这篇博客将深入探讨如何在...
首先,ContentProvider主要负责管理和提供数据,这些数据可以存储在SQLite数据库、文件系统或者网络上。它通过定义标准的CRUD(创建、读取、更新、删除)操作接口,使得其他应用能够方便地访问这些数据。...
在Android开发中,ContentProvider是四大组件之一,它充当了数据共享的桥梁,使得不同的应用程序之间可以安全地访问和共享数据。本篇文章将详细介绍如何在Android中实现一个简单的ContentProvider。 首先,理解...
1. 数据存储:数据存储在SQLite数据库中,通过ContentProvider进行访问。 2. 数据监听:使用`ContentObserver`注册到ContentResolver,监听特定Uri对应的数据变化。 3. 数据变更:当ContentProvider中的数据发生变化...
Android系统使用SQLite作为默认的轻量级数据库,它支持SQL语法,适用于小型数据存储。在Android中,我们通常通过SQLiteOpenHelper这个类来创建、升级和管理数据库。这个类提供了getWritableDatabase()和...
- ContentProvider是Android系统中提供数据访问的标准化接口,它封装了数据存储和读取的操作。 - 一个ContentProvider由四个主要方法构成:`query()`, `insert()`, `update()`, `delete()`,分别对应查询、插入、...
在 Android 中,ContentProvider 是一个抽象的类,它提供了一种方式来存储和管理数据。它可以将数据暴露给其他应用程序,以便它们可以访问和操作这些数据。ContentProvider 可以提供多种类型的数据,包括数据库、...
在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享和访问的重要角色。ContentProvider使得应用程序可以将自己的数据结构暴露给其他应用,同时也能够访问其他应用公开的数据。本篇文章将全面解析...
ContentProvider的数据存储方式多样,可以是SQLite数据库、文件系统或者网络等。具体实现取决于你的需求,但通常推荐使用SQLite数据库,因为它是Android内置的、轻量级的数据库系统。 5. 使用ContentResolver 其他...
很多情况下,ContentProvider会与SQLite数据库配合使用,将数据存储在SQLite数据库中。ContentProvider的insert、query、update和delete方法会对应到SQLite数据库的相应操作。这种方式使得数据管理更加规范,同时也...
Android 平台中实现数据存储的五种方式分别是:使用 SharedPreferences 存储数据、文件存储数据、SQLite 数据库存储数据、使用 ContentProvider 存储数据和网络存储数据。 使用 SharedPreferences 存储数据 ...
ContentProvider使得应用程序可以安全地分享内部数据,同时也为其他应用程序提供了一种标准接口来访问这些数据,无论是SQLite数据库、文件系统还是任何其他形式的数据存储。在这个“Android之ContentProvider事例”...
首先,ContentProvider是Android四大组件之一,它作为数据存储和访问的桥梁,允许不同应用之间共享数据。ContentProvider基于URI(统一资源标识符)来暴露数据,并通过标准的CRUD(创建、读取、更新、删除)操作管理...
4. **处理数据存储**: 通常,ContentProvider会与SQLite数据库配合使用,因此你需要创建一个SQLiteOpenHelper子类,用于创建和升级数据库。在ContentProvider的`query()`等方法中,使用SQLiteOpenHelper来执行SQL...
ContentProvider使得应用程序之间能够安全、有序地访问彼此的数据,无论是系统内置的数据(如联系人、日历等)还是自定义的数据存储。下面我们将深入探讨ContentProvider的使用,并结合"ContentProviderApp1"和...
在Android应用开发中,SQLite和ContentProvider是两个非常重要的组件,它们主要用于数据存储和数据共享。SQLite是一个轻量级的数据库系统,适用于移动设备,而ContentProvider则是一种接口,允许不同应用程序之间...