zoukankan      html  css  js  c++  java
  • android之ContentProvider和Uri具体解释

    一、使用ContentProvider(内容提供者)共享数据
    在android中ContentProvider的作用是对外共享数据,就是说能够通过ContentProvider把应用中的数据共享给其它应用訪问,其它应用能够通过ContentProvider对你应用中的数据进行添删改查。

    就像我们手机的通话记录。我没要查看某个通话时间。这是须要调用通话记录中的数据。此时就该用到了ContentProvider数据共享。

    关于数据共享。在文件操作模式,通过指定文件的操作模式为Context.MODE_WORLD_READABLE或Context.MODE_WORLD_WRITEABLE相同也能够对外共享数据。那么。这里为何要使用ContentProvider对外共享数据呢?答案是:如採用文件操作模式对外共享数据,数据的訪问方式会因数据存储的方式而不同。导致数据的訪问方式无法统一,如:採用sharedpreferences共享数据,须要使用sharedpreferences API读取数据採用xml文件对外共享数据。须要进行xml解析才干读取数据。使用ContentProvider对外共享数据的优点是统一了数据的訪问方式。
    应用须要通过ContentProvider对外共享数据时步骤:

    第一步须要继承ContentProvider并重写以下方法:

    com.example.testcp.FirstContentProvider/users

    public boolean onCreate():该方法在ContentProvider创建后就会被调用。Android开机后,ContentProvider在其他应用第一次訪问它时才会被创建。

    public Uri insert(Uri uri, ContentValues values):该方法用于供外部应用往ContentProvider加入数据。

    public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于供外部应用从ContentProvider删除数据。 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):该方法用于供外部应用更新ContentProvider中的数据。

    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):该方法用于供外部应用从ContentProvider中获取数据。

    public String getType(Uri uri):该方法用于返回当前Url所代表数据的MIME类型。


    假设操作的数据属于集合类型。那么MIME类型字符串应该以vnd.android.cursor.dir/开头。
    比如:要得到全部person记录的Uri为content://com.example.testcp.FirstContentProvider/users,那么返回的MIME类型字符串应该为:"vnd.android.cursor.dir/user"。
    假设要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头。
    比如:得到id为10的person记录。Uri为content://com.example.testcp.FirstContentProvider/users/1。那么返回的MIME类型字符串为:"vnd.android.cursor.item/iser"。

    如代码:

    //该ContentProvider所返回的数据类型的定义。取多条数据
    public static final String CONTENT_TYPE = "vnd.android.crusor.dir/vnd.firstprovider.user";
    //该ContentProvider所返回的数据类型的定义,取一条数据
    public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.firstprovider.user";


    第二步须要在AndroidManifest.xml使用<provider>对该ContentProvider进行配置。为了能让其它应用找到该ContentProvider 。ContentProvider採用了authorities(主机名/域名)对它进行唯一标识,你能够把ContentProvider看作是一个站点(想想。站点也是提供数据者),authorities 就是他的域名:

     <provider
            android:name="com.example.testcp.FirstContentProvider" 
            android:authorities="com.example.testcp.FirstContentProvider">
      </provider>

    二、Uri介绍
    Uri代表了要操作的数据,Uri主要包括了两部分信息:

    1)须要操作的ContentProvider 。

    2)对ContentProvider中的什么数据进行操作,一个Uri由下面几部分组成:           
          

            
    scheme由Android所规定,由ContentProvider(内容提供者),scheme为:content://
    主机(Authoritis)用于唯一标识这个ContentProvider。外部调用者能够依据这个标识来找到它
    路径(path)能够用来表示我们要操作的数据。路径的构建应依据业务而定。

    例如以下:
              要操作users表中id为1的记录,能够构建这种路径:/users/1
              要操作users表中id为1的记录的name字段。 users/1/name
              要操作person表中的全部记录,能够构建这种路径:/users

    当然要操作的数据不一定来自数据库。也能够是文件、xml或网络等其它存储方式.
    假设要把一个字符串转换成Uri。能够使用Uri类中的parse()方法。例如以下:
    Uri uri = Uri.parse("content://com.example.testcp.FirstContentProvider/users")


    三、UriMatcher类使用介绍
    在Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher和ContentUris 。UriMatcher类用于匹配Uri。它的使用方法例如以下:
    首先第一步把你须要匹配Uri路径所有给注冊上。例如以下:

            //检查URI是否合法
    	public static final UriMatcher uriMatcher;
    	public static final int INCOMING_USER_COLLECTION = 1;
    	public static final int INCOMING_USER_SINGLE = 2;
    	private DatabaseHelper dh;
    	static {
                   //常量UriMatcher.NO_MATCH表示不匹配不论什么路径的返回码
                    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    		uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users", INCOMING_USER_COLLECTION);
    		uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users/#", INCOMING_USER_SINGLE);#号为通配符switch
    	}
    
            switch(uriMatcher.match(uri)){
                case INCOMING_USER_COLLECTION:
                     return UserTableMetaData.CONTENT_TYPE;
                case INCOMING_USER_SINGLE:
                     return UserTableMetaData.CONTENT_TYPE_ITEM;
                default:
                     throw new IllegalArgumentException("Unknown URI" + uri);
            }
    



    四、ContentUris类使用介绍

        ContentUris类用于操作Uri路径后面的ID部分,它有两个比較有用的方法:
        withAppendedId(uri, id)用于为路径加上ID部分:

    //生成后的Uri为:content://com.example.testcp.FirstContentProvider/users/1
    Uri uri = Uri.parse("content://com.example.testcp.FirstContentProvider/users")
    Uri insertedUserUri = ContentUris.withAppendedId(uri, 1);

    parseId(uri)方法用于从路径中获取ID部分:

    //获取的结果为:1
    Uri insertedUserUri = Uri.parse("content://com.example.testcp.FirstContentProvider/users/1")
    long userId = ContentUris.parseId(insertedUserUri);

    到这里基本说明已经完毕,那么以下我们来实现ContentProvider:

    五、使用ContentResolver操作ContentProvider中的数据当外部应用须要对ContentProvider中的数据进行加入、删除、改动和查询操作时,能够使用ContentResolver 类来完毕,要获取ContentResolver 对象。能够使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类同样签名的四个方法:这些方法的第一个參数为Uri。代表要操作的ContentProvider和对当中的什么数据进行操作。


    public Uri insert(Uri uri, ContentValues values):该方法用于往ContentProvider加入数据。
    public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于从ContentProvider删除数据。
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):
    该方法用于更新ContentProvider中的数据。

    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder): 该方法用于从ContentProvider中获取数据。


    以下为insert数据的代码

    values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME, "22");
        //第一个參数往哪个uri插入数据
     Uri uri = getContentResolver().insert(FirstProviderMetaData.UserTableMetaData.CONTENT_URI, values);

    六、监听ContentProvider中数据的变化
        假设ContentProvider的訪问者须要知道ContentProvider中的数据发生变化,能够在ContentProvider发生数据变化时调用getContentResolver().notifyChange(uri, null)来通知注冊在此URI上的訪问者,代码例如以下:
     //通过监听器,通知数据已经改变
        getContext().getContentResolver().notifyChange(insertedUserUri, null);

        实现以上步骤生成效果:


    以下附上源代码下载地址:http://download.csdn.net/detail/yangweixing10/7216371

  • 相关阅读:
    为了可怜的成功率、缥缈的理想堵上这个人生,这对多数人来说都不值得(他以及他的家庭都会面临灾难)
    很多人在大学期间开发软件,接国企的案子,彻夜写程序;或者做家教、攒书、卖商品,难道那不是一种创业?
    为什么知乎上很多人都反对创业?(上战场的士兵如果先拿枪打打靶练练枪法,研究研究战术之后,战损比肯定要更好看一点)
    核心思想:创业一定要非常低调的进入市场
    核心思想:互联网创业十问?(大部分创业者是从学习借鉴成功者起步的,不需要把商业模式考虑完备,失败者没资格说趁着年轻...)4种失败的信号 good
    poj 3181 Dollar Dayz(求组成方案的背包+大数)
    核心思想:各位准创业者,不要再想什么蓝海市场了,沉下心来先干吧(试问连自己的生活都不敢去颠覆,谈什么颠覆互联网,颠覆传统行业,颠覆整个世界呢?)
    只想把技术做好,维持一份可观的收入,就精专一门;有创业想法,就全栈
    亢龙有悔,还是亢龙无悔?——是需要看情况的(兵无常势,水无常形)——看准了,就下本钱投入
    Uniconnection 连 mysql 有时会断线的
  • 原文地址:https://www.cnblogs.com/llguanli/p/7267958.html
Copyright © 2011-2022 走看看