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

Android 四大应用组件之ContentProvider

2016-11-10 11:02 363 查看

Android 四大应用组件之ContentProvider

1、理解

1)什么是ContentProvider

ContentProvider是四大应用组件之一

当前应用使用ContentProvider将数据库表数据操作暴露给其它应用访问

其它应用需要使用ContentResolver来调用ContentProvider的方法

它们之间的调用是通过Uri来进行交流的

2) 为什么需要ContentProvider

功能需求:一个应用需要访问另一个应用的数据库表数据data/data/应用包名、databases/xxx.db

实际情况:一个应用数据库文件是该是应用私有的,其它应用不能直接访问



2、相关API

1)ContentProvider : 内容提供者类

//provider对象创建后调用(应用安装成功或手机启动完成)

public abstract boolean onCreate();

//查询表数据

Cursor query(Uri uri, String[] projection,String selection, String[] selectionArgs)

//插入表数据

Uri insert(Uri uri, ContentValues values);

//删除表数据

int delete(Uri uri, String selection, String[] selectionArgs)

//更新表数据

update(Uri uri, ContentValues values, String selection,String[] selectionArgs);

2)ContentResolver: 内容提供者的解析类

//得到它的对象

context.getContentResolver()

//调用provider进行数据库CRUD操作

insert()、delete()、update()、query()

//注册uri的监听

registerContentObserver(Uri uri, boolean notify,ContentObserver observer)

//解注册uri的监听

unregisterContentObserver(ContentObserver observer)

//通知监听器

notifyChange(Uri uri, ContentObserver observer)

3)Uri: 包含请求地址数据的类

//得到其对象

Uri static parse(String uriString) “tel:”+ number

url: http://192.168.10.165:8080/Web_Demo/index.jsp

Uri: content://com.atguigu.pro.contentprovider1/user/



A : 是一个前缀,表示是由ContentProvider提供,固定不变

B : authority, 标识是哪个Provider,不同的Provider此部分必须不同。

C : 对应于哪张表 student

D : id值, 对应表中的哪条记录(可选的)

4)UriMatcher : 用于匹配Uri的容器

//添加一个合法的URI

void addURI(String authority, String path, int code)

//匹配指定的uri, 返回匹配码

int match(Uri uri)

5)ContentUris : 解析uri的工具类

//解析uri, 得到其中的id

long parseId(Uri contentUri)

//添加id到指定的uri中

Uri withAppendedId(Uri contentUri, long id)

3 使用基本步骤

1)编写ContentProvider子类

class PersonProvide extends ContentProvider {

//实现inert、delete、update和query等方法

}

/**
* Created by Jin on 2016/9/13.
*/
public class PersonProvide extends ContentProvider {

//得到数据库帮助类对象
private DBHelper dbHelper;

//提供一个盛放uri的容器    UriMatcher.NO_MATCH 什么意思?
private static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

static {
//参数1:指明authority、参数2:指明访问路径、参数3:给当前的uri赋一个唯一的id。
matcher.addURI("com.atguigu.l9_provider.PersonProvide", "person/", 1);
matcher.addURI("com.atguigu.l9_provider.PersonProvide", "person/#", 2);
}

@Override
public boolean onCreate() {
dbHelper = new DBHelper(getContext(), 1);    //ContentProvider 有一个getContext()方法
return true; //表示正确加载了
}

/**
* 提供对外查询的操作
*
* @param uri
* @param projection
* @param selection
* @param selectionArgs
* @param sortOrder
* @return
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
//根据ContentResolver发送过来的uri,获取其id,判断是容器中的哪个id
int code = matcher.match(uri);
//获取一个数据连接
SQLiteDatabase database = dbHelper.getReadableDatabase();
Cursor cursor = null;
try {
if (code == 1) {
cursor = database.query("person", projection, selection, selectionArgs, null, null, sortOrder);
return cursor;
} else if (code == 2) {
//解析Uri 得到其中id
long id = ContentUris.parseId(uri);
cursor = database.query("person", projection, "_id = ?", new String[]{id + ""}, null, null, sortOrder);
return cursor;
} else {
throw new RuntimeException("输入的uri不合法");
}
} finally {
//关闭操作
//            cursor.close();;
//            database.close();
}
}

@Override
public String getType(Uri uri) {
return null;
}

/**
* 提供对外添加的操作
*
* @param uri
* @param values
* @return
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
int code = matcher.match(uri);
SQLiteDatabase database = dbHelper.getReadableDatabase();
try {
if (code == 1) {
long newID = database.insert("person", null, values);
//将发送过来的uri追加插入成功返回的id后返回。
Uri newUri = ContentUris.withAppendedId(uri, newID);
return newUri;
} else {
throw new RuntimeException("输入的uri不合法");
}
} finally {
if (database != null) {
database.close();
}
}
}

/**
* 提供对外删除的操作
*
* @param uri
* @param selection
* @param selectionArgs
* @return
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {

int code = matcher.match(uri);
SQLiteDatabase database = dbHelper.getReadableDatabase();

try {
if (code == 1) {
int deleteCount = database.delete("person",selection,selectionArgs);
return deleteCount;
} else if (code == 2) {
long id = ContentUris.parseId(uri);
int deleteCount = database.delete("person", "_id = ?", new String[]{id + ""});
return deleteCount;
}
else{
throw new RuntimeException("输入的uri不合法");
}
} finally {
database.close();
}
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int code = matcher.match(uri);
SQLiteDatabase database = dbHelper.getReadableDatabase();
try {
if (code == 1) {
int updateCount = database.update("person",values,selection,selectionArgs);
return updateCount;
} else if (code == 2) {
long id = ContentUris.parseId(uri);
int updateCount = database.update("person",values, "_id = ?", new String[]{id + ""});
return updateCount;
}
else{
throw new RuntimeException("输入的uri不合法");
}
} finally {
database.close();
}

}
}


2)在manifest.xml中注册

ContentResolver resolver = getContentResolver();


4)使用其对象

inert()、delete()、update()和query()

系统自动找到匹配的ContentProvider对象来操作数据

registerContentObserver(Uri uri, boolean notify,ContentObserver

observer) 注册uri的监听

unregisterContentObserver(ContentObserver observer) 解注册uri的监听

notifyChange(Uri uri, ContentObserver observer) 通知监听器

/**
* 测试使用ContentResolver调用ContentProvider的主界面
* @author shkstart
*
*/
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

/*
* 通过ContentResolver调用ContentProvider插入一条记录
*/
public void insert(View v) {
ContentResolver resolver = getContentResolver();
Uri uri  = Uri.parse("content://com.atguigu.l9_provider.PersonProvide/person/");

ContentValues values = new ContentValues();
values.put("name","dongdong");
Uri newUri = resolver.insert(uri, values);
Log.e("TAG",newUri.toString());
}

/*
* 通过ContentResolver调用ContentProvider更新一条记录
*/
public void update(View v) {
ContentResolver resolver = getContentResolver();
Uri uri  = Uri.parse("content://com.atguigu.l9_provider.PersonProvide/person/2");

ContentValues values = new ContentValues();
values.put("name", "jinxiaodong");
int updateCount = resolver.update(uri, values, null, null);

Log.e("TAG","修改了"+updateCount+"条数据");

}

/*
* 通过ContentResolver调用ContentProvider删除一条记录
*/
public void delete(View v) {

ContentResolver resolver = getContentResolver();

Uri uri  = Uri.parse("content://com.atguigu.l9_provider.PersonProvide/person/2");

int deleteCount = resolver.delete(uri, null, null);
Log.e("TAG","删除了"+deleteCount+"条数据");

}

/*
* 通过ContentResolver调用ContentProvider查询所有记录
*/
public void query(View v) {
//获取ContentResolver的对象
ContentResolver resolver = getContentResolver();
//提供查询需要的参数
Uri uri  = Uri.parse("content://com.atguigu.l9_provider.PersonProvide/person/");
//3.进行查询:调用ContentResolver的query(),实际上就会触发对ContentProvider的query()方法的调用
//ContentProvider的query()方法的返回值即为如下的ContentResolver的query()的返回值
Cursor cursor = resolver.query(uri, null, null, null, null);
//4.从cursor中读取数据
while (cursor.moveToNext()){
int id = cursor.getInt(0);
String name = cursor.getString(1);
Log.e("TAG","id = "+id+",name = "+name);
}
//关闭资源
cursor.close();
}
}


4 贴一个小demo

//调用系统联系人
public class MainActivity extends Activity {

private EditText tv_main_number;
private static final int requestCode = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_main_number = (EditText) findViewById(R.id.tv_main_number);
}

public void selectContacts(View v) {
Intent intent = new Intent(this, ContactsActivity.class);

startActivityForResult(intent, requestCode);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == 1 && resultCode == RESULT_OK) {
String number = data.getStringExtra("number");
tv_main_number.setText(number);
}

}
}


//listview/adapter/list/itemlayout
public class ContactsActivity extends Activity implements AdapterView.OnItemClickListener {

private ListView lv_contacts;
private ContactsAdapter adapter;
List<Map<String, String>> list;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts);
//初始化listView
lv_contacts = (ListView) findViewById(R.id.lv_contacts);
//初始化数据
initdata();
//初始化adapter
adapter = new ContactsAdapter();

lv_contacts.setAdapter(adapter);

lv_contacts.setOnItemClickListener(this);

}

//初始化集合数据
private List<Map<String, String>> initdata() {
list = new ArrayList<>();
//得到ContentResolver对象
ContentResolver resolver = this.getContentResolver();
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String name = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME;
String number = ContactsContract.CommonDataKinds.Phone.NUMBER;
//第二个参数什么意思?查询表中的那几个字段
Cursor cursor = resolver.query(uri, new String[]{name, number}, null, null, null);
while (cursor.moveToNext()) {
Map<String, String> map = new HashMap<>();
String namevalue = cursor.getString(cursor.getColumnIndex(name));
String numbervalue = cursor.getString(cursor.getColumnIndex(number));
map.put("name", namevalue);
map.put("number", numbervalue);
list.add(map);
}
cursor.close();
return list;
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String number = list.get(position).get("number");
Intent intent = getIntent();
intent.putExtra("number", number);
setResult(RESULT_OK, intent);
finish();
}

class ContactsAdapter extends BaseAdapter {

@Override
public int getCount() {
return list == null ? 0 : list.size();
}

@Override
public Object getItem(int position) {
return list == null ? null : list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = View.inflate(ContactsActivity.this, R.layout.item_contacts, null);

viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
viewHolder.tv_item_name = (TextView) convertView.findViewById(R.id.tv_item_name);
viewHolder.tv_item_number = (TextView) convertView.findViewById(R.id.tv_item_number);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//装配数据
Map<String, String> map = list.get(position);
viewHolder.tv_item_name.setText(map.get("name"));
viewHolder.tv_item_number.setText(map.get("number"));

return convertView;
}
}

class ViewHolder {
TextView tv_item_name;
TextView tv_item_number;
}
}


配置文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.atguigu.l09_app_contacts">

<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ContactsActivity"></activity>
</application>

</manifest>


刚开始学Android,有错误的还请指出~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: