ContentProvider
2015-12-31 22:55
561 查看
ContentProvider表示“内容提供者”;
ContentProvider是一种数据共享机制,它将允许其它应用程序对自身应用程序中的数据
执行增删改查操作;
ContentProvider是Android核心组件之一,因此,开发人员在创建它时,需要自定义继承
ContentProvider,而且,它需要在项目清单文件中(AndroidMainfest.xml)中注册;
ContentProvider需要定义用于访问数据的URI,当其他应用程序知晓对应的URI时,即可
执行数据的相关操作。
ContentProvider无需被激活,当配置了ContentProvider的应用程序被安装到设备上,
同一台设备上的其它应用程序随时都可以访问它的数据。
ContentProvider的开发步骤:
自定义类继承android,content.ContentProvider类;
重写android.content.ContentProvider类中声明的抽象方法;
在AndroidMainfest.xml文件中配置ContentProvider:
创建<application>节点下添加<provider>子节点;
配置android.name属性,指定ContentProvider类;
配置android.authorities属性,指定用于访问数据的URI的host部分;
配置android:exported属性,指定值为true。
标准URI:scheme://host:port/path
例如:http://www.goole.com:80/android
注意:基于ContentProvider中数据增删改查的方法与使用SQLite数据库时使用的方法极为相似,因此,
大多数的ContentProvider共享的数据的方式都是通过操作SQLite数据库完成的,但是,ContentProvider
与SQLite数据库没有必然的关联。
ContentProvider例子:
DBOpenHelper:
MainActivity:
布局设置:
要在AndroidMainfest.xml中注册:
<provider android:name="com.example.lianxi.StudentProvider"
android:exported="true"
android:authorities="test"></provider>
访问ContentProvider共享的数据
ContentResolver:ContentResolver:用于访问其它应用程序通过ContentProvider共享的数据;
通过ContextWraper类定义的getContentResolver()方法即可获取ContentResolver的对象;
通过使用ContentResolver访问上一个应用程序内的数据,例子:
布局不需修改,MainActivity:
访问到的结果为:
SimpleCursorAdapter:
SimpleCursorAdapter是一种使用Cursor对象作为数据源的Adapter;
使用SimpleCursorAdapter时,要求Cursor对象中必须存在名为_id的列。
使用实例,同样访问的是上面应用的数据:
MainActivity:
布局:
item_student:
ContentProvider中的URI,自定义ContentProvider,实例:
核心代码:
StudentProvider:
运行时需要先将上一个应用部署到虚拟机中,然后再将获取数据的应用运行,
通过一个应用获取另一个应用中的数据:
其他代码同上:核心代码:
Uri uri = Uri.parse("content://com.example.lianxi.providers/student/5");//获取一个数值
Uri uri = Uri.parse("content://com.example.lianxi.providers/student");//获取所有数值
ContentObserver监听数据的变化
使用ContentObserver可监听数据变化,当注册了ContentObserver的URI对应的数据发生变化时,该类中的onChange()
方法会被回调。
调用ContentResolver类定义的registerContentObserver()可以注册ContentObserver。
注意:ContentObserver的工作原理并不是每分每秒的监听对应的数据,只有ContentProvider的增删改查方法必须通知
了数据发生变化以后,ContentObserver才能知晓数据的变化。
实例:
核心代码:
StudentProvider:
MainActivity:
今天今天2015年最后一天。。。。
ContentProvider是一种数据共享机制,它将允许其它应用程序对自身应用程序中的数据
执行增删改查操作;
ContentProvider是Android核心组件之一,因此,开发人员在创建它时,需要自定义继承
ContentProvider,而且,它需要在项目清单文件中(AndroidMainfest.xml)中注册;
ContentProvider需要定义用于访问数据的URI,当其他应用程序知晓对应的URI时,即可
执行数据的相关操作。
ContentProvider无需被激活,当配置了ContentProvider的应用程序被安装到设备上,
同一台设备上的其它应用程序随时都可以访问它的数据。
ContentProvider的开发步骤:
自定义类继承android,content.ContentProvider类;
重写android.content.ContentProvider类中声明的抽象方法;
在AndroidMainfest.xml文件中配置ContentProvider:
创建<application>节点下添加<provider>子节点;
配置android.name属性,指定ContentProvider类;
配置android.authorities属性,指定用于访问数据的URI的host部分;
配置android:exported属性,指定值为true。
标准URI:scheme://host:port/path
例如:http://www.goole.com:80/android
注意:基于ContentProvider中数据增删改查的方法与使用SQLite数据库时使用的方法极为相似,因此,
大多数的ContentProvider共享的数据的方式都是通过操作SQLite数据库完成的,但是,ContentProvider
与SQLite数据库没有必然的关联。
ContentProvider例子:
package com.example.lianxi; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class StudentProvider extends ContentProvider{ private DBOpenHelper helper; @Override public int delete(Uri arg0, String selection, String[] selectionArgs) { SQLiteDatabase db = helper.getReadableDatabase(); db.delete("students", selection, selectionArgs); return 0; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri, ContentValues values) { //插入 SQLiteDatabase db = helper.getReadableDatabase(); db.insert("students", null, values); return null; } @Override public boolean onCreate() { // 完成初始化的操作 helper = new DBOpenHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 查询 SQLiteDatabase db = helper.getReadableDatabase(); Cursor cursor = db.query("students", projection, selection, selectionArgs, null, null, sortOrder); return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = helper.getReadableDatabase(); db.update("students", values, selection, selectionArgs); return 0; } }
DBOpenHelper:
package com.example.lianxi; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DBOpenHelper extends SQLiteOpenHelper{ public DBOpenHelper(Context context){ super(context,"number2.db",null,1); } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub String sql = "CREATE TABLE [students] (" +"[_id] INTEGER PRIMARY KEY AUTOINCREMENT," +"[_name] VARCHAR(50) UNIQUE NOT NULL," +"[_age] INT NOT NULL DEFAULT 16" +")"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } }
MainActivity:
package com.example.lianxi; import android.app.Activity; import android.content.ContentValues; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private DBOpenHelper helper; private SQLiteDatabase db; private EditText name; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); helper = new DBOpenHelper(this); db = helper.getReadableDatabase(); name = (EditText) findViewById(R.id.name); } public void find_All(View view){ Cursor cursor = db.query("students", new String[]{"_id","_name","_age"}, null, null, null, null, "_id desc"); long id; String name; int age; for(cursor.moveToFirst(); !cursor.isAfterLast();cursor.moveToNext()){ id = cursor.getLong(cursor.getColumnIndex("_id")); name = cursor.getString(cursor.getColumnIndex("_name")); age = cursor.getInt(cursor.getColumnIndex("_age")); System.out.println("id = " + id + " ," + "name = " +name +" ," + "age = " + age); } cursor.close(); } public void findName(View view){ String findName = name.getText().toString(); Cursor cursor = db.query("students", null, "_name=?", new String[]{findName}, null, null, null); if(cursor.moveToFirst()){ long id1; String name1; int age1; id1 = cursor.getLong(cursor.getColumnIndex("_id")); name1 = cursor.getString(cursor.getColumnIndex("_name")); age1 = cursor.getInt(cursor.getColumnIndex("_age")); Toast.makeText(this, "学生记录为id = " + id1 + " ," + "name = " +name1 + " ," + "age = " + age1, Toast.LENGTH_LONG).show(); }else{ Toast.makeText(this, "没有匹配的记录!", Toast.LENGTH_LONG).show(); } } }
布局设置:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/find_all" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:onClick="find_All" android:text="查询所有数据" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="30dp" android:orientation="horizontal" > <EditText android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="10" > </EditText> <Button android:id="@+id/find" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:onClick="findName" android:text="查询" /> </LinearLayout> </LinearLayout>
要在AndroidMainfest.xml中注册:
<provider android:name="com.example.lianxi.StudentProvider"
android:exported="true"
android:authorities="test"></provider>
访问ContentProvider共享的数据
ContentResolver:ContentResolver:用于访问其它应用程序通过ContentProvider共享的数据;
通过ContextWraper类定义的getContentResolver()方法即可获取ContentResolver的对象;
通过使用ContentResolver访问上一个应用程序内的数据,例子:
布局不需修改,MainActivity:
package com.example.lianxi; import android.app.Activity; import android.content.ContentValues; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private DBOpenHelper helper; private SQLiteDatabase db; private EditText name; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); helper = new DBOpenHelper(this); db = helper.getReadableDatabase(); name = (EditText) findViewById(R.id.name); } public void find_All(View view){ Cursor cursor = db.query("students", new String[]{"_id","_name","_age"}, null, null, null, null, "_id desc"); long id; String name; int age; for(cursor.moveToFirst(); !cursor.isAfterLast();cursor.moveToNext()){ id = cursor.getLong(cursor.getColumnIndex("_id")); name = cursor.getString(cursor.getColumnIndex("_name")); age = cursor.getInt(cursor.getColumnIndex("_age")); System.out.println("id = " + id + " ," + "name = " +name +" ," + "age = " + age); } cursor.close(); } public void findName(View view){ String findName = name.getText().toString(); Cursor cursor = db.query("students", null, "_name=?", new String[]{findName}, null, null, null); if(cursor.moveToFirst()){ long id1; String name1; int age1; id1 = cursor.getLong(cursor.getColumnIndex("_id")); name1 = cursor.getString(cursor.getColumnIndex("_name")); age1 = cursor.getInt(cursor.getColumnIndex("_age")); Toast.makeText(this, "学生记录为id = " + id1 + " ," + "name = " +name1 + " ," + "age = " + age1, Toast.LENGTH_LONG).show(); }else{ Toast.makeText(this, "没有匹配的记录!", Toast.LENGTH_LONG).show(); } } }
访问到的结果为:
12-30 13:36:02.608: I/System.out(1305): id=1 12-30 13:36:02.616: I/System.out(1305): name=Mike 12-30 13:36:02.616: I/System.out(1305): age=28 12-30 13:36:02.616: I/System.out(1305): id=2 12-30 13:36:02.616: I/System.out(1305): name=fgusdfg 12-30 13:36:02.616: I/System.out(1305): age=21 12-30 13:36:02.616: I/System.out(1305): id=3 12-30 13:36:02.616: I/System.out(1305): name=huanghdf 12-30 13:36:02.616: I/System.out(1305): age=23 12-30 13:36:02.616: I/System.out(1305): id=4 12-30 13:36:02.616: I/System.out(1305): name=Macal 12-30 13:36:02.616: I/System.out(1305): age=45 12-30 13:36:02.616: I/System.out(1305): id=5 12-30 13:36:02.616: I/System.out(1305): name=jiaokong 12-30 13:36:02.616: I/System.out(1305): age=34 12-30 13:36:02.616: I/System.out(1305): id=6 12-30 13:36:02.620: I/System.out(1305): name=sdfff 12-30 13:36:02.620: I/System.out(1305): age=56
SimpleCursorAdapter:
SimpleCursorAdapter是一种使用Cursor对象作为数据源的Adapter;
使用SimpleCursorAdapter时,要求Cursor对象中必须存在名为_id的列。
使用实例,同样访问的是上面应用的数据:
MainActivity:
package com.example.contentresolver; import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.widget.SimpleCursorAdapter; import android.view.Menu; import android.view.MenuItem; import android.widget.ListView; public class MainActivity extends Activity { private ListView listView; private SimpleCursorAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ContentResolver cr = getContentResolver(); Uri uri = Uri.parse("content://test"); Cursor cursor = cr.query(uri, new String[] { "_id", "_name", "_age" }, null, null, null); listView = (ListView) findViewById(R.id.lv_student); String[] from = { "_id", "_name", "_age" }; int[] to = { R.id.item_id, R.id.item_name, R.id.item_age }; adapter = new SimpleCursorAdapter(this, R.layout.student_item, cursor, from, to, 0); listView.setAdapter(adapter); } }
布局:
<RelativeLayout 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:gravity="center_vertical" > <LinearLayout android:id="@+id/ll_head" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/tv_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="ID" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" android:background="#aaaaaa" android:textColor="#ffffff"/> <TextView android:id="@+id/tv_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="NAME" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" android:background="#aaaaaa" android:textColor="#ffffff"/> <TextView android:id="@+id/tv_age" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="AGE" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" android:background="#aaaaaa" android:textColor="#ffffff"/> </LinearLayout> <ListView android:id="@+id/lv_student" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="30dp"></ListView> </RelativeLayout>
item_student:
<?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="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/item_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="ID" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" /> <TextView android:id="@+id/item_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="NAME" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" /> <TextView android:id="@+id/item_age" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="AGE" android:gravity="center" android:layout_weight="1" android:padding="3dp" android:layout_margin="1dp" /> </LinearLayout>
ContentProvider中的URI,自定义ContentProvider,实例:
核心代码:
StudentProvider:
package com.example.lianxi; 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; public class StudentProvider extends ContentProvider { /* * 验证URI 1、是否合法 2、判断操作类型 */ /* * 合法的URI content://com.example.lianxi.providers/student 访问全部的数据 * content://com.example.lianxi.providers/student/5 访问ID为5的数据 */ private DBOpenHelper helper; private static UriMatcher MATCHER;// 用于验证URi的类 private static String AUTHORITY = "com.example.lianxi.providers"; private static String PATH = "student"; private static int MATCHER_ALL = 23; private static int MATCHER_ID = 34; static { MATCHER = new UriMatcher(UriMatcher.NO_MATCH); MATCHER.addURI(AUTHORITY, PATH, MATCHER_ALL); MATCHER.addURI(AUTHORITY, PATH + "/#", MATCHER_ID); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if (MATCHER.match(uri) == MATCHER_ID) { SQLiteDatabase db = helper.getReadableDatabase(); long id = ContentUris.parseId(uri); String whereClause; if (selection == null || "".equals(selection)) { whereClause = "_id" + id; } else { whereClause = selection + " and _id=" + id; } int result = db.delete("students", whereClause, selectionArgs); return result; } else { throw new IllegalArgumentException("非法的URI:" + uri.toString()); } } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri, ContentValues values) { // 插入 if (MATCHER.match(uri) == MATCHER_ALL) { SQLiteDatabase db = helper.getReadableDatabase(); long id = db.insert("students", null, values); return ContentUris.withAppendedId(uri, id);// 返回的为两者合成的 } else { throw new IllegalArgumentException("非法的URI:" + uri.toString()); } } @Override public boolean onCreate() { // 完成初始化的操作 helper = new DBOpenHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 查询 if (MATCHER.match(uri) == MATCHER_ALL) { SQLiteDatabase db = helper.getReadableDatabase(); Cursor cursor = db.query("students", projection, selection, selectionArgs, null, null, sortOrder); return cursor; } else if (MATCHER.match(uri) == MATCHER_ID) { SQLiteDatabase db = helper.getReadableDatabase(); long id = ContentUris.parseId(uri); String whereClause; if (selection == null || "".equals(selection)) { whereClause = "_id=" + id; } else { whereClause = selection + " and _id=" + id; } Cursor cursor = db.query("students", projection, whereClause, selectionArgs, null, null, sortOrder); return cursor; } else { throw new IllegalArgumentException("非法的URI:" + uri.toString()); } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { if (MATCHER.match(uri) == MATCHER_ID) { SQLiteDatabase db = helper.getReadableDatabase(); long id = ContentUris.parseId(uri); String whereClause; if (selection == null || "".equals(selection)) { whereClause = "_id=" + id; } else { whereClause = selection + " and _id=" + id; } int result = db .update("students", values, whereClause, selectionArgs); return result; } else { throw new IllegalArgumentException("非法的URI:" + uri.toString()); } } }
运行时需要先将上一个应用部署到虚拟机中,然后再将获取数据的应用运行,
通过一个应用获取另一个应用中的数据:
其他代码同上:核心代码:
Uri uri = Uri.parse("content://com.example.lianxi.providers/student/5");//获取一个数值
Uri uri = Uri.parse("content://com.example.lianxi.providers/student");//获取所有数值
ContentObserver监听数据的变化
使用ContentObserver可监听数据变化,当注册了ContentObserver的URI对应的数据发生变化时,该类中的onChange()
方法会被回调。
调用ContentResolver类定义的registerContentObserver()可以注册ContentObserver。
注意:ContentObserver的工作原理并不是每分每秒的监听对应的数据,只有ContentProvider的增删改查方法必须通知
了数据发生变化以后,ContentObserver才能知晓数据的变化。
实例:
核心代码:
StudentProvider:
@Override public int delete(Uri uri, String selection, String[] selectionArgs) { if (MATCHER.match(uri) == MATCHER_ID) { SQLiteDatabase db = helper.getReadableDatabase(); long id = ContentUris.parseId(uri); String whereClause; if (selection == null || "".equals(selection)) { whereClause = "_id=" + id; } else { whereClause = selection + " and _id=" + id; } int result = db.delete("students", whereClause, selectionArgs); this.getContext().getContentResolver().notifyChange(uri, null); return result; } else { throw new IllegalArgumentException("非法的URI:" + uri.toString()); } }
MainActivity:
package com.example.contentresolver; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentUris; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.support.v4.widget.SimpleCursorAdapter; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ContextMenu.ContextMenuInfo; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.ListView; public class MainActivity extends Activity { private ListView listView; private SimpleCursorAdapter adapter; private Cursor cursor; private Uri uri; private ContentResolver cr; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); cr = getContentResolver(); uri = Uri.parse("content://com.example.lianxi.providers/student");//获取一个数值 // Uri uri = Uri.parse("content://com.example.lianxi.providers/student");//获取所有数值 cursor = cr.query(uri, new String[] { "_id", "_name", "_age" }, null, null, null); ContentObserver observer = new ContentObserver(new Handler()){ @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub cursor.requery(); adapter.notifyDataSetChanged(); super.onChange(selfChange); } }; cr.registerContentObserver(uri, true, observer); listView = (ListView) findViewById(R.id.lv_student); String[] from = { "_id", "_name", "_age" }; int[] to = { R.id.item_id, R.id.item_name, R.id.item_age }; adapter = new SimpleCursorAdapter(this, R.layout.student_item, cursor, from, to, 0); listView.setAdapter(adapter); registerForContextMenu(listView); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // TODO Auto-generated method stub AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; int position = info.position; cursor.moveToPosition(position); String studentName = cursor.getString(cursor.getColumnIndex("_name")); menu.add(Menu.NONE,1,1,"删除"+ studentName ); super.onCreateContextMenu(menu, v, menuInfo); } @Override public boolean onContextItemSelected(MenuItem item) { // TODO Auto-generated method stub AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); int position = info.position; cursor.moveToPosition(position); long id = cursor.getLong(cursor.getColumnIndex("_id")); Uri deleteUri = ContentUris.withAppendedId(uri, id); cr.delete(deleteUri,null,null); return super.onContextItemSelected(item); } }
今天今天2015年最后一天。。。。
相关文章推荐
- PHP---LAMP初步
- phpunit学习 3:
- PHP学习练手(十一)
- php 二维数组传递给 js 问题解决记录
- php中二维数组如何使用
- laravel5.1 数据库相关,操作底层实现
- laravel5.1 日志相关
- laravel5.1 配置相关
- php+mysql 简单增删查改
- Hello yii2
- 【PHP】PHP转换图片为ico格式源码
- PHP函数
- PHP 部分函数
- workerman 定时器
- PHP版本的线程安全与非线程安全
- phpcms 二次开发 (1)
- LNMP服务器配置(PHP)
- 获取客户端的IP地址
- iis7.5安装配置php环境详细清晰教程,三步实现【图文】
- IIS+PHP本地开发环境配置