Android学习之五种数据存储方式(三)

本文介绍了Android数据存储方式中的ContentProvider存储。它是不同应用间数据共享的唯一机制,为存储和获取数据提供统一接口。还阐述了使用Uri类处理数据,以及Uri类、UriMatcher类和ContentUris类实现数据匹配,最后给出了在Android Studio实现其访问联系人数据的步骤。
Android数据存储方式之ContentProvider存储

  1.ContentProvider简介
  ☆☆☆ ContentProvider是Android平台在不同应用程序之间实现数据共享的唯一机制;如果一个应用程序需要让别的应用程序能够操作自己的数据,可采用这种机制。
  ☆☆☆ ContentProvider为存储和获取数据提供统一的接口;以类似数据库中表的形式来组成数据,提供了一种多应用间数据共享的方式;且Android内置的许多数据都是使用该方式供开发者调用的,这时就用到另外一个类(ContentResolver),通过Uri来操作数据从而实现对数据的处理。
  ☆☆☆ 使用Uri类来实现对数据的处理:
  Uri是一个通用资源标志符,将其分为A、B、C、D,4个部分:在这里插入图片描述
  A:无法改变的标准前缀,如:“content://”、"tel://"等。当前缀是"content://"时,说明可通过ContentProvider控制这些数据;
  B:URI的标识,它通过authorities属性声明,限制一个类的访问,用于限制是哪个ContentProvider能够有权限提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的类名;
  C:路径,可以近似的理解为需要操作的数据库中表的名字;
  D:如果URI中包含表示需要获取的记录的ID,则就返回该ID对应的数据,如果没有ID,就表示返回全部。
  2.使用Uri类和UriMatcher类以及ContentUris类来实现对数据的匹配
  ☆2.1 可以通过Uri类的parse方法将字符串转换为Uri对象:
  Uri uri = Uri.parse(“content://com.android.contentprovider/Topic”);
  ☆2.2 使用UriMatcher类来实现对数据的匹配:
  使用UriMatcher类对象的addURI(contact,path,code)方法注册URI:

方法说明
public void addURI(String authority, String path, int code) 往UriMatcher类里添加一个Uri,我们可以理解为UriMatcher为一个Uri的容器,里面包含着要操作的Uri,用于业务逻辑的处理,path相当于Uri中上述所说的路径,也就是想要操作的数据表名,第三个参数code,如果通过下面的match()方法匹配成功就返回这个code值。

  使用UriMatcher类对象的match(Uri uri)方法来匹配Uri:

方法说明
public int match(Uri uri) 与传入的Uri匹配,它会首先与找我们之前通过addURI方法添加进来的Uri匹配,如果匹配成功就返回之前我们设置的code值,否则返回一个值为-1的常量UriMatcher.NO_MATCH。

  ☆2.3.使用ContentUris类来实现对数据的匹配
  可以通过该类的withAppendedId(Uri uri, long id)来添加id:
    给只有路径的Uri添加id,返回添加了id信息的Uri;
    可通过该方法来获取到特定行的数据。
  可以通过该类的parseId(Uri uri)来获取Uri中的id信息:
    通过该方法可以知道uri具体访问的是哪行的数据。

  3.ContentProvider核心类
  ContentProvider常用方法:

方法说明
public abstract boolean onCreate() 在ContentProvider创建后被调用
public abstract Uri insert(Uri uri, Content Values values) 根据Uri插入values对应的数据
public abstract int delete(Uri uri, String selection, String[] selectionArgs) 根据Uri删除selection指定条件所匹配的全部记录
public abstract int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)根据Uri修改selection指定条件所匹配的全部记录
public abstract Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)根据Uri查询出selection指定条件所匹配的全部记录,并且可以指定查询哪些列(projection)以什么方式(sortOrder)排序
public abstract String getType(Uri uri) 返回当前Uri所指向数据的MIME类型,MIME类型由自己定义。如果该Uri对应的数据包括多条记录,那MIME类型的字符串就以vnd.android.cursor.dir/开头, 如果Uri对应的数据只包含一条记录,那MIME类型的字符串就以vnd.android.cursor.item/开头,执行query()方法返回Cursor对象时,系统将不需要再验证,若返回的字符串不能被系统识别,在执行query()方法返回Cursor对象时将需要再验证。

  ☆☆☆Android Studio实现ContentProvider访问联系人数据
  1.打开Android Studio,新建工程后,在activity_main.xml中,建立1个Button,1个ListView。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="lession.example.com.learncontentprovider.MainActivity">
    
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
        <Button
            android:text="获取手机联系人信息"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/button"
            android:textSize="20sp"
            android:textColor="@android:color/holo_red_dark" />
            
        <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/listView" />
            
    </LinearLayout>
</RelativeLayout>

  2.在MainActivity.java中,编写相关代码。

package lession.example.com.learncontentprovider;

import android.content.ContentResolver;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;
/*
 * 获取手机联系人信息
 */
public class MainActivity extends AppCompatActivity {
    private ArrayAdapter<String> adapter;
    private List<String> list;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取ListView实例
        ListView lv = (ListView) findViewById(R.id.listView);
        //获取Button实例
        Button bt = (Button) findViewById(R.id.button);
        ContentResolver cr = this.getContentResolver();
        final Cursor cs = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                null,null,null,null);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                while (cs.moveToNext()){
                    String name = cs.getString
                            (cs.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String number = cs.getString
                            (cs.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    //添加信息
                    list.add(name+"\n"+number);
                }
                //更新适配器
                adapter.notifyDataSetChanged();
            }
        });
        //获取数据源
        list = new ArrayList<>();
        //创建适配器
        adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,list);
        //设置适配器
        lv.setAdapter(adapter);
    }
}

  3.在AndroidManifest.xml中,添加权限。

<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>

  运行结果:
在这里插入图片描述
  这就是ContentProvider存储数据的使用,如果转载以及CV操作,请务必注明出处,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值