Android 學習 筆記_06. Content Provider初步


1、作用:

     (1、為存儲和獲取(訪問)數據提供了統一的接口(它對數據的存儲進行了一層封裝,讓我們無需關心數據存儲的細節就可以直接使用。)

     (2、能夠讓我們的數據在不同的應用程序中共享(SQLite只能在同一個應用程序中共享數據)

     (3、Android為常見的一些數據提供了Content Provider(包括了音頻、視頻、圖片、通訊錄等)

2、ContentProvider使用表的形式來組織數據

    

3、統一資源標識符 URL(為資源起名字)

     (1、每個ContentProvider都有一個公共的URl,用於表示該ContentProvider提供的數據

     (2、Android的ContentProvider都存放於android.provider包當中

4、ContentProvider函數:對數據進行增刪改查的操作

      (1、query();

      (2、insert();

      (3、update();

      (4、delete();

      (5、getType();

      (6、onCreate();

5、實現ContentProvider的過程

      (1、定義一個CONTENT_URL常量

      (2、定義一個類,繼承ContentProvider

      (3、實現上述函數方法

      (4、在Manifest.xml中聲明

 

             

 CPActivity.java

 1 package zzl.contentprovider;
 2 
 3 import zzl.contentprovider.FirstProviderMetaData.UserTableMetaData;
 4 import android.app.Activity;
 5 import android.content.ContentValues;
 6 import android.database.Cursor;
 7 import android.net.Uri;
 8 import android.os.Bundle;
 9 import android.view.Menu;
10 import android.view.View;
11 import android.view.View.OnClickListener;
12 import android.widget.Button;
13 
14 public class CPActivity extends Activity {
15     
16     private Button insert=null;
17     private Button query=null;
18 
19     @Override
20     protected void onCreate(Bundle savedInstanceState) {
21         super.onCreate(savedInstanceState);
22         setContentView(R.layout.activity_cp);
23         
24         insert=(Button)findViewById(R.id.insert);
25         query=(Button)findViewById(R.id.query);
26         
27         insert.setOnClickListener(new InsertOnClickListener());
28         query.setOnClickListener(new QueryOnClickListener());
29         System.out.println(getContentResolver().getType(FirstProviderMetaData.UserTableMetaData.CONTENT_URI));
30     }
31     //往子表中插入一條記錄
32     public class InsertOnClickListener implements OnClickListener{
33 
34         public void onClick(View arg0) {
35             // TODO Auto-generated method stub    
36             ContentValues values = new ContentValues();
37             values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME, "tornadomeet");
38             //實際上使用的是ContentResolver的insert方法
39             //該insert中有2個參數,第一個為代表了ContentProvider的URL,第二個參數為要插入的值。此處的insert函數
40             //一執行,則自動調用ContentProvider的insert方法。
41             Uri uri = getContentResolver().insert(FirstProviderMetaData.UserTableMetaData.CONTENT_URI, 
42                     values);
43             System.out.println("uri--->" +uri.toString());
44         }        
45     }
46     
47     
48     //查詢也是采用的ContentResolver中的query方法。
49     public class QueryOnClickListener implements OnClickListener{
50         public void onClick(View v) {
51             // TODO Auto-generated method stub        
52             Cursor c = getContentResolver().query(FirstProviderMetaData.UserTableMetaData.CONTENT_URI, 
53                     null, null, null, null);
54             while(c.moveToNext())
55                 System.out.println(c.getString(c.getColumnIndex(UserTableMetaData.USER_NAME)));
56         }     
57     }
58 
59     @Override
60     public boolean onCreateOptionsMenu(Menu menu) {
61         // Inflate the menu; this adds items to the action bar if it is present.
62         getMenuInflater().inflate(R.menu.activity_cp, menu);
63         return true;
64     }
65 
66 }

FirstProviderMetaData.java

 1 package zzl.contentprovider;
 2 
 3 import android.net.Uri;
 4 import android.provider.BaseColumns;
 5 
 6 public class FirstProviderMetaData {
 7 
 8     //這里的AUTHORTY為包的全名+ContentProvider子類的全名
 9     public static final String AUTHORTY = "zzl.contentprovider.FirstContentProvider";
10     //數據庫名稱
11     public static final String DATABASE_NAME = "FisrtProvider.db";
12     //數據庫版本
13     public static final int DATABASE_VERSION = 1;
14     //數據庫表名
15     public static final String USERS_TABLE_NAME = "users";
16     //表中的字表
17     public static final class UserTableMetaData implements BaseColumns{
18         
19         //子表名
20         public static final String TABLE_NAME = "users";
21         //訪問ContentProvider的URL:CONTENT_URI為常量URL; parse是將文本轉換成URL
22         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORTY + "/users");
23        
24         //返回ContentProvider中表的數據類型
25         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.firstprovider.user";
26         //返回ContentProvider表中item的一條數據類型
27         public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.firstprovider.user";
28         
29         //子表列名
30         public static final String USER_NAME = "name";
31         //表中記錄的默認排序算法,這里是降序排列
32         public static final String DEFAULT_SORT_ORDER = "_id desc";
33         
34         
35     }
36     
37 }

FirstProviderMetaData.java

  1 package zzl.contentprovider;
  2 
  3 import java.util.HashMap;
  4 
  5 import zzl.contentprovider.FirstProviderMetaData.UserTableMetaData;
  6 import zzl.sqlite3.db.DatabaseHelper;
  7 import android.content.ContentProvider;
  8 import android.content.ContentUris;
  9 import android.content.ContentValues;
 10 import android.content.UriMatcher;
 11 import android.database.Cursor;
 12 import android.database.SQLException;
 13 import android.database.sqlite.SQLiteDatabase;
 14 import android.database.sqlite.SQLiteQueryBuilder;
 15 import android.net.Uri;
 16 import android.text.TextUtils;
 17 
 18 public class FirstContentProvider extends ContentProvider{
 19     
 20     //定義一個UriMatcher類對象,用來匹配URL:形成映射,規則是否合法
 21     public static final UriMatcher uriMatcher;
 22     //組時的ID
 23     public static final int INCOMING_USER_COLLECTION = 1;
 24     //單個時的ID
 25     public static final int INCOMING_USER_SIGNAL = 2;
 26     //定義一個DatabaseHelper對象
 27     private DatabaseHelper dh;
 28     
 29     static{
 30         //UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼
 31         uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 32         uriMatcher.addURI(FirstProviderMetaData.AUTHORTY, "users", INCOMING_USER_COLLECTION);
 33         //后面加了#表示為單個:users下面的某一個users
 34         uriMatcher.addURI(FirstProviderMetaData.AUTHORTY, "users/#", INCOMING_USER_SIGNAL);
 35    }
 36     //新建一個HashMap,后面執行插入操作時有用
 37     public static HashMap<String, String> userProjectionMap;
 38     static
 39     {
 40         userProjectionMap = new HashMap<String, String>();
 41         //給數據庫表中的列取別名
 42         userProjectionMap.put(UserTableMetaData._ID, UserTableMetaData._ID);
 43         userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
 44     }
 45     
 46     //得到ContentProvider的數據類型,返回的參數URL所代表的數據類型
 47     @Override
 48     public String getType(Uri uri) {
 49         // TODO Auto-generated method stub
 50         System.out.println("getType");
 51         switch(uriMatcher.match(uri)){
 52         //matcher滿足URL的前2項(即協議+路徑)為第1種情況時,switch語句的值為URL的第3項,此處為INCOMING_USER_COLLECTION
 53         case INCOMING_USER_COLLECTION:
 54             return UserTableMetaData.CONTENT_TYPE;
 55         case INCOMING_USER_SIGNAL:
 56             return UserTableMetaData.CONTENT_TYPE_ITEM;
 57         default:
 58             throw new IllegalArgumentException("Unknown URI" + uri);
 59         }
 60     }
 61     //該函數的返回值是一個URL
 62     //這個URL表示的是剛剛使用這個函數的所插入的數據
 63     //content://zzl.FirstContentProvider/users/
 64     @Override
 65     public Uri insert(Uri uri, ContentValues values) {
 66         // TODO Auto-generated method stub
 67         System.out.println("insert");
 68         SQLiteDatabase db = dh.getWritableDatabase();
 69         long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
 70         if(rowId > 0){            
 71             //發出通知給監聽器,說明數據已經改變
 72             //ContentUris為工具類
 73             Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
 74             getContext().getContentResolver().notifyChange(insertedUserUri, null);
 75             
 76             return insertedUserUri;
 77         }
 78         throw new SQLException("Failed to insert row into" + uri);
 79     }
 80 
 81     //回調函數,在ContentProvider創建的時候調用
 82     @Override
 83     public boolean onCreate() {
 84         // TODO Auto-generated method stub
 85         System.out.println("onCreate");
 86         dh = new DatabaseHelper(getContext(), FirstProviderMetaData.DATABASE_NAME);
 87         return true;
 88     }
 89     @Override
 90     public int delete(Uri uri, String selection, String[] selectionArgs) {
 91         // TODO Auto-generated method stub
 92         System.out.println("delete");
 93         return 0;
 94     }
 95 
 96     @Override
 97     public int update(Uri uri, ContentValues values, String selection,
 98             String[] selectionArgs) {
 99         // TODO Auto-generated method stub
100         System.out.println("update");
101         return 0;
102     }
103 
104     @Override
105     public Cursor query(Uri uri, String[] projection, String selection,
106             String[] selectionArgs, String sortOrder) {
107         // TODO Auto-generated method stub
108         System.out.println("query");
109         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
110         switch(uriMatcher.match(uri)){
111         case INCOMING_USER_COLLECTION:
112             qb.setTables(UserTableMetaData.TABLE_NAME);//設置表的名稱
113             qb.setProjectionMap(userProjectionMap);//其中userProjectionMap為上面建立好了的Hashmap
114             break;
115         case INCOMING_USER_SIGNAL:
116             qb.setTables(UserTableMetaData.TABLE_NAME);//設置表的名稱
117             qb.setProjectionMap(userProjectionMap);//其中userProjectionMap為上面建立好了的hashmap
118             //uri.getPathSegments()得到Path部分,即把URL的協議+authory部分去掉,把剩下的部分分段獲取,這里取第
119             //一部分
120             qb.appendWhere(UserTableMetaData._ID + "=" +uri.getPathSegments().get(1));//設置where條件
121             break;
122         }
123         //排序
124         String orderBy;
125         if(TextUtils.isEmpty(sortOrder)){
126             orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;//傳入的排序參數為空的時候采用默認的排序
127         }
128         else{
129             orderBy = sortOrder;//不為空時用指定的排序方法進行排序
130         }
131         SQLiteDatabase db = dh.getWritableDatabase();
132         //采用傳入的參數進行查詢
133         Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
134         //發出通知
135         c.setNotificationUri(getContext().getContentResolver(), uri);
136         return c;
137     }
138 }

總結:

    (1、 要在Manifest中加入

      <provider
               android:name="zzl.contentprovider.FirstContentProvider"
              android:authorities="zzl.contentprovider.FirstContentProvider"
     />

 

   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM