Android应用程序之间的数据交互之ContentProvider

来源:互联网 发布:企业网络硬盘软件排行 编辑:程序博客网 时间:2024/05/16 17:26

大致的总结一下Android应用程序之间的通讯有哪些方式可以实现:

1、将数据本地化储存

2、利用广播机制

3、AIDL

4、ContentProvider

简单解释一下,“数据本地化储存”可以将数据保存到一个文本文件或者数据库中,另一个程序只需打开指定的文本文件或者数据库读取数据即可完成应用程序之间的交互;“利用广播机制”,一个用用程序发送广播,另一个应用程序接收广播,也可以实现应用程序之间的数据交互;“AIDL”全称Android Interface definition language,简单的翻译一下就是android接口定义语言,它是将两个程序一个作为服务器一个作为客户端来实现数据交互;“ContentProvider”Android的四大组件之一,内容提供者,它也可以实现应用程序之间的数据交互,今天就重点的学习一下这种实现方式。

ContentProvider的使用大致可以分为两类:

1、与手机内置应用程序的数据交互,比如读取联系人、图库等。

2、我们新建的两个应用程序之间的数据数据交互。

先看第一种,与手机内置应用程序的数据交互

这种方式我们常见到是查询手机联系人和手机图片信息。
查询手机联系人:

查询联系人需要添加权限

<uses-permission android:name="android.permission.READ_CONTACTS" />
添加新的联系人数据需要添加权限
 <uses-permission android:name="android.permission.WRITE_CONTACTS" />
// 查询联系人private void searchContracts() {// TODO Auto-generated method stubUri uri = Uri.parse("content://com.android.contacts/contacts");ContentResolver resolver = getActivity().getContentResolver();Cursor cursor = resolver.query(uri, new String[] { "_id" }, null, null,null);while (cursor.moveToNext()) {int contractID = cursor.getInt(0);StringBuilder sb = new StringBuilder("contractID=");sb.append(contractID);uri = Uri.parse("content://com.android.contacts/contacts/"+ contractID + "/data");Cursor cursor1 = resolver.query(uri, new String[] { "mimetype","data1", "data2" }, null, null, null);while (cursor1.moveToNext()) {String data1 = cursor1.getString(cursor1.getColumnIndex("data1"));String mimeType = cursor1.getString(cursor1.getColumnIndex("mimetype"));if ("vnd.android.cursor.item/name".equals(mimeType)) { // 是姓名sb.append(",name=" + data1);} else if ("vnd.android.cursor.item/email_v2".equals(mimeType)) { // 邮箱sb.append(",email=" + data1);} else if ("vnd.android.cursor.item/phone_v2".equals(mimeType)) { // 手机sb.append(",phone=" + data1);}}cursor1.close();// System.out.println(sb.toString());contractList.add(sb.toString());}cursor.close();}

// 查询通话记录private void searchCallLog() {Cursor mCursor = getActivity().getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null,CallLog.Calls.DEFAULT_SORT_ORDER);if (null == mCursor) {System.out.println("null");} else if (mCursor.getCount() < 1) {System.out.println("00000");} else {System.out.println(mCursor.getCount());}mCursor.close();}

// 查询指定电话的联系人姓名,邮箱public void testContactNameByNumber() throws Exception {String number = "18052369652";Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/"+ number);ContentResolver resolver = getActivity().getContentResolver();Cursor cursor = resolver.query(uri, new String[] { "display_name" },null, null, null);if (cursor.moveToFirst()) {String name = cursor.getString(0);System.out.println(name);}cursor.close();}

// 添加联系人,使用事务public void testAddContact() throws Exception {Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");ContentResolver resolver = getActivity().getContentResolver();ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();ContentProviderOperation op1 = ContentProviderOperation.newInsert(uri).withValue("account_name", null).build();operations.add(op1);uri = Uri.parse("content://com.android.contacts/data");ContentProviderOperation op2 = ContentProviderOperation.newInsert(uri).withValueBackReference("raw_contact_id", 0).withValue("mimetype", "vnd.android.cursor.item/name").withValue("data2", "龚小永").build();operations.add(op2);ContentProviderOperation op3 = ContentProviderOperation.newInsert(uri).withValueBackReference("raw_contact_id", 0).withValue("mimetype", "vnd.android.cursor.item/phone_v2").withValue("data1", "13539777967").withValue("data2", "2").build();operations.add(op3);ContentProviderOperation op4 = ContentProviderOperation.newInsert(uri).withValueBackReference("raw_contact_id", 0).withValue("mimetype", "vnd.android.cursor.item/email_v2").withValue("data1", "asdfasfad@163.com").withValue("data2", "2").build();operations.add(op4);resolver.applyBatch("com.android.contacts", operations);}
查询手机图片:
权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
private void searchImage() {// 指定获取的列Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;ContentResolver mContentResolver = getActivity().getContentResolver();// 只查询jpeg的图片Cursor mCursor = mContentResolver.query(mImageUri, null,MediaStore.Images.Media.MIME_TYPE + "=?",new String[] { "image/jpeg" },MediaStore.Images.Media.DATE_TAKEN);int i = 0;mCursor.moveToFirst();// 这里演示使用,只选取20张图片加载do {if (i >= 20)break;// 获取图片的路径String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));String name = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));Map<String, String> map = new HashMap<String, String>();map.put(path, name);list.add(map);i++;} while (mCursor.moveToNext());}
程序主要代码就是这些。
下面是程序运行截图

            

源码下载

第二种ContentProvider的使用就是我们自己定义一个ContentProvider来实现我们的应用程序之间的数据交互
在CPTestA定义一个继承自ContentProvider的类MyContentProvider

package com.example.cptesta;import android.content.ContentProvider;import android.content.ContentResolver;import android.content.ContentValues;import android.database.CharArrayBuffer;import android.database.ContentObserver;import android.database.Cursor;import android.database.DataSetObserver;import android.net.Uri;import android.os.Bundle;public class MyContentProvider extends ContentProvider {@Overridepublic boolean onCreate() {// TODO Auto-generated method stubreturn false;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {// TODO Auto-generated method stubSystem.out.println("查询");/** * 在正在的开发中需要在这里实现数据查询,并return */return null;}@Overridepublic String getType(Uri uri) {// TODO Auto-generated method stubreturn null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {// TODO Auto-generated method stubSystem.out.println("插入");/** * 在正在的开发中需要在这里实现数据插入,并return */return null;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {// TODO Auto-generated method stubSystem.out.println("删除");/** * 在正在的开发中需要在这里实现数据删除,并return */return 0;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {// TODO Auto-generated method stubSystem.out.println("更新");/** * 在正在的开发中需要在这里实现数据删除,并return */return 0;}}

在AndroidManifest.xml文件中注册一个Provider,注意要放到application标签内

 <provider            android:name="MyContentProvider"            android:authorities="com.example.cptesta.MyContentProvider"            android:exported="true" />

新建一个项目CPTestB

package com.example.cptestb;import android.content.ContentResolver;import android.content.ContentValues;import android.net.Uri;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;public class MainActivity extends ActionBarActivity {// 需与CPTestA中的android:authorities="com.example.cptesta.MyContentProvider"保持一致private static final String AUTHORY = "com.example.cptesta.MyContentProvider";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);queryData();}private void queryData() {Uri uri = Uri.parse("content://" + AUTHORY + "/userinfo1");ContentResolver mContentResolver = getContentResolver();ContentValues values = new ContentValues();values.put("insert", "CPTestB want to insert!");mContentResolver.query(uri, null, null, null, null);}private void insertData() {Uri uri = Uri.parse("content://" + AUTHORY + "/userinfo1");ContentResolver mContentResolver = getContentResolver();ContentValues values = new ContentValues();values.put("insert", "CPTestB want to insert!");mContentResolver.insert(uri, values);}private void updateData() {Uri uri = Uri.parse("content://" + AUTHORY + "/userinfo1");ContentResolver mContentResolver = getContentResolver();ContentValues values = new ContentValues();values.put("insert", "CPTestB want to update!");mContentResolver.update(uri, values, "where name=?",new String[] { "zhangsan" });}private void deleteData() {Uri uri = Uri.parse("content://" + AUTHORY + "/userinfo1");ContentResolver mContentResolver = getContentResolver();mContentResolver.delete(uri, "where name=?",new String[] { "zhangsan" });}}


先运行CPTestA,运行CPTestB,就可以看到在控制台输出

源码下载









0 0