• Android学习笔记——Content Provider(一)


    Content Provider是Android系统四大组件之一:

    官方的定义是:A Content Provider manages access to a central repository of data.

    那么Android系统为什么要提供这样一个组件呢?

     

    个人觉得至少有如下两点:

    首先,Android是一个很重视安全性的系统(貌似Android系统的漏洞最多~~~),一个应用的数据对于其他应用来说私有的,除非你把数据存储在SD卡上。但很多时候我们需要在程序之间共享数据,比如我们想获取联系人的信息之类的。这时Content Provider就提供了一个很好的解决方案,将数据的存储、读取细节隐藏,提供一个统一的接口供其它应用访问,并且还可以做到权限控制,在一定程度上保证数据的安全性。

    其次就是进程间通信(inter-process communication IPC)的问题,如果让开发者自己来处理这些细节无疑会加大开发的难度。而Content Provider提供了类似于b/s结构的模式,b与c之间是以一种什么方式去实现我们并不关心,就像我们大部分时候不用去关心网络到底是怎么连接的。开发者应该关心的是怎么去实现一个Content Provider或去调用一个Content Provider。

     

    URI(Uniform Resource Identifier)统一资源标识符

    URI和URL(Unifrom Resource Locator)很像,但两者并不是同一个东西,不过可以拿来做类推。

    对于一个content URI的一般形式是这样子的:

    content://user_dictionary/words

    其中“content://”称为scheme,类似于http://或ftp://,表示这个URI的类型。

    “user_dictionary”就类似于域名,但在这里应该叫做authority(这个怎么翻译呢?)。它是一个用来标识不同content provider的名称。

    “words”这里用于表示对哪一个表进行操作。注意,这里这么说是不准确的!

    首先content provider的数据源不一定就是关系型数据库,可以是xml,数据文件甚至是网络数据。

    其次,就算是SQLite之类的数据库,这一部分也不一定就真的是一个真实存在的表,它可能就是某个视图而已,这里说它是某一个表只是方便理解,切记!

     

    如何创建一个Uri呢?

    第一种:可以用Uri.Builder来创建:

    Uri.Builder builder = new Uri.Builder();
    
    builder.scheme("content");
    
    builder.authority("user_dictionary");
    
    builder.path("words");
    
    Uri uri = builder.build();

    还有一种更简单的方法,就是使用Uri.Parse()方法:

    Uri uri = Uri.parse("content://user_dictionary/words");

    显然,第二种要简洁得多了。

     

    有些content provider支持直接查询到某一条记录,就是在上面提到Uri的末尾再加上一个id如:

    content://user_dictionary/words/2

    就表示直接定位到某一个记录上。构建这种Uri有一个简单的方法

    Uri uri = Uri.parse("content://user_dictionary/words");
    
    Uri singleUri = ContentUris.withAppendedId(uri, 4);

    从content provider中检索数据:

    使用一个content provider主要有如下几个步骤:

     

    在AndroidManifest.xml文件中添加相应的权限。

    如,想要查看系统的通话记录应该添加

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

    要注意,content provider读写权限是分开的,读就只能读,写就只能写(不像写外部存储卡那个权限,它其实还含有读的权限)。比如同时还要修改通话记录的话,还应该添加这个权限:

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

    使用ContentResolver的query方法。该方法的签名是这样的:

    public final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 

    如果比较熟悉SQLite的应该对这些参数相当熟悉。不就是把一个SQL语句分成几个部分嘛。

    这个方法将返回一个Cursor,通过这个“游标”我们就可以得到我们想要的数据了。

    下面给一个获取通话记录的例子:

     

        public void getData() {
            
            String[] projection = {
                Calls.NUMBER,
                Calls.DATE,
                Calls.DURATION,
                Calls.TYPE
            };
            Cursor cursor = getContentResolver().query(Calls.CONTENT_URI, projection, null, null, null);
            while (cursor.moveToNext()) {
                for (int i = 0; i < cursor.getColumnCount(); i++) {
                    System.out.println(cursor.getColumnName(i) + "--->" + cursor.getString(i));
                }
                System.out.println("~~~~~~~~~~~~~~~~");
            }
            cursor.close();
        }

    其他方法其实也都是差不多的,看看文档可以掌握了,如果还觉得比较难懂,建议先学一下SQLite的使用。

  • 相关阅读:
    js的event对象 详解
    RestSharp使用详解(1)调用阿里巴巴开放存储服务
    RestSharp使用详解(2)RestSharp的BUG和不足
    WF实例学习笔记:(2)通过Workflow 调用 WCF Data Services 获取数据
    译文:SQL Azure客户端瞬态错误处理最佳实践
    Windbg 基本命令
    RestSharp使用详解(3)OSS文件上传的问题
    Transient Fault Handling and Retry Logic: 瞬间错误处理——重试
    推荐一本免费的Node.js电子书(台湾)
    CSS导航菜单应用滑动门技术的玻璃效果菜单
  • 原文地址:https://www.cnblogs.com/yjiyjige/p/3239847.html
Copyright © 2020-2023  润新知