天天看點

Android元件之自定義ContentProvider

Android的資料存儲有五種方式Shared Preferences、網絡存儲、檔案存儲、外儲存儲、SQLite,一般這些存儲都隻是在單獨的一個應用程式之中達到一個資料的共享,有時候我們需要操作其他應用程式的一些資料,例如常見系統裡的通訊錄,短信,照片等等,是以雲存儲,通訊錄,豔照門等等就孕育而生了。ContentProvider可以了解成内容提供者,也可以了解為一個接口,就是提供了一個供外部通路的接口,有的時候需要進行權限控制。

ContentProvider向我們提供了我們在應用程式之前共享資料的一種機制,而我們知道每一個應用程式都是運作在不同的應用程式的,不同程式的之間資料共享是現實的需要,程式總不能使閉環的,Android中的ContentProvider外共享資料的好處是統一了資料的通路方式。簡單總結說下:

ContentProvider為存儲和擷取資料提供了統一的接口。ContentProvide對資料進行封裝,不用關心資料存儲的細節。使用表的形式來組織資料。

使用ContentProvider可以在不同的應用程式之間共享資料。 

Android為常見的一些資料提供了預設的ContentProvider(包括音頻、視訊、圖檔和通訊錄等)。 

說到了ContentProvider這麼多好處,不能不說下Uri(Universal Resource Identifier)注意不是URL,通用資源辨別符,看個簡單的讀取聯系人的Uri,content://contacts/people,

content://是字首,固定的;

contacts 主機名(或叫Authority)用于唯一辨別這個ContentProvider,外部調用者可以根據這個辨別來調用;

people  路徑(path)表示我們要操作的資料,路徑的建構根據業務而定;

俗話說,欲善其事必先利其器,想要成為一個内容提供者,就先需要有資料,先建立一個SqlDbConncetion:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<code>public</code> <code>class</code> <code>SqlDBConnection </code><code>extends</code> <code>SQLiteOpenHelper {</code>

<code>    </code><code>private</code> <code>static</code> <code>final</code> <code>String DbName =</code><code>"Book.db"</code><code>;</code>

<code>    </code><code>private</code> <code>static</code> <code>int</code> <code>version=</code><code>1</code><code>;</code>

<code>    </code><code>public</code> <code>SqlDBConnection(Context context) {</code>

<code>        </code><code>super</code><code>(context, DbName, </code><code>null</code><code>, version);</code>

<code>    </code><code>}</code>

<code>    </code><code>@Override</code>

<code>    </code><code>public</code> <code>void</code> <code>onCreate(SQLiteDatabase db) {</code>

<code>        </code><code>// TODO Auto-generated method stub</code>

<code>         </code><code>String sqlString=</code><code>"create table Book (id integer primary key autoincrement,Name nvarchar(200),Title nvarchar(200))"</code><code>;</code>

<code>         </code><code>db.execSQL(sqlString);</code>

<code>    </code><code>public</code> <code>void</code> <code>onUpgrade(SQLiteDatabase db, </code><code>int</code> <code>oldVersion, </code><code>int</code> <code>newVersion) {</code>

<code>}</code>

  上篇文章講的junit測試這個時候可以拿過來使用一下初始化下資料:

<code>public</code> <code>class</code> <code>BookCase </code><code>extends</code> <code>AndroidTestCase {</code>

<code>    </code><code>public</code> <code>void</code> <code>Intial() {</code>

<code>        </code><code>SqlDBConnection dbConnection = </code><code>new</code> <code>SqlDBConnection(getContext());</code>

<code>        </code><code>SQLiteDatabase sqlDataBase = dbConnection.getWritableDatabase();</code>

<code>        </code><code>long</code> <code>row = </code><code>0</code><code>;</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i &lt; </code><code>5</code><code>; i++) {</code>

<code>            </code><code>ContentValues values = </code><code>new</code> <code>ContentValues();</code>

<code>            </code><code>values.put(</code><code>"Name"</code><code>, </code><code>"書籍"</code><code>+i);</code>

<code>            </code><code>values.put(</code><code>"Title"</code><code>, </code><code>"标題"</code> <code>+ i);</code>

<code>            </code><code>row = sqlDataBase.insert(</code><code>"Book"</code><code>, </code><code>null</code><code>, values);</code>

<code>            </code><code>Log.i(</code><code>"BookCase"</code><code>, </code><code>"插入成功:"</code> <code>+ row);</code>

<code>        </code><code>}</code>

 前面是基礎工作,這個時候就可以建立一個自己的ContentProvider:

<a href="http://www.cnblogs.com/xiaofeixiang/p/4072486.html#">+ View Code</a>

 主機名是需要自己去AndroidManifest.xml檔案中自己配置的,要求是唯一的,最好是用包名就好:

<code>&lt;provider android:name=</code><code>"com.example.googlecontentprovider.MyContentProvider"</code>

<code>         </code><code>android:authorities=</code><code>"com.example.googlecontentprovider.MyContentProvider"</code><code>&gt;&lt;/provider&gt;</code>

  如果覺得上面的那一串代碼不是很好了解,下面調用的時候我會分别解釋。

方法寫在一個應用程式中調用屬于正常,在另外一個程式中調用該程式的方法就是類似于接口了,下面先看原來初始化的資料:

Android元件之自定義ContentProvider

重新建立一個Android測試項目,定義為BookCase,首先插入資料,定義一個Uri,這裡面主機名就是上面定義的包名,book/insert與CONTENT_INSERT是對應的:

<code>public</code> <code>void</code> <code>bookInsert() {</code>

<code>    </code><code>Uri uri = Uri</code>

<code>            </code><code>.parse(</code><code>"content://com.example.googlecontentprovider.MyContentProvider/book/insert"</code><code>);</code>

<code>    </code><code>ContentResolver resolver = getContext().getContentResolver();</code>

<code>    </code><code>ContentValues values = </code><code>new</code> <code>ContentValues();</code>

<code>    </code><code>values.put(</code><code>"Name"</code><code>, </code><code>"書籍5"</code><code>);</code>

<code>    </code><code>values.put(</code><code>"Title"</code><code>, </code><code>"标題5"</code><code>);</code>

<code>    </code><code>uri = resolver.insert(uri, values);</code>

<code>    </code><code>Log.i(</code><code>"BookCase"</code><code>, </code><code>"Uri"</code> <code>+ uri);</code>

<code>    </code><code>long</code> <code>id = ContentUris.parseId(uri);</code>

<code>    </code><code>Log.i(</code><code>"BookCase"</code><code>, </code><code>"測試成功"</code> <code>+ id);</code>

  顯示結果如下:

Android元件之自定義ContentProvider

然後更新剛才插入的資料,同樣的更具Code給Uri指派,然後初始化一個ContentResolver,調用update方法:

<code>public</code> <code>void</code> <code>bookUpdate() {</code>

<code>            </code><code>.parse(</code><code>"content://com.example.googlecontentprovider.MyContentProvider/book/update"</code><code>);</code>

<code>    </code><code>ContentValues values=</code><code>new</code> <code>ContentValues();</code>

<code>    </code><code>values.put(</code><code>"Name"</code><code>, </code><code>"修改"</code><code>);</code>

<code>    </code><code>int</code> <code>count = resolver.update(uri, values, </code><code>" id=?"</code><code>,</code><code>new</code> <code>String[]{</code><code>"10"</code><code>});</code>

<code>    </code><code>Log.i(</code><code>"BookCase"</code><code>, </code><code>"更新了"</code> <code>+ count + </code><code>"行"</code><code>);</code>

  結果如下:

Android元件之自定義ContentProvider

删除插入的資料:

<code>public</code> <code>void</code> <code>bookDelete() {</code>

<code>        </code><code>Uri uri = Uri</code>

<code>                </code><code>.parse(</code><code>"content://com.example.googlecontentprovider.MyContentProvider/book/delete"</code><code>);</code>

<code>        </code><code>ContentResolver resolver = getContext().getContentResolver();</code>

<code>        </code><code>String where =</code><code>" id=?"</code><code>;</code>

<code>        </code><code>String[] argString = {</code><code>"10"</code><code>};</code>

<code>        </code><code>int</code> <code>count = resolver.delete(uri, where, argString);</code>

<code>        </code><code>Log.i(</code><code>"BookCase"</code><code>, </code><code>"删除了"</code> <code>+ count + </code><code>"行"</code><code>);</code>

結果如下:

Android元件之自定義ContentProvider

查詢所有的資料:

<code>public</code> <code>void</code> <code>bookQuery() {</code>

<code>            </code><code>.parse(</code><code>"content://com.example.googlecontentprovider.MyContentProvider/book/query"</code><code>);</code>

<code>    </code><code>Cursor  cursor=resolver.query(uri, </code><code>new</code> <code>String[]{</code><code>"id"</code><code>,</code><code>"Name"</code><code>,</code><code>"Title"</code><code>}, </code><code>null</code><code>, </code><code>null</code><code>, </code><code>null</code><code>);</code>

<code>    </code><code>if</code> <code>(cursor.getCount()&gt;</code><code>0</code><code>) {</code>

<code>        </code><code>while</code> <code>(cursor.moveToNext()) {</code>

<code>            </code><code>int</code> <code>id=cursor.getInt(cursor.getColumnIndex(</code><code>"Id"</code><code>));</code>

<code>            </code><code>String nameString=cursor.getString(cursor.getColumnIndex(</code><code>"Name"</code><code>));</code>

<code>            </code><code>String titleString=cursor.getString(cursor.getColumnIndex(</code><code>"Title"</code><code>));</code>

<code>            </code><code>Log.i(</code><code>"BookCase"</code><code>, id+</code><code>"---"</code><code>+nameString+</code><code>"---"</code><code>+titleString);</code>

<code>    </code> 

  Log下的記錄:

Android元件之自定義ContentProvider

查詢單條記錄:

<code>public</code> <code>void</code> <code>bookQuerySingle() {</code>

<code>    </code><code>uri=ContentUris.withAppendedId(uri,</code><code>1</code><code>);</code>

 結果如圖:

Android元件之自定義ContentProvider

本文轉自Fly_Elephant部落格園部落格,原文連結:http://www.cnblogs.com/xiaofeixiang/p/4072486.html,如需轉載請自行聯系原作者

繼續閱讀