• 说说ContentProvider的用法


      最近写了一个数据库,这个数据库的服务没包装在Provider中,导致在测试的时候老是出现Cursor没有关闭的问题,搞不定,所以决定把数据的增删查改都写在Provider中,刚开始的时候不知道怎么写,参考了下源码中的闹钟的Provider。

      下面是系统源码中的闹钟的Provider:

    1 /*
    2 * Copyright (C) 2007 The Android Open Source Project
    3 *
    4 * Licensed under the Apache License, Version 2.0 (the "License");
    5 * you may not use this file except in compliance with the License.
    6 * You may obtain a copy of the License at
    7 *
    8 * http://www.apache.org/licenses/LICENSE-2.0
    9 *
    10 * Unless required by applicable law or agreed to in writing, software
    11 * distributed under the License is distributed on an "AS IS" BASIS,
    12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13 * See the License for the specific language governing permissions and
    14 * limitations under the License.
    15 */
    16
    17  package com.android.alarmclock;
    18
    19  import android.content.ContentProvider;
    20  import android.content.ContentUris;
    21  import android.content.ContentValues;
    22  import android.content.Context;
    23  import android.content.UriMatcher;
    24  import android.database.Cursor;
    25  import android.database.SQLException;
    26  import android.database.sqlite.SQLiteDatabase;
    27  import android.database.sqlite.SQLiteOpenHelper;
    28  import android.database.sqlite.SQLiteQueryBuilder;
    29  import android.net.Uri;
    30  import android.text.TextUtils;
    31
    32  public class AlarmProvider extends ContentProvider {
    33 private SQLiteOpenHelper mOpenHelper;
    34
    35 private static final int ALARMS = 1;
    36 private static final int ALARMS_ID = 2;
    37 private static final UriMatcher sURLMatcher = new UriMatcher(
    38 UriMatcher.NO_MATCH);
    39
    40 static {
    41 sURLMatcher.addURI("com.android.alarmclock", "alarm", ALARMS);
    42 sURLMatcher.addURI("com.android.alarmclock", "alarm/#", ALARMS_ID);
    43 }
    44
    45 private static class DatabaseHelper extends SQLiteOpenHelper {
    46 private static final String DATABASE_NAME = "alarms.db";
    47 private static final int DATABASE_VERSION = 5;
    48
    49 public DatabaseHelper(Context context) {
    50 super(context, DATABASE_NAME, null, DATABASE_VERSION);
    51 }
    52
    53 @Override
    54 public void onCreate(SQLiteDatabase db) {
    55 db.execSQL("CREATE TABLE alarms (" +
    56 "_id INTEGER PRIMARY KEY," +
    57 "hour INTEGER, " +
    58 "minutes INTEGER, " +
    59 "daysofweek INTEGER, " +
    60 "alarmtime INTEGER, " +
    61 "enabled INTEGER, " +
    62 "vibrate INTEGER, " +
    63 "message TEXT, " +
    64 "alert TEXT);");
    65
    66 // insert default alarms
    67   String insertMe = "INSERT INTO alarms " +
    68 "(hour, minutes, daysofweek, alarmtime, enabled, vibrate, message, alert) " +
    69 "VALUES ";
    70 db.execSQL(insertMe + "(7, 0, 127, 0, 0, 1, '', '');");
    71 db.execSQL(insertMe + "(8, 30, 31, 0, 0, 1, '', '');");
    72 db.execSQL(insertMe + "(9, 00, 0, 0, 0, 1, '', '');");
    73 }
    74
    75 @Override
    76 public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
    77 if (Log.LOGV) Log.v(
    78 "Upgrading alarms database from version " +
    79 oldVersion + " to " + currentVersion +
    80 ", which will destroy all old data");
    81 db.execSQL("DROP TABLE IF EXISTS alarms");
    82 onCreate(db);
    83 }
    84 }
    85
    86 public AlarmProvider() {
    87 }
    88
    89 @Override
    90 public boolean onCreate() {
    91 mOpenHelper = new DatabaseHelper(getContext());
    92 return true;
    93 }
    94
    95 @Override
    96 public Cursor query(Uri url, String[] projectionIn, String selection,
    97 String[] selectionArgs, String sort) {
    98 SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    99
    100 // Generate the body of the query
    101   int match = sURLMatcher.match(url);
    102 switch (match) {
    103 case ALARMS:
    104 qb.setTables("alarms");
    105 break;
    106 case ALARMS_ID:
    107 qb.setTables("alarms");
    108 qb.appendWhere("_id=");
    109 qb.appendWhere(url.getPathSegments().get(1));
    110 break;
    111 default:
    112 throw new IllegalArgumentException("Unknown URL " + url);
    113 }
    114
    115 SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    116 Cursor ret = qb.query(db, projectionIn, selection, selectionArgs,
    117 null, null, sort);
    118
    119 if (ret == null) {
    120 if (Log.LOGV) Log.v("Alarms.query: failed");
    121 } else {
    122 ret.setNotificationUri(getContext().getContentResolver(), url);
    123 }
    124
    125 return ret;
    126 }
    127
    128 @Override
    129 public String getType(Uri url) {
    130 int match = sURLMatcher.match(url);
    131 switch (match) {
    132 case ALARMS:
    133 return "vnd.android.cursor.dir/alarms";
    134 case ALARMS_ID:
    135 return "vnd.android.cursor.item/alarms";
    136 default:
    137 throw new IllegalArgumentException("Unknown URL");
    138 }
    139 }
    140
    141 @Override
    142 public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
    143 int count;
    144 long rowId = 0;
    145 int match = sURLMatcher.match(url);
    146 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    147 switch (match) {
    148 case ALARMS_ID: {
    149 String segment = url.getPathSegments().get(1);
    150 rowId = Long.parseLong(segment);
    151 count = db.update("alarms", values, "_id=" + rowId, null);
    152 break;
    153 }
    154 default: {
    155 throw new UnsupportedOperationException(
    156 "Cannot update URL: " + url);
    157 }
    158 }
    159 if (Log.LOGV) Log.v("*** notifyChange() rowId: " + rowId + " url " + url);
    160 getContext().getContentResolver().notifyChange(url, null);
    161 return count;
    162 }
    163
    164 @Override
    165 public Uri insert(Uri url, ContentValues initialValues) {
    166 if (sURLMatcher.match(url) != ALARMS) {
    167 throw new IllegalArgumentException("Cannot insert into URL: " + url);
    168 }
    169
    170 ContentValues values;
    171 if (initialValues != null)
    172 values = new ContentValues(initialValues);
    173 else
    174 values = new ContentValues();
    175
    176 if (!values.containsKey(Alarm.Columns.HOUR))
    177 values.put(Alarm.Columns.HOUR, 0);
    178
    179 if (!values.containsKey(Alarm.Columns.MINUTES))
    180 values.put(Alarm.Columns.MINUTES, 0);
    181
    182 if (!values.containsKey(Alarm.Columns.DAYS_OF_WEEK))
    183 values.put(Alarm.Columns.DAYS_OF_WEEK, 0);
    184
    185 if (!values.containsKey(Alarm.Columns.ALARM_TIME))
    186 values.put(Alarm.Columns.ALARM_TIME, 0);
    187
    188 if (!values.containsKey(Alarm.Columns.ENABLED))
    189 values.put(Alarm.Columns.ENABLED, 0);
    190
    191 if (!values.containsKey(Alarm.Columns.VIBRATE))
    192 values.put(Alarm.Columns.VIBRATE, 1);
    193
    194 if (!values.containsKey(Alarm.Columns.MESSAGE))
    195 values.put(Alarm.Columns.MESSAGE, "");
    196
    197 if (!values.containsKey(Alarm.Columns.ALERT))
    198 values.put(Alarm.Columns.ALERT, "");
    199
    200 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    201 long rowId = db.insert("alarms", Alarm.Columns.MESSAGE, values);
    202 if (rowId < 0) {
    203 throw new SQLException("Failed to insert row into " + url);
    204 }
    205 if (Log.LOGV) Log.v("Added alarm rowId = " + rowId);
    206
    207 Uri newUrl = ContentUris.withAppendedId(Alarm.Columns.CONTENT_URI, rowId);
    208 getContext().getContentResolver().notifyChange(newUrl, null);
    209 return newUrl;
    210 }
    211
    212 public int delete(Uri url, String where, String[] whereArgs) {
    213 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    214 int count;
    215 long rowId = 0;
    216 switch (sURLMatcher.match(url)) {
    217 case ALARMS:
    218 count = db.delete("alarms", where, whereArgs);
    219 break;
    220 case ALARMS_ID:
    221 String segment = url.getPathSegments().get(1);
    222 rowId = Long.parseLong(segment);
    223 if (TextUtils.isEmpty(where)) {
    224 where = "_id=" + segment;
    225 } else {
    226 where = "_id=" + segment + " AND (" + where + ")";
    227 }
    228 count = db.delete("alarms", where, whereArgs);
    229 break;
    230 default:
    231 throw new IllegalArgumentException("Cannot delete from URL: " + url);
    232 }
    233
    234 getContext().getContentResolver().notifyChange(url, null);
    235 return count;
    236 }
    237 }

      其实对于数据库的操作,无非是四种,增删查改;在这里我仿照系统的闹钟的Provider自己写了一个Provider。以供以后忘记了的时候好参考参考:

      首先我们邀创建一个数据库,并确定数据库是否生成。

    1 package com.test.provider;
    2
    3  import android.content.ContentValues;
    4  import android.content.Context;
    5  import android.database.sqlite.SQLiteDatabase;
    6  import android.database.sqlite.SQLiteOpenHelper;
    7  import android.net.Uri;
    8  import android.provider.BaseColumns;
    9
    10  public class AppDataBase extends SQLiteOpenHelper {
    11
    12 //数据库的名字
    13   private static final String DATABASE_NAME = "test.db";
    14 private static final int DATABASE_VERSION = 1;
    15 //数据表的名字
    16   private static final String TABLE_NAME = "test";
    17 //数据表中的字段
    18   public static final String FIELD_ID = "field_id";
    19 public static final String FIELD_SHOW = "field_show";
    20 public static final String FIELD_LOCTION = "field_location";
    21
    22 //用于表示该数据的一个Uri
    23   public static final Uri CONTENT_URI = Uri.parse("content://com.fermax.monitor/apps");
    24
    25 //创建数据库
    26   public AppDataBase (Context context) {
    27 super(context, DATABASE_NAME, null, DATABASE_VERSION);
    28 }
    29
    30 //创建表
    31 @Override
    32 public void onCreate (SQLiteDatabase db) {
    33 String sql = "Create table "+TABLE_NAME+"("+BaseColumns._ID + " integer primary key autoincrement," +
    34 FIELD_ID + " integer not null, " +
    35 FIELD_LOCTION + " integer not null, " +
    36 FIELD_SHOW + " integer not null );";
    37 db.execSQL(sql);
    38
    39 initDataBase(db);
    40 }
    41
    42 //初始化表
    43 private void initDataBase (SQLiteDatabase db) {
    44 ContentValues cv = new ContentValues();
    45 cv.put(FIELD_ID, 1);
    46 cv.put(FIELD_LOCTION, 1);
    47 cv.put(FIELD_SHOW, 1);
    48 db.insert(TABLE_NAME, null, cv);
    49
    50 cv.clear();
    51 cv.put(FIELD_ID, 2);
    52 cv.put(FIELD_LOCTION, 2);
    53 cv.put(FIELD_SHOW, 1);
    54 db.insert(TABLE_NAME, null, cv);
    55
    56 cv.clear();
    57 cv.put(FIELD_ID, 3);
    58 cv.put(FIELD_LOCTION, 3);
    59 cv.put(FIELD_SHOW, 0);
    60 db.insert(TABLE_NAME, null, cv);
    61
    62 cv.clear();
    63 cv.put(FIELD_ID, 4);
    64 cv.put(FIELD_LOCTION, 4);
    65 cv.put(FIELD_SHOW, 1);
    66 db.insert(TABLE_NAME, null, cv);
    67
    68 cv.clear();
    69 cv.put(FIELD_ID, 5);
    70 cv.put(FIELD_LOCTION, 5);
    71 cv.put(FIELD_SHOW, 0);
    72 db.insert(TABLE_NAME, null, cv);
    73
    74 cv.clear();
    75 cv.put(FIELD_ID, 6);
    76 cv.put(FIELD_LOCTION, 6);
    77 cv.put(FIELD_SHOW, 0);
    78 db.insert(TABLE_NAME, null, cv);
    79
    80 cv.clear();
    81 cv.put(FIELD_ID, 7);
    82 cv.put(FIELD_LOCTION, 7);
    83 cv.put(FIELD_SHOW, 0);
    84 db.insert(TABLE_NAME, null, cv);
    85
    86 cv.clear();
    87 cv.put(FIELD_ID, 8);
    88 cv.put(FIELD_LOCTION, 8);
    89 cv.put(FIELD_SHOW, 1);
    90 db.insert(TABLE_NAME, null, cv);
    91
    92 cv.clear();
    93 cv.put(FIELD_ID, 9);
    94 cv.put(FIELD_LOCTION, 9);
    95 cv.put(FIELD_SHOW, 0);
    96 db.insert(TABLE_NAME, null, cv);
    97
    98 cv.clear();
    99 cv.put(FIELD_ID, 10);
    100 cv.put(FIELD_LOCTION, 10);
    101 cv.put(FIELD_SHOW, 0);
    102 db.insert(TABLE_NAME, null, cv);
    103
    104 cv.clear();
    105 cv.put(FIELD_ID, 11);
    106 cv.put(FIELD_LOCTION, 11);
    107 cv.put(FIELD_SHOW, 0);
    108 db.insert(TABLE_NAME, null, cv);
    109
    110 cv.clear();
    111 cv.put(FIELD_ID, 12);
    112 cv.put(FIELD_LOCTION, 12);
    113 cv.put(FIELD_SHOW, 0);
    114 db.insert(TABLE_NAME, null, cv);
    115
    116 cv.clear();
    117 cv.put(FIELD_ID, 13);
    118 cv.put(FIELD_LOCTION, 13);
    119 cv.put(FIELD_SHOW, 0);
    120 db.insert(TABLE_NAME, null, cv);
    121
    122 cv.clear();
    123 cv.put(FIELD_ID, 14);
    124 cv.put(FIELD_LOCTION, 14);
    125 cv.put(FIELD_SHOW, 1);
    126 db.insert(TABLE_NAME, null, cv);
    127
    128 cv.clear();
    129 cv.put(FIELD_ID, 15);
    130 cv.put(FIELD_LOCTION, 15);
    131 cv.put(FIELD_SHOW, 1);
    132 db.insert(TABLE_NAME, null, cv);
    133
    134 cv.clear();
    135 cv.put(FIELD_ID, 16);
    136 cv.put(FIELD_LOCTION, 16);
    137 cv.put(FIELD_SHOW, 1);
    138 db.insert(TABLE_NAME, null, cv);
    139
    140 cv.clear();
    141 cv.put(FIELD_ID, 17);
    142 cv.put(FIELD_LOCTION, 17);
    143 cv.put(FIELD_SHOW, 0);
    144 db.insert(TABLE_NAME, null, cv);
    145
    146 cv.clear();
    147 cv.put(FIELD_ID, 18);
    148 cv.put(FIELD_LOCTION, 18);
    149 cv.put(FIELD_SHOW, 1);
    150 db.insert(TABLE_NAME, null, cv);
    151
    152 cv.clear();
    153 cv.put(FIELD_ID, 19);
    154 cv.put(FIELD_LOCTION, 19);
    155 cv.put(FIELD_SHOW, 0);
    156 db.insert(TABLE_NAME, null, cv);
    157
    158 cv.clear();
    159 cv.put(FIELD_ID, 20);
    160 cv.put(FIELD_LOCTION, 20);
    161 cv.put(FIELD_SHOW, 0);
    162 db.insert(TABLE_NAME, null, cv);
    163
    164 cv.clear();
    165 cv.put(FIELD_ID, 21);
    166 cv.put(FIELD_LOCTION, 21);
    167 cv.put(FIELD_SHOW, 0);
    168 db.insert(TABLE_NAME, null, cv);
    169
    170 cv.clear();
    171 cv.put(FIELD_ID, 22);
    172 cv.put(FIELD_LOCTION, 22);
    173 cv.put(FIELD_SHOW, 0);
    174 db.insert(TABLE_NAME, null, cv);
    175
    176 cv.clear();
    177 cv.put(FIELD_ID, 23);
    178 cv.put(FIELD_LOCTION, 23);
    179 cv.put(FIELD_SHOW, 0);
    180 db.insert(TABLE_NAME, null, cv);
    181
    182 cv.clear();
    183 cv.put(FIELD_ID, 24);
    184 cv.put(FIELD_LOCTION, 24);
    185 cv.put(FIELD_SHOW, 0);
    186 db.insert(TABLE_NAME, null, cv);
    187 }
    188
    189 //用于更新表
    190 @Override
    191 public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) {
    192 String sql=" DROP TABLE IF EXISTS "+TABLE_NAME;
    193 db.execSQL(sql);
    194 onCreate(db);
    195 }
    196 }

    上面是创建了一个数据库并初始化了很多值,但我们并不知道数据库是否生成了,我们可以写一个测试类,来测试一下数据库是否生成了。

    package com.test.provider;

    import android.test.AndroidTestCase;

    /**
    * test the database.
    *
    @author shang
    *
    */
    public class DBTest extends AndroidTestCase {

    //用于测试数据库是否生成
    public void TestHomeDB() throws Exception {
    AppDataBase appDataBase
    = new AppDataBase(this.getContext());
    appDataBase.getWritableDatabase();
    }
    }

      写完测试类后不要忘记在manifest.xml文件中加上包和instrumentation:

    1 <!-- android:targetPackage 是用来存放生成的数据库的位置的,可以和manifest中的package相同 -->
    2 <instrumentation
    3 android:name="android.test.InstrumentationTestRunner"
    4 android:targetPackage="com.test.provider"
    5 android:label="test for my app"/>

      如下所示:

      还有测试包,这个放在application下面,上面一个放在manifest根目录下面:

    1 <!-- 这个是用来说明android测试的包 -->
    2 <uses-library android:name="android.test.runner"/>

      然后运行测试包,看data中对应的目录下生成了数据库文件没有:

    我们可以看到生成了数据库了,好了,既然生成了数据库,我们就要把数据库的增删查改包装在一个Provider中,这个Provider是要继承ContentProvider的:

    1 package com.test.provider;
    2
    3 import android.content.ContentProvider;
    4 import android.content.ContentUris;
    5 import android.content.ContentValues;
    6 import android.content.UriMatcher;
    7 import android.database.Cursor;
    8 import android.database.sqlite.SQLiteDatabase;
    9 import android.database.sqlite.SQLiteOpenHelper;
    10 import android.database.sqlite.SQLiteQueryBuilder;
    11 import android.net.Uri;
    12 import android.text.TextUtils;
    13 import android.util.Log;
    14
    15 public class AppProvider extends ContentProvider {
    16
    17 private SQLiteOpenHelper mOpenHelper;
    18
    19 //用于做所有的操作
    20 private static final int APPS = 1;
    21
    22 //用于做跟ID有关的操作
    23 private static final int APPS_ID = 2;
    24
    25 //初始化UriMatcher
    26 private static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    27
    28 //在UriMatcher中加入指定的Uri
    29 static {
    30 mUriMatcher.addURI("com.fermax.monitor", "apps", APPS);
    31 mUriMatcher.addURI("com.fermax.monitor", "apps/#", APPS_ID);
    32 }
    33
    34 //拿到OpenHelper的对象
    35 @Override
    36 public boolean onCreate () {
    37 mOpenHelper = new AppDataBase(getContext());
    38 return true;
    39 }
    40
    41 //做查询操作
    42 @Override
    43 public Cursor query (Uri uri, String[] projection, String selection,
    44 String[] selectionArgs, String sortOrder) {
    45 SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    46
    47 int match = mUriMatcher.match(uri);
    48 switch (match) {
    49 //直接查询表中的所有的数据
    50 case APPS:
    51 qb.setTables("test");
    52 break;
    53
    54 //根据Id查询
    55 case APPS_ID:
    56 qb.setTables("test");
    57 qb.appendWhere("_id =");
    58
    59 //拿到Uri后面的第一个参数,并将它赋给数据库中的字段_id.
    60 qb.appendWhere(uri.getPathSegments().get(1));
    61 break;
    62
    63 default:
    64 throw new IllegalArgumentException("Unknow Uri " + uri);
    65 }
    66
    67 //根据指定的条件查询数据,并返回Cursor
    68 SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    69 Cursor ret = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
    70 if(ret == null) {
    71 Log.v("ddd","apps: apps query failed");
    72 } else {
    73 ret.setNotificationUri(getContext().getContentResolver(), uri);
    74 }
    75 return ret;
    76 }
    77
    78 //返回给定的Uri数据的MIME类型
    79 @Override
    80 public String getType (Uri uri) {
    81 int match = mUriMatcher.match(uri);
    82 switch (match) {
    83 case APPS:
    84 return "vnd.android.cursor.dir/apps";
    85
    86 case APPS_ID:
    87 return "vnd.android.cursor.item/apps";
    88
    89 default:
    90 throw new IllegalArgumentException("Unknow uri");
    91 }
    92 }
    93
    94 //做插入操作
    95 @Override
    96 public Uri insert (Uri uri, ContentValues initialValues) {
    97 //插入操作要对所有的字段插入,如果带有参数,则报异常
    98 if(mUriMatcher.match(uri) != APPS) {
    99 throw new IllegalArgumentException("Can not insert into uri " + uri);
    100 }
    101
    102 //将给定的值插入数据库,如果给的值为空,则设默认值0
    103 ContentValues values;
    104 if(initialValues != null) {
    105 values = new ContentValues(initialValues);
    106 } else {
    107 values = new ContentValues();
    108 }
    109
    110 if(!values.containsKey(AppDataBase.FIELD_ID)) {
    111 values.put(AppDataBase.FIELD_ID, 0);
    112 }
    113
    114 if(!values.containsKey(AppDataBase.FIELD_LOCTION)) {
    115 values.put(AppDataBase.FIELD_LOCTION, 0);
    116 }
    117
    118 if(!values.containsKey(AppDataBase.FIELD_SHOW)) {
    119 values.put(AppDataBase.FIELD_SHOW, 0);
    120 }
    121
    122 //向表中插入数据。
    123 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    124 long rowId = db.insert("test", null, values);
    125 if(rowId < 0) {
    126 throw new IllegalArgumentException("Failed to insert to " + uri);
    127 }
    128
    129 Uri newUri = ContentUris.withAppendedId(AppDataBase.CONTENT_URI, rowId);
    130 getContext().getContentResolver().notifyChange(newUri, null);
    131 return newUri;
    132 }
    133
    134 //删除数据
    135 @Override
    136 public int delete (Uri uri, String selection, String[] selectionArgs) {
    137 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    138 int count;
    139 int match = mUriMatcher.match(uri);
    140 switch (match) {
    141
    142 //如果没有参数,则删除指定的参数的列
    143 case APPS:
    144 count = db.delete("test", selection, selectionArgs);
    145 break;
    146
    147 //如果带有参数ID,则删除指定的参数和指定Id的列
    148 case APPS_ID:
    149 String segment = uri.getPathSegments().get(1);
    150 if(TextUtils.isEmpty(selection)) {
    151 selection = "_id=" + segment;
    152 } else {
    153 selection = "_id=" + segment + "and (" + selection + ")" ;
    154 }
    155
    156 //执行删除操作
    157 count = db.delete("test", selection, selectionArgs);
    158 break;
    159
    160 default:
    161 throw new IllegalArgumentException("can not delete from uri " + uri);
    162
    163 }
    164 getContext().getContentResolver().notifyChange(uri, null);
    165 return count;
    166 }
    167
    168 //执行更新操作
    169 @Override
    170 public int update (Uri uri, ContentValues values, String selection,
    171 String[] selectionArgs) {
    172 int count;
    173 long rowId = 0;
    174 int match = mUriMatcher.match(uri);
    175 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    176 switch (match) {
    177 //对指定的id的列进行更新
    178 case APPS_ID:
    179
    180 //拿到Uri参数中的id,并转化成long类型,然后根据指定的id更新
    181 String segment = uri.getPathSegments().get(1);
    182 rowId = Long.valueOf(segment);
    183 count = db.update("test", values, "_id = " + rowId, null);
    184 break;
    185
    186 default:
    187 throw new IllegalArgumentException("can not update the uri " + uri);
    188 }
    189 getContext().getContentResolver().notifyChange(uri, null);
    190 return count;
    191 }
    192
    193 }

    完了之后我们要在manifest里面注册这个Provider:

    1 <!-- 注册数据库的Provider -->
    2 <provider
    3 android:name=".AppProvider"
    4 android:authorities="com.fermax.monitor"
    5 android:exported="true"/

    完了之后就可以在测试类中测试了,用Provider做增删查改非常方便:

    1
    2 //用于测试插入一条数据到数据库
    3 public void testInsert() throws Exception {
    4 ContentValues cv = new ContentValues();
    5 cv.put(AppDataBase.FIELD_ID, 100);
    6 cv.put(AppDataBase.FIELD_LOCTION, 100);
    7 cv.put(AppDataBase.FIELD_SHOW, 100);
    8 getContext().getContentResolver().insert(AppDataBase.CONTENT_URI, cv);
    9 }
    10
    11 //用于测试从数据库中删除一条数据
    12 public void testDelete() throws Exception {
    13 int _id = 25;
    14 String uriStr = "content://com.fermax.monitor/apps/" + _id;
    15 Uri uri = Uri.parse(uriStr);
    16 getContext().getContentResolver().delete(uri, null, null);
    17 }
    18
    19 //用于测试从数据库中查询数据
    20 public void testQuery() throws Exception {
    21 Cursor c = getContext().getContentResolver().query(AppDataBase.CONTENT_URI, null, null, null, null);
    22 if(c != null && c.getCount() != 0) {
    23 while(c.moveToNext()) {
    24 int location = c.getInt(c.getColumnIndexOrThrow(AppDataBase.FIELD_LOCTION));
    25 System.out.println("location = " + location);
    26 }
    27 }
    28 c.close();
    29 }
    30
    31 //用于测试从数据库中更新一条数据
    32 public void testUpdate() throws Exception {
    33 int _id = 24;
    34 String uriString = "content://com.fermax.monitor/apps/" + _id;
    35 Uri uri = Uri.parse(uriString);
    36 ContentValues cv = new ContentValues();
    37 cv.put(AppDataBase.FIELD_LOCTION, 150);
    38 getContext().getContentResolver().update(uri, cv, null, null);
    39 }

    运行完成之后可以去数据库中查看数据库中的数据是否发生了变化,这里我就不在赘述。

    下面是这个工程的打包文件:

    点击我下载
  • 相关阅读:
    说说ReactiveCocoa 2
    xcode5 添加Build Phases脚本
    关于CoreData的一个工具Mogenerator的使用
    Keystone controller.py & routers.py代码解析
    Openstack Restful API 开发框架 Paste + PasteDeploy + Routes + WebOb
    Openstack Restful API 开发框架 Paste + PasteDeploy + Routes + WebOb
    Web 开发规范 — WSGI
    Web 开发规范 — WSGI
    Openstack API 类型 & REST 风格
    Openstack API 类型 & REST 风格
  • 原文地址:https://www.cnblogs.com/shang53880/p/2038714.html
Copyright © 2020-2023  润新知