zoukankan      html  css  js  c++  java
  • Android · ContentProvider学习

    一、Content Provider基本概念

    1、ContentProvider为存储和获取数据提供了统一的接口。ContentProvide对数据进行封装,不用关心数据存储的细节。使用表的形式来组织数据。image

    2、使用ContentProvider可以在不同的应用程序之间共享数据。

    3、Android为常见的一些数据提供了默认的ContentProvider(包括音频、视频、图片和通讯录等)。

    ContentProvider所提供的函数: query(),insert(),update(),delete(),getType(),onCreate()等。

    二、URI统一资源标识符)的使用方法

    为系统的每一个资源给其一个名字,比方说通话记录。

    1、每一个ContentProvider都拥有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。

    2、Android所提供的ContentProvider都存放在android.provider包中。 将其分为A,B,C,D 4个部分:

    image

    A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;"content://"

    B:URI 的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。这个标识在元素的 authorities属性中说明:一般是定义该ContentProvider的包.类的名称;"content://hx.android.text.myprovider"

    C:路径,通俗的讲就是数据库中要操作的表的名字

    D:如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部

    Uri写法1

    Uri uri = Uri.parsecontent://media/internal/images") 这个URI将返回设备上存储的所有图片 
    content://contacts/people/  这个URI将返回设备上的所有联系人信息
    content://contacts/people/45 这个URI返回单个结果(联系人信息中ID为45的联系人记录)

    Uri写法2

    Uri person = ContentUris.withAppendedId(People.CONTENT_URI,  45);

    然后执行数据查询:  Cursor cur = managedQuery(person, null, null, null);

    这个查询返回一个包含所有数据字段的游标,我们可以通过迭代这个游标来获取所有的数据:

    三、ContentProvider的使用

    实现: 应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法

    自己实现ContentProvider不常见,因为可能不需要和别的应用程序交换数据。

    因此下面主要介绍ContentProvider的使用

    • 从Android 2.0 SDK开始有关联系人provider的类从android.provider.Contacts变成了android.provider.ContactsContract
    • ContactsContract的子类ContactsContract.Contacts是一张表,代表了所有联系人的统计信息。比如联系人ID(—ID),查询键(LOOKUP_KEY),联系人的姓名(DISPLAY_NAME_PRIMARY),头像的id(PHOTO_ID)以及群组的id等等
    • 在新的Contacts API中,联系人数据被安排三个主要的表中:contacts, raw contacts and data. 结构如下图所示:

    一个contact(联系人)记录关联一个或多个RawContact(联系人来源,如Gmail)记录,每个RawContact记录又关联多个data(email, phone number等等)记录

    package com.example.manhua;
    
    import java.util.ArrayList;
    
    import android.app.ListActivity;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    
    public class MainActivity extends ListActivity {
    	
    /*
     * ListActivity的默认布局由一个位于屏幕中心的全屏列表构成。
     * 如果你不想使用默认的布局,可以在onCreate()方法中通过setContentView()方法设定你自己的布局。
     * 如果指定你自己定制的布局,你的布局中必须包含一个id为"@id/android:list"的ListView。 
     * 若你还指定了一个id为"@id/android:empty"的view,当ListView中没有数据要显示时,
     * 这个view就会被显示,同时 ListView会被隐藏。
     * */
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		//setContentView(R.layout.activity_main);
    		displayRecords();
    	}
    
    	
    	//  <uses-permission android:name="android.permission.READ_CONTACTS"/>
    	private void displayRecords() {
    		Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;
    		// 该数组中包含了所有要返回的字段
    		String proj1[] = new String[] { ContactsContract.Contacts.DISPLAY_NAME,
    				ContactsContract.Contacts.HAS_PHONE_NUMBER , ContactsContract.Contacts.LOOKUP_KEY};
    		// declare a ArrayList object to store the data that will present to the
    		// user
    		Cursor curContacts = getContentResolver().query(contactsUri, proj1,
    				null, null, null);
    		ArrayList<String> contactsList = new ArrayList<String>();
    		String allPhoneNo = "";
    		if (curContacts.getCount() > 0) {
    			while (curContacts.moveToNext()) {
    				// get all the phone numbers if exist
    				if (curContacts.getInt(1) > 0) {
    					allPhoneNo = getAllPhoneNumbers(curContacts.getString(2));
    				}
    				contactsList.add(curContacts.getString(0) + " , " + allPhoneNo);
    				allPhoneNo = "";
    			}
    		}
    		// binding the data to ListView
    		setListAdapter(new ArrayAdapter<String>(this,
    				android.R.layout.simple_list_item_1, contactsList));
    		ListView lv = getListView();
    		lv.setTextFilterEnabled(true);
    	}
    
    	/**
    	 * Get all the phone numbers of a specific contact person
    	 * 
    	 * @param lookUp_Key
    	 *            lookUp key for a specific contact
    	 * @return a string containing all the phone numbers
    	 */
    	public String getAllPhoneNumbers(String lookUp_Key) {
    		String allPhoneNo = "";
    
    		// Phone info are stored in the ContactsContract.Data table
    		Uri phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    		String[] proj2 = { ContactsContract.CommonDataKinds.Phone.NUMBER };
    		// using lookUp key to search the phone numbers
    		String selection = ContactsContract.Data.LOOKUP_KEY + "=?";
    
    		Cursor cur = getContentResolver().query(phoneUri, proj2, selection,
    				new String[] { lookUp_Key }, null);
    		while (cur.moveToNext()) {
    			allPhoneNo += cur.getString(0) + " ";
    		}
    
    		return allPhoneNo;
    	}
    }

    由于读取联系人比较的占用资源,为了提高用户的体验度。考虑将读取的过程放在线程里完成,推荐使用AsyncTask类

  • 相关阅读:
    关于扩展欧几里得算法___基础,基础中的基础
    bzoj 2152聪聪可可
    poj1741 树上的点分治
    POJ1201 区间
    codevs 2756树上的路径
    zoj1260 king
    栈与队列应用:迷宫问题(DFS非最短路径)
    估值为一亿的AI核心代码
    栈与队列应用:计算前缀表达式的值
    栈与队列:循环队列算法+可执行代码
  • 原文地址:https://www.cnblogs.com/manhua/p/4154914.html
Copyright © 2011-2022 走看看