Android學習筆記——Content Provider(一)

Content Provider是Android系統四大組件之一:android

官方的定義是:A Content Provider manages access to a central repository of data.數據庫

那麼Android系統爲何要提供這樣一個組件呢?安全

 

我的以爲至少有以下兩點:網絡

首先,Android是一個很重視安全性的系統(貌似Android系統的漏洞最多~~~),一個應用的數據對於其餘應用來講私有的,除非你把數據存儲在SD卡上。但不少時候咱們須要在程序之間共享數據,好比咱們想獲取聯繫人的信息之類的。這時Content Provider就提供了一個很好的解決方案,將數據的存儲、讀取細節隱藏,提供一個統一的接口供其它應用訪問,而且還能夠作到權限控制,在必定程度上保證數據的安全性。ide

其次就是進程間通訊(inter-process communication IPC)的問題,若是讓開發者本身來處理這些細節無疑會加大開發的難度。而Content Provider提供了相似於b/s結構的模式,b與c之間是以一種什麼方式去實現咱們並不關心,就像咱們大部分時候不用去關心網絡究竟是怎麼鏈接的。開發者應該關心的是怎麼去實現一個Content Provider或去調用一個Content Provider。ui

 

URI(Uniform Resource Identifier)統一資源標識符spa

URI和URL(Unifrom Resource Locator)很像,但二者並非同一個東西,不過能夠拿來作類推。翻譯

對於一個content URI的通常形式是這樣子的:code

content://user_dictionary/words

 

其中「content://」稱爲scheme,相似於http://或ftp://,表示這個URI的類型。orm

「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的使用。

相關文章
相關標籤/搜索