您的位置:首页 > 移动开发 > Android开发

Android四大组件之一之内容提供者ContentProvider

2014-01-23 22:27 806 查看
内容提供者(ContentProvider)
    1.什么是ContentProvider

                 ContentProvider可以用来把程序中的数据对外进行共享, 提供增删改查的方法(从而避免其他应用直接操作数据库产生不必要的麻烦)

                 比如只给A应用提供查询的方法,增删改都不提供。

                 ContentProvider中可以注册观察者, 监听数据的变化





      2.怎么创建内容提供者
                  定义类继承ContentProvider, 实现增删改查抽象方法

                  在清单文件中注册

<!--
内容提供者的路径 相对于manifest标签中的package来说的
内容提供者的别名  别的应用用 content://com.xxc.test.provider  来访问此内容提供者
-->
<provider
android:name=".provider.SQLiteProvider"
android:authorities="com.xxc.test.provider"
/>


      3.在手机上注册内容提供者
                  将应用安装到手机上即可, 可以不用运行程序
      4.怎么访问内容提供者
                  获取解析器ContentResolver, 指定Uri
                  通过ContentResolver.insert(),
delete(), update(), query()方法访问Uri关联的ContentProvider
      5.Uri的处理
                  使用UriMatcher可以检查传入的Uri是否和指定的匹配
                  如果Uri带了id, 可以使用ContentUris获取id,
插入方法可以使用ContentUris给Uri加上id

ContentUris.withAppendedId(contentUri, id)//向指定Uri后追加id
ContentUris.parseId(contentUri)//解析ID


内容提供者类

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 com.xxc.dao.MySQLiteOpenHelper;

/**
* 在别的应用调用内容提供者的方法
* 1.内容提供者这个类要继承ContentProvider,实现增删改差和getType方法
* 2.在别的应用中
* 		ContentResolver resolver = getContext().getContentResolver();
*      resolver.当前类里的方法      在别的应用调用此类方法的时候必定要带uri,指明调用哪个内容提供者
*/
public class SQLiteProvider extends ContentProvider {
//Uri匹配器,用来匹配传入的Uri
private UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);//随便传一个参数表示没有匹配上  传入-1也行

private static final int PERSON = 1;
private static final int STUDENT = 2;
private static final int PERSON_ID = 3;

private MySQLiteOpenHelper helper;

@Override
public boolean onCreate() {//第一次启动时执行,然后会长期驻留在后台,除非杀死进程,否则不会再执行
/* 第一个参数:是内容提供者的别名
* 第二个参数:表名(就是/后的内容是什么)
* 第三个参数:匹配上以后,返回的值
*/
matcher.addURI("com.xxc.test.provider", "person", PERSON);
matcher.addURI("com.xxc.test.provider", "person/#", PERSON_ID);
matcher.addURI("com.xxc.test.provider", "student", STUDENT);
helper = new MySQLiteOpenHelper(getContext());
return true;//表示加载成功
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,	String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = null;
switch (matcher.match(uri)) {//判断uri匹配后返回的值
case PERSON_ID:
//获取Uri最后的id内容
long id = ContentUris.parseId(uri);
//如果查询条件为null,那么就加上id的查询条件,如果不为null,就在查询条件的基础上加上id查询条件
selection = selection==null?"id="+id: selection + " AND id="+id;
//这里不写break,因为这里的判断必须经过
case PERSON:
c = db.query("person", projection, selection, selectionArgs, null, null, sortOrder);
return c;
case STUDENT:
System.out.println("查询学生表");
return c;
default:
throw new RuntimeException("URI不能被识别---->"+uri);
}
}

@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = helper.getWritableDatabase();
switch (matcher.match(uri)) {
case PERSON:
long id = db.insert("person","name,balance", values);//插入数据,返回id值得
return ContentUris.withAppendedId(uri, id);//将id值跟在uri后返回
default:
throw new RuntimeException("Uri不能识别--->"+uri);
}
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
switch (matcher.match(uri)) {//判断uri匹配后返回的值
case PERSON_ID:
long id = ContentUris.parseId(uri);
selection = selection==null?"id="+id: selection + " AND id="+id;
case PERSON:
int count = db.delete("person", selection, selectionArgs);
return count;
default:
throw new RuntimeException("URI不能被识别---->"+uri);
}
}

@Override
public int update(Uri uri, ContentValues values, String selection,	String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
switch (matcher.match(uri)) {//判断uri匹配后返回的值
case PERSON_ID:
long id = ContentUris.parseId(uri);
selection = selection==null?"id="+id: selection + " AND id="+id;
case PERSON:
int count = db.update("person", values, selection, selectionArgs);
return count;
default:
throw new RuntimeException("URI不能被识别---->"+uri);
}
}

@Override
public String getType(Uri uri) {
switch (matcher.match(uri)) {//判断uri匹配后返回的值
case PERSON_ID:
return "vnd.android.cursor.item/person";//返回mimetype  这个表示一条数据
case PERSON:
return "vnd.android.cursor.dir/person";//返回一堆数据
default:
throw new RuntimeException("URI不能被识别---->"+uri);
}
}

}


内容提供者所在应用的AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxc.test"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="10" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".SimpleCursorAdapterActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 配置内容提供者 -->
<provider
android:name=".provider.SQLiteProvider"
android:authorities="com.xxc.test.provider"
/>
</application>

</manifest>


使用内容提供者的类

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;

import com.xxc.domain.Person;

public class ProviderTest extends AndroidTestCase {
/**
* 虽然每个测试方法都用到
* ContentResolver resolver = getContext().getContentResolver();
* 但是这句话的创建动作不能写在成员变量上,因为getContext()为null
* 写在成员变量上的执行顺序:
* .class->.dex->.apk->安装->开启进程(开启主线程)->创建ProviderTest对象->getContext()->setContext()自动执行的->测试方法
* 写在测试方法中的执行顺序:
* .class->.dex->.apk->安装->开启进程(开启主线程)->创建ProviderTest对象->setContext()自动执行的->测试方法->getContext()
*/
public void test1(){
ContentResolver resolver = getContext().getContentResolver();

}

public void testQuery(){
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://com.xxc.test.provider/person");
Cursor c = resolver.query(uri, null, "balance>?", new String[]{"100"}, "balance DESC");
while(c.moveToNext()){
Person p = new Person(c.getInt(0),c.getString(1),c.getInt(2));
System.out.println(p);
}
}

public void testInsert(){
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://com.xxc.test.provider/person");
ContentValues values = new ContentValues();
values.put("name", "xiaoxiongmao");
values.put("balance", 2000);
uri = resolver.insert(uri, values);
System.out.println(uri);
}

public void testDelete(){
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://com.xxc.test.provider/person");
//由于Provider解析了url后带的id,所以这边就没指定条件了,如果url后没带id就删除所有的(update同理)
int count = resolver.delete(uri, null, null);
System.out.println("删除了---->"+count+"条");
}

public void testUpdate(){
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://com.xxc.test.provider/person/2");
ContentValues values = new ContentValues();
values.put("name", "xiaolaohu");
values.put("balance", 10);
int count = resolver.update(uri, values, null,null);
System.out.println("更新了---->"+count+"条");
}

public void testGetType(){
ContentResolver resolver = getContext().getContentResolver();
String type1 = resolver.getType(Uri.parse("content://com.xxc.test.provider/person"));
String type2 = resolver.getType(Uri.parse("content://com.xxc.test.provider/person/1"));
System.out.println(type1);
System.out.println(type2);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: