ContentProviderイニシャル


原文:http://www.cnblogs.com/linjiqin/archive/2011/05/28/2061396.html
一、ContentProvider(コンテンツプロバイダ)によるデータ共有
ContentProviderのandroidでの役割は、データを対外的に共有することです.つまり、ContentProviderを通じてアプリケーションのデータを他のアプリケーションに共有してアクセスすることができます.他のアプリケーションはContentProviderを通じてアプリケーションのデータを削除して調べることができます.データ共有については,以前にファイルの操作モードを学習したが,ファイルの操作モードがContextであることを知っていた.MODE_WORLD_READADBLEまたはContext.MODE_WORLD_WRITEABLEも同様にデータを対外的に共有することができる.では、ここではなぜContentProviderを使ってデータを対外共有するのでしょうか.このように、ファイル操作モードを採用してデータを対外共有すると、データのアクセス方式はデータ記憶の方式によって異なり、データのアクセス方式が統一できない.例えば、xmlファイルを採用してデータを対外共有するには、xml解析を行ってからデータを読み取る必要がある.sharedpreferencesを使用してデータを共有するには、sharedpreferences APIを使用してデータを読み込む必要があります.ContentProviderを使用してデータを対外的に共有するメリットは、データへのアクセス方法を統一することです.アプリケーションがContentProviderを介してデータを共有する必要がある場合、最初のステップはContentProviderを継承し、次の方法を書き換える必要があります.
public class PersonContentProvider extends ContentProvider{
   public boolean onCreate()
   public Uri insert(Uri uri, ContentValues values)
   public int delete(Uri uri, String selection, String[] selectionArgs)
   public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
   public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
   public String getType(Uri uri)
}


2つ目はAndroidManifestですxmlはを使用してContentProviderを構成します.他のアプリケーションがContentProviderを見つけるために、ContentProviderはauthorities(ホスト名/ドメイン名)を使用して一意の識別を行います.ContentProviderはWebサイトと見なすことができます(サイトもデータ提供者です).authoritiesは彼のドメイン名です.
<manifest.... >
   <application android:icon="@drawable/icon" android:label="@string/app_name">
      <provider android:name=".PersonContentProvider" android:authorities="com.ljq.providers.personprovider"/>
   </application>
</manifest>

          
             
二、Uri紹介
Uriは操作するデータを表し、Uriは主に2つの部分の情報を含んでいる:1』操作が必要なContentProvider、2』はContentProviderの中のどんなデータに対して操作を行い、1つのUriは以下のいくつかの部分から構成されている:
ContentProvider初步_第1张图片                  
ContentProvider(コンテンツプロバイダ)のschemeはAndroidによって規定されており、schemeはcontent://ホスト名(またはAuthority)でこのContentProviderを一意に識別するために使用され、外部呼び出し者はこの識別に基づいてそれを見つけることができる.(path)は、私たちが操作するデータを表すために使用することができ、パスの構築はビジネスによって決まる.以下のように、personテーブルのidが10のレコードを操作するには、/person/10 personテーブルのidが10のレコードのnameフィールドを操作し、person/10/nameはpersonテーブルのすべてのレコードを操作し、このようなパスを構築することができる./personはxxxテーブルのレコードを操作するレコードは、このようなパスを構築することができる:/xxxはもちろん操作するデータは必ずしもデータベースから来なくてもよいし、ファイル、xmlあるいはネットワークなどの他の記憶方式であってもよい.以下のように、xmlファイルの中のpersonノードの下のnameノードを操作するには、このようなパスを構築することができる:/person/nameは、1つの文字列をUriに変換するには、Uriクラスのparse()メソッドを使用することができる.以下:Uriuri=Uri.parse("content://com.ljq.provider.personprovider/person")
                
             
三、UriMatcher類の使用紹介
Uriは操作するデータを表すため,Uriを解析し,Uriからデータを取得することがしばしば必要である.Androidシステムは、Uriを操作するための2つのツールクラスを提供しています.それぞれUriMatcherとContentUrisです.それらの使用を把握すると、私たちの開発作業に便利になります.UriMatcherクラスはUriをマッチングするために使用されます.まず、最初のステップでは、Uriパスをすべて登録する必要があります.以下のようにします.
//  UriMatcher.NO_MATCH              UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//  match()    content://com.ljq.provider.personprovider/person  ,      1 sMatcher.addURI("com.ljq.provider.personprovider", "person", 1);//      uri,            //  match()    content://com.ljq.provider.personprovider/person/230  ,      2 sMatcher.addURI("com.ljq.provider.personprovider", "person/#", 2);//#      switch (sMatcher.match(Uri.parse("content://com.ljq.provider.personprovider/person/10"))) { 
   case 1
     break;
   case 2
     break;
   default://         break;
}


一致するUriを登録したら、sMatcherを使用できます.match(uri)メソッドは入力したUriをマッチングし,マッチングするとマッチングコードを返し,マッチングコードはaddURI()メソッドを呼び出して入力した3番目のパラメータであり,マッチングを仮定するcontent://com.ljq.provider.personprovider/personパス、返される一致コードは1です.
              
                 
四、ContentUris類の使用紹介
ContentUrisクラスは、Uriパスの後ろのIDセクションを操作するために使用され、2つの比較的実用的な方法があります.withAppendedId(uri,id)は、パスにIDセクションを追加するために使用されます.
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10); 
//    Uri :content://com.ljq.provider.personprovider/person/10

parseId(uri)メソッドは、パスからID部分を取得するために使用される.
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//      :10

          
              
五、ContentProviderによるデータ共有
ContentProviderクラスの主なメソッドの役割:public boolean onCreate():このメソッドはContentProviderの作成後に呼び出され、Androidが起動すると、ContentProviderは他のアプリケーションが初めてアクセスしたときに作成されます.public Uri insert(Uriuri,ContentValue):外部アプリケーションからContentProviderへのデータの追加に使用します.public int delete(Uriuri,String selection,String[]selectionArgs):外部アプリケーションがContentProviderからデータを削除するために使用されます.public int update(Uriuri,ContentValues values,String selection,String[]selectionArgs):このメソッドは、外部アプリケーションがContentProviderのデータを更新するために使用されます.public Cursor query(Uriuri,String[]projection,String selection,String[]selectionArgs,String sortOrder):外部アプリケーションがContentProviderからデータを取得するために使用されます.public String getType(Uriuri):このメソッドは、現在のUrlで表されるデータのMIMEタイプを返すために使用されます.
操作データが集合型に属する場合、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」です.
              
                
六、ContentResolverを使用してContentProviderのデータを操作する
外部アプリケーションでContentProviderのデータの追加、削除、変更、クエリー操作が必要な場合は、ContentResolverクラスを使用して完了できます.ContentResolverオブジェクトを取得するには、Activityが提供するgetContentResolver()メソッドを使用します.ContentResolverクラスには、ContentProviderクラスと同じ署名の4つのメソッドがあります.public Uri insert(Uriuri,ContentValues values):ContentProviderにデータを追加するためのメソッドです.public int delete(Uriuri,String selection,String[]selectionArgs):ContentProviderからデータを削除する方法です.public int update(Uriuri,ContentValue,String selection,String[]selectionArgs):ContentProviderのデータを更新する方法です.public Cursor query(Uriuri,String[]projection,String selection,String[]selectionArgs,String sortOrder):ContentProviderからデータを取得する方法です.
これらのメソッドの最初のパラメータはUriであり、操作するContentProviderとその中のどのデータを操作するかを表します.
仮に与えられたのは:Uri.parse("content://com.ljq.providers.personprovider/person/10「)では、ホスト名com.ljq.providers.personproviderのContentProviderが操作され、操作データはpersonテーブルのidが10のレコードになります.
ContentResolverを使用して、ContentProviderのデータの追加、削除、変更、クエリーを行います.
ContentResolver resolver =  getContentResolver();
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person");
//       ContentValues values = new ContentValues();
values.put("name", "linjiqin");
values.put("age", 25);
resolver.insert(uri, values);  
//  person       Cursor cursor = resolver.query(uri, null, null, null, "personid desc");
while(cursor.moveToNext()){
   Log.i("ContentTest", "personid="+ cursor.getInt(0)+ ",name="+ cursor.getString(1));
}
// id 1    name       zhangsan ContentValues updateValues = new ContentValues();
updateValues.put("name", "zhangsan");
Uri updateIdUri = ContentUris.withAppendedId(uri, 2);
resolver.update(updateIdUri, updateValues, null, null);
//  id 2    Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);
resolver.delete(deleteIdUri, null, null);


            
               
七、ContentProviderにおけるデータの変化を傍受する
ContentProviderのアクセス者がContentProviderのデータの変化を知る必要がある場合は、ContentProviderのデータの変化時にgetContentResolver()を呼び出すことができる.notifyChange(uri,null)は、このURIに登録されている訪問者に通知し、例は以下の通りである.
public class PersonContentProvider extends ContentProvider {
   public Uri insert(Uri uri, ContentValues values) {
      db.insert("person", "personid", values);
      getContext().getContentResolver().notifyChange(uri, null);
   }
}

ContentProviderのアクセス者がデータ変更通知を取得する必要がある場合は、ContentObserverを使用してデータ(データはuri記述)をリスニングする必要があります.データ変更通知を監視すると、ContentObserverのonChange()メソッドが呼び出されます.
getContentResolver().registerContentObserver(Uri.parse("content://com.ljq.providers.personprovider/person"),
       true, new PersonObserver(new Handler()));
public class PersonObserver extends ContentObserver{
   public PersonObserver(Handler handler) {
      super(handler);
   }
   public void onChange(boolean selfChange) {
      //                 }
}