標籤:android uri
ContentProvider概述
public abstract class
ContentProvider
extends Object
implements ComponentCallbacks2
Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver interface. A content provider is only required if you need to share data between multiple applications. For example, the contacts data is used by multiple applications and must be stored in a content provider. If you don’t need to share data amongst multiple applications you can use a database directly via SQLiteDatabase.
When a request is made via a ContentResolver the system inspects the authority of the given URI and passes the request to the content provider registered with the authority. The content provider can interpret the rest of the URI however it wants. The UriMatcher class is helpful for parsing URIs.
Android的ContentProvider作用就是在應用程式之間交換資料,如果我們採用檔案分享權限設定的方式需要注意的是必須採用特定的資料訪問方式,而ContentProvider是不同應用程式之間進行資料交換的標準API。ContentProvider以某種Uri的形式對外提供資料,而其他應用使用ContentResolver根據Uri去訪問操作指定資料。
ContentProvider也是Android應用的四大組件之一,與Activity、Service、BroadcastReceiver相似,都需要在AndroidManifest.xml檔案中進行配置。
ContentProvider的使用
- 定義自己的ContentProvider類,繼承子ContentProvider基類;
在AndroidManifest.xml檔案中註冊,並且綁定一個URL。
public class ImageContentProvider extends ContentProvider{
//該方法用於供外部應用從ContentProvider刪除資料@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) { return 0;}//該方法用於返回當前Url所代表資料的MIME類型@Overridepublic String getType(Uri uri) { return null;}//該方法用於供外部應用往ContentProvider添加資料@Overridepublic Uri insert(Uri uri, ContentValues values) { return null;}//該方法在ContentProvider建立後就會被調用,Android開機後,ContentProvider在其它應用第一次訪問它時才會被建立@Overridepublic boolean onCreate() { return false;}//該方法用於供外部應用從ContentProvider中擷取資料@Overridepublic Cursor query(Uri uri, String[] values, String selection, String[] selectionArgs, String sortOrder) { return null;}//該方法用於供外部應用程式更新ContentProvider中的資料@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0;}
}
如果操作的資料屬於集合類型,那麼MIME類型字串應該以vnd.android.cursor.dir/開頭,
例如:要得到所有person記錄的Uri為content://com.ljq.provider.personprovider/person,那麼返回的MIME類型字串應該為:”vnd.android.cursor.dir/person”。
如果要操作的資料屬於非集合類型資料,那麼MIME類型字串應該以vnd.android.cursor.item/開頭,
例如:得到id為10的person記錄,Uri為content://com.ljq.provider.personprovider/person/10,那麼返回的MIME類型字串為:”vnd.android.cursor.item/person”。
註冊ContentProvider只需要在
Uri概述
Uri還是很容易理解的,我們可以和互連網的URL進行類比。
content://com.twilight.providers.imagecontentprovider/image/2
這裡的意思就是訪問image資料總ID為2的記錄。雖然大部分ContentProvider操作的資料都是來自於資料庫,但是有時候可以來自於檔案、XML或網路等其他的儲存方式。
content://com.twilight.providers.imagecontentprovider/image/detail
這裡的意思就是操作image節點下的detail節點。
Uri工具類
Android系統提供了2個操作Uri的工具類,分別是UriMatcher和ContentUris。
(1)UriMatcher類是用來匹配Uri
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);matcher.addURI("com.twilight.providers.imageprovider", "image", 1);matcher.addURI("com.twilight.providers.imageprovider", "image/#", 2);switch (matcher.match(Uri.parse("content://com.twilight.providers.imageprovider/image/7"))) { case 1: break; case 2: break; default: break;}
註冊完需要匹配的Uri後,是用matcher.match(uri)方法對輸入的Uri進行匹配,如果匹配就返回匹配碼。
(2)ConentUris類用於操作Uri路徑後面的ID部分。
Uri uri1 = Uri.parse("content://com.twilight.providers.imageprovider/image");Uri resultUri = ContentUris.withAppendedId(uri1, 7);Uri uri2 = Uri.parse("content://com.twilight.providers.imageprovider/image/7");long resultId = ContentUris.parseId(uri2);
使用ContentResolver操作資料
ContentProvider相當於一個網站,而ContentResolver則相對於HttpClient。一般來說Content是單例模式,當多個應用程式通過ContentResolver來操作ContentProvider提供的資料時,資料操作會委託給同一個ContentProvider處理。
(1)調用Activity的ContentResolver()擷取ContentResolver對象;
(2)使用ContentResolover的insert、delete、update、query方法操作資料,如果是系統提供的ContentProvider,只需要知道ContentProvider的Uri即可。
ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.twilight.providers.imageprovider/image");ContentValues values = new ContentValues();values.put("name", "pic1");values.put("date", "2014-03-10");resolver.insert(uri, values);
監聽ContentProvider的資料改變
getContext().getContentResolver().notifyChange(uri, null);
當ContentProvider所共用的資料發生了改變,這行代碼可以通知所有註冊在改Uri上的監聽者,為了在應用程式中監聽ContentProvider資料的改變,需要利用Android提供了ContentObserver基類。
監聽ContentProvider資料改變的監聽器需要繼承ContentObserver類,並重寫改基類所定義的onChange(boolean selfChange)方法。在使用的時候需要通過ContentProvider向指定的Uri註冊ContentObserver監聽器。
final class ImageObserver extends ContentObserver { public ImageObserver(Handler handler) { super(handler); } public void onChange(boolean selfChange) { } } getContentResolver().registerContentObserver(Uri.parse("content://com.twilight.providers.imageprovider/image"), true, new ImageObserver(new Handler()));
Android學習_ContentProvider和Uri