1.理解ContentProvider是什么?
我的理解:我们通过DBOpenHelper操作SQLite,可以进行创建表、插入、修改、删除等行为,而ContentProvider对这些再封装后,通过ContentProvider进行相关数据的存和取.
Content Provider 属于Android应用程序的组件之一,作为应用程序之间唯一的共享数据的途径,Content Provider 主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的借口。
理解:也就是说我手机里有两个APP,例如一个是新浪APP,一个是百度APP,
在百度APP通过ContentResolver对指定的URI发送查询动作,新浪APP的某个ContentProvider如果符合
此URI的话,就会返回相应的数据.
两点注意
1.百度APP并不需要注册新浪APP的那个ContentProvider,ContentResolver通过URI操作被新浪的ContentProvider截取而已
2.在上面描述的过程中,新浪APP并不需要保持运行状态,并且我认为手机里只有有相关的文件即可
2.工作原理
ContentResolver可以说是具体的行为者,它通过URI散播消息,相关ContentProvider收到消息后,进行相关动作
public class Person {
private Integer _id;
private String name;
private String age;
public Integer get_id() {
return _id;
}
public void set_id(Integer _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
public class DBOpenHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "person.db"; //数据库名称
private static final int DATABASE_VERSION = 1;//数据库版本
public DBOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE person (_id integer primary key autoincrement, name varchar(20), age varchar(10))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS person");
onCreate(db);
}
}
public class PersonProvider extends ContentProvider {
private DBOpenHelper dbOpenHelper;
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSONS = 1;
private static final int PERSON = 2;
static {
MATCHER.addURI("com.test.jd.contentproviderdemo.personProvider", "person", PERSONS);
MATCHER.addURI("com.test.jd.contentproviderdemo.personProvider", "person/#", PERSON);
<span style="color:#FF0000;">// 第一个参数是包名+类名</span> <span style="color:#FF0000;">第二个参数path组成的后面部分,第三个是匹配后返回的code</span>
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
this.dbOpenHelper = new DBOpenHelper(this.getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
switch (MATCHER.match(uri)) {
case PERSONS:
return db.query("person", projection, selection, selectionArgs,
null, null, sortOrder);
case PERSON:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
return db.query("person", projection, where, selectionArgs, null,
null, sortOrder);
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
//返回数据的MIME类型。
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
switch (MATCHER.match(uri)) {
case PERSONS:
return "vnd.android.cursor.dir/person";
case PERSON:
return "vnd.android.cursor.item/person";
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
// 插入person表中的所有记录 /person
// 插入person表中指定id的记录 /person/10
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
switch (MATCHER.match(uri)) {
case PERSONS:
// 特别说一下第二个参数是当name字段为空时,将自动插入一个NULL。
long rowid = db.insert("person", "name", values);
Uri insertUri = ContentUris.withAppendedId(uri, rowid);// 得到代表新增记录的Uri
this.getContext().getContentResolver().notifyChange(uri, null);
/**
* <span style="color:#FF0000;">①By default, CursorAdapter objects will get this notification.</span>
*/
return insertUri;
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
@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 PERSONS:
count = db.delete("person", selection, selectionArgs);
return count;
case PERSON:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
count = db.delete("person", where, selectionArgs);
return count;
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int count = 0;
switch (MATCHER.match(uri)) {
case PERSONS:
count = db.update("person", values, selection, selectionArgs);
return count;
case PERSON:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
count = db.update("person", values, where, selectionArgs);
return count;
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
}
public class ResolverDemoActivity extends Activity {
/** Called when the activity is first created. */
private SimpleCursorAdapter adapter;
private ListView listView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView) this.findViewById(R.id.listView);
ContentResolver contentResolver = getContentResolver();
Uri selectUri = Uri.parse("content://com.test.jd.contentproviderdemo.personProvider/person");
Cursor cursor =contentResolver.query(selectUri, null, null, null, null);
cursor.setNotificationUri(contentResolver,selectUri);<span style="color:#CC0000;">//①Register to watch a content URI for changes.</span>
adapter = new SimpleCursorAdapter(this, R.layout.item, cursor,
new String[]{"_id", "name", "age"}, new int[]{R.id.id, R.id.name, R.id.age});
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ListView lView = (ListView)parent;
Cursor data = (Cursor)lView.getItemAtPosition(position);
int _id = data.getInt(data.getColumnIndex("_id"));
Toast.makeText(ResolverDemoActivity.this, _id + "", Toast.LENGTH_LONG).show();
}
});
Button button = (Button) this.findViewById(R.id.insertbutton);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentResolver contentResolver = getContentResolver();
Uri insertUri = Uri.parse("content://com.test.jd.contentproviderdemo.personProvider/person");
ContentValues values = new ContentValues();
values.put("name", "wangkuifeng");
values.put("age", 23);
Uri uri = contentResolver.insert(insertUri, values);
Toast.makeText(ResolverDemoActivity.this, "添加完成", Toast.LENGTH_SHORT).show();
}
});
}
}
activity_main.xml
<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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<ListView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/listView"
android:layout_below="@+id/insertbutton"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="插入"
android:id="@+id/insertbutton"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true" />
</RelativeLayout>
activity_resolver_demo.xml
<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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.test.jd.contentproviderdemo.ResolverDemoActivity">
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="80dip"
android:layout_height="wrap_content"
android:text="435"
android:id="@+id/id"
/>
<TextView
android:layout_width="100dip"
android:layout_height="wrap_content"
android:text="liming"
android:id="@+id/name"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="45"
android:id="@+id/age"
/>
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.jd.contentproviderdemo" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
</activity>
<provider
android:name=".PersonProvider"
android:authorities=<span style="color:#FF0000;">"com.test.jd.contentproviderdemo.personProvider</span>" />
<activity
android:name=".ResolverDemoActivity"
android:label="@string/title_activity_resolver_demo" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
参考地址:http://blog.csdn.net/wangkuifeng0118/article/details/7028953
在另外一个应用利用我们做的ContentProvider
package com.test.jd.myapplication;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
private ListView listView;
private SimpleCursorAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView) this.findViewById(R.id.listView);
ContentResolver contentResolver = getContentResolver();
Uri selectUri = Uri.parse("content://com.test.jd.contentproviderdemo.personProvider/person");
Cursor cursor =contentResolver.query(selectUri, null, null, null, null);
cursor.setNotificationUri(contentResolver,selectUri);
adapter = new SimpleCursorAdapter(this, R.layout.item, cursor,
new String[]{"_id", "name", "age"}, new int[]{R.id.id, R.id.name, R.id.age});
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ListView lView = (ListView)parent;
Cursor data = (Cursor)lView.getItemAtPosition(position);
int _id = data.getInt(data.getColumnIndex("_id"));
Toast.makeText(MainActivity.this, _id + "", Toast.LENGTH_LONG).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
备注:布局文件就一个listView,item.xml和上面的相同,不需要注册contentProvider