好记性不如烂笔杆android学习笔记<九> Content Provider 数据共享机制

21,//Content Provider 数据共享机制
<1>//在minifest.xml文件中注册
<provider
android:name="zjq.contentprovider.FirstContentProvider"
android:authorities="zjq.contentprovider.FirstContentProvider"
/>
//main.xml文件中添加一个TextView和两个Button
Java文件
<2>//创建一个数据库的工具类

 1 public class FirstProviderMetaData {
 2     public static final String AUTHORIY = "zjq.contentprovider.FirstContentProvider";
 3     //数据库名称
 4     public static final String DATABASE_NAME = "FirstProvider.db";
 5     //数据库版本
 6     public static final int DATABASE_VERSION = 1;
 7     //表名
 8     public static final String USERS_TABLE_NAME = "users";
 9     
10     public static final class UserTableMetaData implements BaseColumns{
11     //表名
12     public static final String TABLE_NAME = "users";
13     //访问该ContentProvider的URL
14     public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORIY + "/users");
15     //访问该ContentProvider所返回的数据类型的定义
16     public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.firstprovider.user";
17     public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.firstprovider.user";
18     //列名
19     public static final String USER_NAME = "name";
20     //默认的排序方法
21     public static final String DEFAULT_SORT_ORDER = "_id desc";
22     }
23 }


<3>//创建一个数据库
//DatabaseHelper作为一个访问SQLite的助手类,提供两个方面的功能
//第一,getReadableDatabase(),getWritableDatabase()可以获得SQLiteDatabase对象,通过该对象可以对数据库进行操作
//第二,提供了onCreate和onUpgrade两个回调函数,允许我们创建和升级数据库时,进行自己的操作。

 1 public class DatabaseHelper extends SQLiteOpenHelper {
 2     private static final int VERSION = 1 ;
 3     //在SQLiteOpenHelper的子类中,必须有该构造函数
 4     public DatabaseHelper(Context context, String name, CursorFactory  factory,
 5             int version){
 6         //必须通过super调用父类当中的构造函数
 7         super(context, name, factory, version);
 8     }
 9     public DatabaseHelper(Context context, String name){
10         //必须通过super调用父类当中的构造函数
11         this(context, name,VERSION);
12     }
13     public DatabaseHelper(Context context, String name,int version){
14         //必须通过super调用父类当中的构造函数
15         this(context, name,null, version);
16     }
17     
18     //该函数是在第一次创建数据库的时候执行,实际上是在第一次得到SQLiteDatabase对象的时候,才会调用这个方法
19     @Override
20     public void onCreate(SQLiteDatabase db) {
21         System.out.println("create a Database");
22         //execSQL函数用于执行SQL语句
23         db.execSQL("create table " + FirstProviderMetaData.USERS_TABLE_NAME 
24                 + "(" + FirstProviderMetaData.UserTableMetaData._ID
25                 + " INTEGER PRIMARY KEY AUTOINCREMENT,"
26                 +  FirstProviderMetaData.UserTableMetaData.USER_NAME
27                 + " varchar(20))");
28     }
29     @Override
30     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
31         // TODO Auto-generated method stub
32         System.out.println("update a Database");
33     }
34 }

<4>//创建一个ContentProvider对象,对数据库的接口进行包装:

  1 public class FirstContentProvider extends ContentProvider {
  2 
  3     public static final UriMatcher uriMatcher;
  4     public static final int INCOMING_USER_COLLECTION = 1;
  5     public static final int INCOMING_USER_SINGLE = 2;
  6     private DatabaseHelper dh;
  7     static {
  8         //UriMatcher 在ContentProvider中帮助匹配URL
  9         uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 10         //FirstProviderMetaData.AUTHORIY部分的值是之前URL中/和/之间的内容,所以这里不需要users前的/
 11         uriMatcher.addURI( FirstProviderMetaData.AUTHORIY, "users",
 12                 INCOMING_USER_COLLECTION);
 13         uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "users/#",
 14                 INCOMING_USER_SINGLE);
 15     }
 16     public static HashMap<String,String> userProjectionMap;
 17     static
 18     {
 19         userProjectionMap = new HashMap<String,String>();
 20         userProjectionMap.put(UserTableMetaData._ID,UserTableMetaData._ID);
 21         userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
 22     }
 23     @Override
 24     public int delete(Uri arg0, String arg1, String[] arg2) {
 25         System.out.println("delete");
 26         return 0;
 27     }
 28 
 29     //根据传入的URI,返回该URI所表示的数据类型
 30     @Override
 31     public String getType(Uri uri) {
 32         System.out.println("getType");
 33         switch(uriMatcher.match(uri)){
 34         case INCOMING_USER_COLLECTION:
 35             return UserTableMetaData.CONTENT_TYPE;
 36         case INCOMING_USER_SINGLE:
 37             return UserTableMetaData.CONTENT_TYPE_ITEM;
 38         default:
 39             throw new IllegalArgumentException("Unknown URI" + uri);
 40         }
 41     }
 42     /**
 43      * 该函数的返回值是一个URI,这个URI表示的是刚刚使用这个函数所插入的数据
 44      * content://mars.cp.FirstContentProvider/users/1
 45     */
 46     @Override
 47     public Uri insert(Uri uri, ContentValues values) {
 48         System.out.println("insert");
 49         SQLiteDatabase db = dh.getWritableDatabase();
 50         long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
 51         if(rowId > 0){
 52             Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
 53             //通知监听器,数据已经改变
 54             getContext().getContentResolver().notifyChange(insertedUserUri, null);
 55             return insertedUserUri;
 56         }
 57         throw new SQLException("Failed to insert row into" + uri);
 58     }
 59 
 60     //是一个回调方法,所以说在ContentProvider创建的时候执行
 61     @Override
 62     public boolean onCreate() {
 63         //打开数据库
 64         dh = new DatabaseHelper(getContext(),FirstProviderMetaData.DATABASE_NAME);
 65         System.out.println("FirstContentProvider.java onCreate");
 66         return true;
 67     }
 68     //查询方法
 69     @Override
 70     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
 71             String sortOrder) {
 72         System.out.println("Query Debug");
 73         //SQLiteQueryBuilder类,用于创建一个查询的语句
 74         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
 75         int type = uriMatcher.match(uri);
 76         switch(type){
 77         case INCOMING_USER_COLLECTION:
 78             qb.setTables(UserTableMetaData.TABLE_NAME);
 79             qb.setProjectionMap(userProjectionMap);
 80             break;
 81         case INCOMING_USER_SINGLE:
 82             qb.setTables(UserTableMetaData.TABLE_NAME);
 83             qb.setProjectionMap(userProjectionMap);
 84             qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1));
 85             break;
 86         }
 87         String orderBy;
 88         if(TextUtils.isEmpty(sortOrder)){
 89             orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;
 90         }
 91         else{
 92             orderBy = sortOrder;
 93         }
 94         SQLiteDatabase db = dh.getWritableDatabase();
 95         Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
 96         c.setNotificationUri(getContext().getContentResolver(), uri);
 97         System.out.println("query");
 98         return c;
 99     }
100     @Override
101     public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
102         System.out.println("update");
103         return 0;
104     }
105 }

<5>//创建一个测试用的Activity,对DB进行插入和查找

 1 public class CPActivity extends Activity {
 2     private Button insertButton = null;
 3     private Button queryButton = null;
 4     @Override
 5     public void onCreate(Bundle savedInstanceState) {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.main);
 8         queryButton = (Button) findViewById(R.id.query);
 9         queryButton.setOnClickListener(new QueryListener());
10         insertButton = (Button) findViewById(R.id.insert);
11         insertButton.setOnClickListener(new InsertListener());
12         System.out.println(getContentResolver().getType(FirstProviderMetaData.UserTableMetaData.CONTENT_URI));
13     }
14     class InsertListener implements OnClickListener {
15 
16         @Override
17         public void onClick(View v) {
18             ContentValues values = new ContentValues();
19             //把数据存如Values中
20             values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME,
21                     "zhangsan");
22             Uri uri = getContentResolver()
23                     .insert(
24                             FirstProviderMetaData.UserTableMetaData.CONTENT_URI,
25                             values);
26             System.out.println("uri--->" + uri.toString());
27         }
28 
29     }
30     class QueryListener implements OnClickListener {
31 
32         @Override
33         public void onClick(View v) {
34             //设置查询表中的那些字段,new String[]{"_id","name"}
35             Cursor c = getContentResolver().query(
36                     FirstProviderMetaData.UserTableMetaData.CONTENT_URI, new String[]{"_id","name"},
37                     null, null, null);
38             while(c.moveToNext()){
39                 //System.out.println(c.getString(c.getColumnIndex(UserTableMetaData.USER_NAME)));
40             }
41         }
42     }
43 }

<6>,其他的一些指令

 1 //删除数据库:
 2 
 3 Context.deleteDatabase(String name)删除指定名称的数据库
 4 this.deleteDatabase("myDatabase.db");
 5 //打开数据库:
 6 SQLiteDatabase my_DataBase = this.openOrCreateDatabase("myDatabase.db",MODE_PRIVATE,null);
 7 my_Database.close();
 8 //非查询 SQL 指令
 9 SQLiteDatabase.execSQL(String sql)可以用来执行非查询 SQL 指令,这些指令没有结果
10 包括:CREATE TABLE / DROP TABLE / INSERT 等等
11 //创建一个名为"test"并带两个参数的表
12 my_DataBase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY,
13 someNumber INTERGER);");
14 //在数据库中插入一个元组
15 my_DataBase.execSQL("INSERT INTO test (_id,someNumber) values(1,8);");
16 //删除表
17 my_DataBase.execSQL("DROP TABLE test");

 

原文地址:https://www.cnblogs.com/zjqlogs/p/2779258.html