zoukankan      html  css  js  c++  java
  • 【转】Pro Android学习笔记(六):了解Content Provider(中)

    Content Provider的架构

    Authority类似web中的域名,每个content provider会通过AndroidManifest.xml向系统注册authority,如下。其中name是类名,即如何找寻这个content provider。可以省去AndroidManifest.xml中package name,不需要写完整的类名。如android:name=".BookProvider"。

    <provider android:name="SomeProvider"  android:authorities="com.your-company.SomeProvider" /> 
    <provider android:name="NotePadProvider" android:authorities="com.google.provider.NotePad" />

    和web的URL域名类似,content provider进行数据访问的URL为content://authority/......,例如content://com.your-company.SomeProvider/。对于Android自己提供的content provider,有时会写的比较简单,例如用contacts来代替com.google.android.contacts,如content://contacts/……。

    有时注册的provider会比较复杂,例如Android的联系人信息,其uri为content://com.android.contacts/contacts,其源代码信息为如下,该provider需要读写权限。

    <provider android:name="ContactsProvider2" 
        android:authorities="contacts;com.android.contacts" 
        android:label="@string/provider_label" 
        android:multiprocess="false" 
        android:readPermission="android.permission.READ_CONTACTS" 
        android:writePermission="android.permission.WRITE_CONTACTS"> 
        <path-permission 
                android:pathPrefix="/search_suggest_query" 
                android:readPermission="android.permission.GLOBAL_SEARCH"/> 
        <path-permission 
                android:pathPrefix="/search_suggest_shortcut" 
                android:readPermission="android.permission.GLOBAL_SEARCH"/> 
        <path-permission 
                android:pathPattern="/contacts/.*/photo" 
                android:readPermission="android.permission.GLOBAL_SEARCH"/> 
        <grant-uri-permission android:pathPattern=".*" /> 
    </provider>

    Content URI的结构。Android通过Content URI来获取数据,并返回具有行列结构的游标cursor。content UI的格式为:

    content://<authority-name>/<path-segment1>/<path-segment2>/etc 
    例子:content://com.google.provider.NotePad/notes/23

    例子的/notes表示collection,或理解为一个目录,称为path segment,而/23表示特定的item,是具体的index,content provider提供的是二维数据,这就是该row的_id值。

    MIME Type。HTTP响应会带有MIME Type,最长江就是text/html,告知body的数据类型。Content Provider也一样,可以用方法获得MIME。MIME由两部分组成:type/subtype,具体可以参考rfc2046。type和subtype的定义可以在IANA中查到。下面是MIME的几个例子:

    text/xml 
    application/rtf 
    application/vnd.ms-excel  //vnd是vendeor-specific,厂家自定义格式,如此处的微软excel格式 
    application/x-tar                //x-表示自定义的私有格式

    在Content Provider中可以存在多层目录,即存在item和collection,相应地分别有item的MIME tye和collection的MIME type。Android采用namespace的方式定义type和subtype。如下:

    vnd.android.cursor.item/vnd.<yourcompanyname.contenttype> 是item的MIME type 
    vnd.android.cursor.dir/vnd.<yourcompanyname.contenttype>是collection的MIME type

    从上面的格式可以看到,type已指定,开发者只能对subtype进行设置。

    定义清晰描述。我们应该为所创建的content provider提供清晰的定义或描述,可通过所使用的Uri进行constant的预定义。例如MediaStore.Images.Media.INTERNETAL_CONTENT_URI表示content://media/internal/images。同时我们也应为个列

    小例子:读取联系人信息。Provider通过uri去访问,返回游标(cursor),我们将通过下面的小例子进行验证,先进行Uri的了解,然后对cursor进行二次轮询,一次采用while,一次采用for方式。正如前面的contact provider在xml的定义所示,有读写权限限制,因此在XML中应赋予相应的权限:<uses-permission android:name="android.permission.READ_CONTACTS" />

        private void contentProviderTest(){ 
            /* Contact的内容很多,我们只选取部分列名字,相当于SELECT xxxx FROM ....中的xxxx。如果是自己创建创建的Content Provider,也应当采用constant的方式了明晰表示每项的内容*/ 
            String[] contactProjection = new String[]{ 
                    Contacts._ID,    /* 每一行都有一个唯一的_id来表示 */ 
                    Contacts.DISPLAY_NAME_PRIMARY 
            };        

            /* 下面是一些uri的操作,作为测试,通过provider的Uri都会提供constant的方式 */ 
            Uri peopleBaseUri = ContactsContract.Contacts.CONTENT_URI; 
            showInfo(peopleBaseUri.toString());  //showInfo( )信息显示,我将在TextView中呈现内容 
            Uri myPersonUri = Uri.withAppendedPath(peopleBaseUri, "1"); 
            showInfo(myPersonUri.toString());  
             
            /* managedQuery( )从Content Provider读取数据,返回Cursor 
             * 第1参数:Uri uri表示URI;  
             * 第2参数:String[] projection表示所需读取的信息; 
             * 第3参数:String selection数是限制条件,类似SQL中的WHERE,但去掉了“WHERE”; 
             * 第4参数:String[] selectionArgs和第3个参数配合使用,具体描述第三个参数中的“?”为何; 
             * 第5参数:String sortOrder,类似于SQL中的ORDER BY */
     
            @SuppressWarnings("deprecation") //在API Level 11,也就是Android3.0后由CursorLoader替代,为了不使Eclipse报警告,我们先在此禁止警告。看到Eclipse有个小三角的告警说明,觉得不舒服,干掉它。^_^ 
            Cursor cur = managedQuery(ContactsContract.Contacts.CONTENT_URI, 
                                    contactProjection, 
                                    null, 
                                    null, 
                                    null);  
           showInfo("query Contacts get cursor : " + cur); 
           showInfo("cursor has " + cur.getCount() + " rows."); 
            
            // 轮询方式一:  通过while 
            showInfo("read from cursor"); 
            //游标是rows的集合,首先需要使用moveToFirst(),因为query后游标是位于第一行的前面。返回false,表示为空。 
            if(!cur.moveToFirst()){ 
                showInfo("no rows. It's empty"); 
                cur.close(); 
                return; 
            } 
            
            //游标可以前后移动,去可以查看不同行的数据,还可以指定特定的行,它的移动非常灵活。游标对数据的获取是基于column number,可通过列名来获取。  
            int nameColumnIndex = cur.getColumnIndex(Contacts.DISPLAY_NAME_PRIMARY);  
            showInfo(" Name: " + cur.getString(nameColumnIndex)); 
            while(cur.moveToNext()){  
                showInfo(" Name: " + cur.getString(nameColumnIndex)); 
            } 
            
            //轮询方式二:通过for  
            showInfo("read from cursor again"); 
            for(cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()){ 
                String name = cur.getString(nameColumnIndex); 
                showInfo(" Name: " + name); 
            } 
            
            cur.close(); 
        }

    Where条件的用法。查找特定的数据,可以利用Uri,也可以利用manageQuery()方法的参数。例如希望查询select * from notes where _id=23,利用Uri,可以设置为

    String noteUri = “content://com.google.progider.NotePad/notes/23”;

    利用manageQuery( )中的selection擦数,同样可以表达为

    managedQuery(uri, //为"content://com.google.provider.NotePad/notes" 
                              null,  
                              "_id=?" , 
                              new String[] {23} ,  
                              null);

    增加、修改、删除数据。增删改查是数据读写的四大功能,我们将在后面的小例子中给出详细的说明。

    相关链接: 我的Android开发相关文章

    转自http://blog.csdn.net/flowingflying/article/details/9217431

  • 相关阅读:
    (Beta)Let's-Beta阶段展示博客
    (Beta)Let's-M2后分析报告
    (Beta)Let's-版本测试报告
    (Beta)Let's-版本发布说明
    团队作业Week14
    Daily Scrum 12.20
    Daily Scrum 12.19
    Daily Scrum 12.18
    Daily Scrum 12.17
    最后一次作业
  • 原文地址:https://www.cnblogs.com/blongfree/p/5047557.html
Copyright © 2011-2022 走看看