Android组件(Content Provider)
2016-05-19 15:41
645 查看
1.目录:
1.Content Provider概述
2.Content Provider共享数据过程
3.Content Provider作用
4.Content Provider创建
5.Content Provider数据管理(数据的增删改查)
6.访问Content Provider获取数据
7.UriMatcher & Uri
2.Content Provider概述:
Content Provider(内容提供者),明白它的含义我们的明白两点,内容是啥?提供给谁?
OK,内容即数据,来自File或者sqlite数据库,该组件主要用于建立一个统一的接口
提供给其他应用访问自己应用数据,同时也可利用他获取其他应用数据,达到信息交互的效果
3.Content Provider共享数据过程(例子解释):
抗战时期的一个地下情报组织(我的APP),建立一个咖啡馆(Content Provider)向上级提供
情报(数据),上级(其他APP)需要情报的时候会派接头人(ContentResolver)给他暗号和
地址(URI),让他到咖啡馆来获取情报。
ps:上面有几个关键的名词ContentResolver 数据 URI他们的作用上面的例子应该能看出来(后面深入讲解)
4.Content Provider作用:
4.1 向其他app组件提供共享数据
4.2 存储及检索数据
ps:下面用一个例子带描述的形式学习Content Provider的创建管理,以及访问
5.Content Provider创建
5.1 创建Sqlite数据库(伙伴们不知道Sqlite没关系我们先用它讲解Content Provider的使用,后面再单独学习Sqlite)
5.1.1 创建数据库管理类MyDBOpenHelper继承SQLiteOpenHelper
5.2 实现ContentProvider类
ContentProvider类中需要继承实现了方法:
1)public boolean onCreate() (创建ContentProvider时调用)
2)public Cursor query(Uri, String[], String, String[], String) ( 查询指定URI的content provider 返回Cursor)
3)public Uri insert(Uri, ContentValues) (插入数据到指定Uri的ContentProvider)
4)public int update(Uri, ContentValues, String, String[]) (更新指定Uri的ContentProvider数据)
5)public int delete(Uri, String, String[]) (删除指定Uri的ContentProvider数据)
6)public String getType(Uri) (获得指定数据的MIME类型)
MyContentProvider 类实现:
5.3 Manifest.xml注册ContentProvider
6.Content Provider数据管理(数据增删改查)
Content Provider数据管理可用ContentProvider实现类;或者,通过数据库管理类SQLiteOpenHelper去实例化SQLiteDatabase操作类
从而实现数据管理(ContentProvider实现类上面已经实现,通过SQLiteDatabase管理的部分准备在sqlite那一部分去学习)
7.访问Content Provider获取数据
我们新建一个android工程去访问上面的ContentProvider
7.1 MainActivity.java(通过ContentResolver访问ContentProvider获取数据并绑定到UI展示)
7.3 ListView 自定义布局list.xml
8.UriMatcher & Uri
UriMatcher:我们先解释一下,UriMatcher用在哪儿,作用是啥?
UriMatcher用在Contentprovider实现类中,用来创建“暗号”接口路径和建立路径与code的匹配关系
//authority即是你注册provider的时候定义的路径(包名),path即访问路径可为table名,也可自定义
//code只是一个匹配码,一个Uri对应一个匹配码,用于后面对不同的uri执行不同的操作
uriMatcher.addURI(authority, path, code);
URI:上面提到过Uri相当于暗号和地址,什么意思呢,就是我定义一个Contentprovider开放一个“暗号”接口,好你ContentResolver
想要获得我提供的数据,你先根据地址找到我并告诉我暗号,如果暗号匹配我就把数据给你,这就是URI主要作用。
参考:/article/1358725.html
PS:学习大神们的,自己的思路总结,谢谢大神们的分享!
1.Content Provider概述
2.Content Provider共享数据过程
3.Content Provider作用
4.Content Provider创建
5.Content Provider数据管理(数据的增删改查)
6.访问Content Provider获取数据
7.UriMatcher & Uri
2.Content Provider概述:
Content Provider(内容提供者),明白它的含义我们的明白两点,内容是啥?提供给谁?
OK,内容即数据,来自File或者sqlite数据库,该组件主要用于建立一个统一的接口
提供给其他应用访问自己应用数据,同时也可利用他获取其他应用数据,达到信息交互的效果
3.Content Provider共享数据过程(例子解释):
抗战时期的一个地下情报组织(我的APP),建立一个咖啡馆(Content Provider)向上级提供
情报(数据),上级(其他APP)需要情报的时候会派接头人(ContentResolver)给他暗号和
地址(URI),让他到咖啡馆来获取情报。
ps:上面有几个关键的名词ContentResolver 数据 URI他们的作用上面的例子应该能看出来(后面深入讲解)
4.Content Provider作用:
4.1 向其他app组件提供共享数据
4.2 存储及检索数据
ps:下面用一个例子带描述的形式学习Content Provider的创建管理,以及访问
5.Content Provider创建
5.1 创建Sqlite数据库(伙伴们不知道Sqlite没关系我们先用它讲解Content Provider的使用,后面再单独学习Sqlite)
5.1.1 创建数据库管理类MyDBOpenHelper继承SQLiteOpenHelper
package com.demo.contentproviderdemo; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class MyDBOpenHelper extends SQLiteOpenHelper { /* * 带参构造方法,供外部实例化MyDBOpenHelper */ public MyDBOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } /* * 数据库创建时调用,做一些创建数据表和初始化工作(non-Javadoc) */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE user(_id integer primary key autoincrement, user_name varchar(20))"); Log.i("SYS", "create table user"); } /* * 数据库传入版本与传入的版本不同时执行 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS user"); onCreate(db); } }
5.2 实现ContentProvider类
ContentProvider类中需要继承实现了方法:
1)public boolean onCreate() (创建ContentProvider时调用)
2)public Cursor query(Uri, String[], String, String[], String) ( 查询指定URI的content provider 返回Cursor)
3)public Uri insert(Uri, ContentValues) (插入数据到指定Uri的ContentProvider)
4)public int update(Uri, ContentValues, String, String[]) (更新指定Uri的ContentProvider数据)
5)public int delete(Uri, String, String[]) (删除指定Uri的ContentProvider数据)
6)public String getType(Uri) (获得指定数据的MIME类型)
MyContentProvider 类实现:
package com.demo.contentproviderdemo; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.util.Log; /** * * @author Andy_lau * */ public class MyContentProvider extends ContentProvider { private MyDBOpenHelper dbOpenHelper; // 无uri匹配时默认匹配码NO_MATCH private static final UriMatcher MATCHER = new UriMatcher( UriMatcher.NO_MATCH); private static final int USERS = 1; private static final int USER = 2; // 静态代码块建立uri和匹配码的映射关系,方便后面根据不同uri进行不同操作 static { MATCHER.addURI("com.demo.contentproviderdemo", "Users", USERS); MATCHER.addURI("com.demo.contentproviderdemo", "Users/#", USER); } /* * MyContentProvider创建时调用,做一些初始化方法 */ @Override public boolean onCreate() { // 实例化数据库管理类MyDBOpenHelper dbOpenHelper = new MyDBOpenHelper(this.getContext(), "user.db", null, 1); return true; } /* * 接收外部数据进行数据查询操作 */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor = null; SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); switch (MATCHER.match(uri)) { case USERS: cursor = db.query("user", projection, selection, selectionArgs, null, null, sortOrder); break; case USER: long user_id = ContentUris.parseId(uri); String where = "_id =" + user_id; where = selection + "and" + where; cursor = db.query("user", projection, where, selectionArgs, null, null, sortOrder); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } return cursor; } /* * 返回数据的MIME类型 */ @Override public String getType(Uri uri) { switch (MATCHER.match(uri)) { case USERS: // 数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头 return "vnd.android.cursor.dir/Users"; case USER: // 单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头 return "vnd.android.cursor.item/Users"; default: throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); } } /* * 接收外部数据进行数据插入操作 Uri:外部传入的uri ContentValues:外部传入的数据集合 */ @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); switch (MATCHER.match(uri)) { case USERS: // 特别说一下第二个参数是当name字段为空时,将自动插入一个NULL。 long rowid = db.insert("user", null, values); Uri insertUri = ContentUris.withAppendedId(uri, rowid);// 得到代表新增记录的Uri this.getContext().getContentResolver().notifyChange(uri, null); return insertUri; default: throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); } } /* * 接收外部数据进行数据删除操作 selection:sql语句中where后面的参考字段 selectionArgs参考字段的值 */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); int count = 0; switch (MATCHER.match(uri)) { case USERS: count = db.delete("user", selection, selectionArgs); return count; case USER: // 从uri中获取id long id = ContentUris.parseId(uri); // 将id拼接到查询语句 String where = "_id=" + id; if (selection != null && !"".equals(selection)) { where = selection + " and " + where; } count = db.delete("user", where, selectionArgs); return count; default: throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); } } /* * 接收外部数据进行数据更新操作 */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); int count = 0; switch (MATCHER.match(uri)) { case USERS: count = db.update("user", values, selection, selectionArgs); return count; case USER: long id = ContentUris.parseId(uri); String where = "_id=" + id; if (selection != null && !"".equals(selection)) { where = selection + " and " + where; } count = db.update("user", values, where, selectionArgs); return count; default: throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); } } }
5.3 Manifest.xml注册ContentProvider
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.Andy.contentprovider" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- authorities与MyContentProvider中uriMatcher的第一个参数一致 --> <provider android:name=".MyContentProvider" android:authorities="com.Andy.contentprovider" > </provider> </application> </manifest>
6.Content Provider数据管理(数据增删改查)
Content Provider数据管理可用ContentProvider实现类;或者,通过数据库管理类SQLiteOpenHelper去实例化SQLiteDatabase操作类
从而实现数据管理(ContentProvider实现类上面已经实现,通过SQLiteDatabase管理的部分准备在sqlite那一部分去学习)
7.访问Content Provider获取数据
我们新建一个android工程去访问上面的ContentProvider
7.1 MainActivity.java(通过ContentResolver访问ContentProvider获取数据并绑定到UI展示)
package com.test.contentresvoler; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.widget.SimpleCursorAdapter; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.Toast; public class MainActivity extends Activity { private Button button; private ListView listView; final String uri = "content://com.demo.contentproviderdemo/Users"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 绑定button按钮 button = (Button) findViewById(R.id.button1); // 绑定listview listView = (ListView) findViewById(R.id.list); // 设置button监听 button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 实例化ContentResolver ContentProvider管理类 ContentResolver contentResolver = getContentResolver(); // 根据String地址实例化Uri(访问ContentProvider路径) Uri addUri = Uri .parse("content://com.demo.contentproviderdemo/Users"); // 实例化数据封装类ContentValues ContentValues values = new ContentValues(); // 放入数据 /* values.put("_id", 3); Log.i("_id", values.get("_id")+"");*/ values.put("user_name", "Andy"); // 通过管理类将数据与Uri整合 Uri uri = contentResolver.insert(addUri, values); // toast提示信息 Toast.makeText(MainActivity.this, "添加成功", Toast.LENGTH_LONG) .show(); } }); // 实例化ContentResolver ContentProvider管理类 ContentResolver contentResolver = getContentResolver(); // 根据String地址实例化Uri(访问ContentProvider路径) Uri selectUri = Uri .parse("content://com.demo.contentproviderdemo/Users"); // 通过通过管理类将数据与Uri整合contentResolver实例方法获取操作游标Cursor实例 Cursor cursor = contentResolver .query(selectUri, null, null, null, null); if (cursor == null) { Log.i("report", "cursor is null"); } else { while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex("_id")); String user_name = cursor.getString(cursor.getColumnIndex("user_name")); Log.i("id&name", id+"&"+user_name); Toast.makeText(MainActivity.this, id+"&"+user_name, Toast.LENGTH_LONG).show(); } // 设置listview适配器,适配布局和数据 /* * MainActivity.this */ ListAdapter listAdapter = new SimpleCursorAdapter(MainActivity.this, R.layout.list, cursor, new String[] { "_id", "user_name" }, new int[] { R.id.value_id, R.id.value_name },0); listView.setAdapter(listAdapter); } // 设置listview item监听 listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 通过位置获取listview显示内容,强制类型转换为Cursor Cursor cursor = (Cursor) listView.getItemAtPosition(position); // 通过cursor方法获取对应字段的值 int name = cursor.getColumnIndex("user_name"); // toast提示信息 Toast.makeText(MainActivity.this, name + "", Toast.LENGTH_LONG) .show(); } }); } }7.2 主UI布局activity_main.xml(展示查询结果)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.test.contentresvoler.MainActivity" > <!-- text的内容尽量写到 strings.xml中,方便国际化 --> <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="添加" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="25dp" android:layout_weight="1" android:gravity="center" android:text="编号" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="25dp" android:layout_weight="1" android:gravity="center" android:text="姓名" /> </LinearLayout> <ListView android:id="@+id/list" android:layout_width="wrap_content" android:layout_height="wrap_content" > </ListView> </LinearLayout>
7.3 ListView 自定义布局list.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/value_id" android:layout_gravity="center" android:gravity="center" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center" android:id="@+id/value_name" android:gravity="center" /> </LinearLayout>
8.UriMatcher & Uri
UriMatcher:我们先解释一下,UriMatcher用在哪儿,作用是啥?
UriMatcher用在Contentprovider实现类中,用来创建“暗号”接口路径和建立路径与code的匹配关系
//authority即是你注册provider的时候定义的路径(包名),path即访问路径可为table名,也可自定义
//code只是一个匹配码,一个Uri对应一个匹配码,用于后面对不同的uri执行不同的操作
uriMatcher.addURI(authority, path, code);
URI:上面提到过Uri相当于暗号和地址,什么意思呢,就是我定义一个Contentprovider开放一个“暗号”接口,好你ContentResolver
想要获得我提供的数据,你先根据地址找到我并告诉我暗号,如果暗号匹配我就把数据给你,这就是URI主要作用。
参考:/article/1358725.html
PS:学习大神们的,自己的思路总结,谢谢大神们的分享!
相关文章推荐
- Android 属性动画(Property Animation) 完全解析 (下)
- PopularGitHub Android Libraries(android流行开源库分类)
- Android简单对话框、输入对话框、单选对话框、复选对话框、列表对话框、自定义对话框、时间对话框
- Android 属性动画(Property Animation) 完全解析 (上)
- AndroidStudio下SVN使用介绍
- Android基础之十六Handle机制
- 在android listview中使用editText无法获取焦点和输入窗
- Android--173个项目源码
- android 休眠唤醒机制分析(二) — early_suspend
- Android应用界面开发(二)
- android 休眠唤醒机制分析(一) — wake_lock
- Android动画集与自定义动画
- android design library提供的TabLayout的用法
- Android平台Overlay机制
- android:descendantFocusability
- 深入浅出RxJava四-在Android中使用响应式编程
- AndroidManifest合并原理
- Android开发实践 巧用Activity和Fragment
- Android贝塞尔动画实现QQ,虎牙等平台点赞效果初探
- 使用Netty进行Android与Server端通信实现文字发送接收与图片上传