LeoYan Blog

技术分享,生活记录。

0%

Android 之 ContentProvider (二) 示例代码

转载请注明出处:www.leoyanblog.com

本文出自 LeoYan 的博客

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 LeoYan 即可关注。

示例说明

ContentProviderDemo_01

  在创建ContentProvider前,首先要实现底层的数据源,数据源包括数据库、文件系统或网络等,然后继承ContentProvider类中实现基本数据操作的接口函数。调用者不能直接调用ContentProvider的接口函数,需要通过ContentResolver对象,通过URI间接调用ContentProvider。

注:示例中所选的数据源是 SQLite。

Demo 结构

  Demo结构如下:

ContentProviderDemo_02

ContentProviderDemo_03

关键代码

  People.Java (TestContentProvider 和 TestContentResolver 都有)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class People {
public static final String MIME_DIR_PREFIX = "vnd.android.cursor.dir";
public static final String MIME_ITEM_PREFIX = "vnd.android.cursor.item";
public static final String MIME_ITEM = "vnd.leo.people";

public static final String MIME_TYPE_SINGLE = MIME_ITEM_PREFIX + "/" + MIME_ITEM;
public static final String MIME_TYPE_MULTIPLE = MIME_DIR_PREFIX + "/" + MIME_ITEM;

public static final String AUTHORITY = "com.leo.peopleprovider";
public static final String PATH_SINGLE = "people/#";
public static final String PATH_MULTIPLE = "people";
public static final String CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_MULTIPLE;
public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING);

public static final String KEY_ID = "_id";
public static final String KEY_NAME = "name";
public static final String KEY_AGE = "age";
public static final String KEY_HEIGHT = "height";
}

  DBOpenHelper.java (TestContentProvider 中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class DBOpenHelper extends SQLiteOpenHelper {

public static final String DB_NAME = "people.db";
public static final String DB_TABLE = "peopleinfo";
public static final int DB_VERSION = 1;

private static final String DB_CREATE = "create table " +
DB_TABLE + "(" + People.KEY_ID + " integer primary key autoincrement, " +
People.KEY_NAME + " text not null, " + People.KEY_AGE + " integer, " +
People.KEY_HEIGHT + " float);";

public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_CREATE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
onCreate(db);
}
}

  PeopleProvider.java (TestContentProvider 中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
public class PeopleProvider extends ContentProvider {

private SQLiteDatabase db;
private DBOpenHelper dbOpenHelper;

private static final int MULTIPLE_PEOPLE = 1;
private static final int SINGLE_PEOPLE = 2;
private static final UriMatcher uriMatcher;

static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(People.AUTHORITY, People.PATH_MULTIPLE, MULTIPLE_PEOPLE);
uriMatcher.addURI(People.AUTHORITY, People.PATH_SINGLE, SINGLE_PEOPLE);
}

@Override
public boolean onCreate() {
Context context = getContext();
dbOpenHelper = new DBOpenHelper(context, DBOpenHelper.DB_NAME, null, DBOpenHelper.DB_VERSION);
db = dbOpenHelper.getWritableDatabase();
if (db == null) {
return false;
} else {
return true;
}
}

@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(DBOpenHelper.DB_TABLE);
switch (uriMatcher.match(uri)) {
case SINGLE_PEOPLE:
// 单条数据的处理
qb.appendWhere(People.KEY_ID + "=" + uri.getPathSegments().get(1));
break;
default:
break;
}
Cursor cursor = qb.query(db,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}

@Nullable
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case MULTIPLE_PEOPLE:
// 多条数据的处理
return People.MIME_TYPE_MULTIPLE;
case SINGLE_PEOPLE:
// 单条数据的处理
return People.MIME_TYPE_SINGLE;
default:
throw new IllegalArgumentException("Unkown uro:" + uri);
}
}

@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
long id = db.insert(DBOpenHelper.DB_TABLE, null, values);
if (id > 0) {
Uri newUri = ContentUris.withAppendedId(People.CONTENT_URI, id);
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
throw new SQLException("failed to insert row into " + uri);
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case MULTIPLE_PEOPLE:
// 多条数据的处理
count = db.delete(DBOpenHelper.DB_TABLE, selection, selectionArgs);
break;
case SINGLE_PEOPLE:
// 单条数据的处理
String segment = uri.getPathSegments().get(1);
count = db.delete(DBOpenHelper.DB_TABLE, People.KEY_ID + "=" + segment, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unsupported URI:" + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int count;
switch (uriMatcher.match(uri)) {
case MULTIPLE_PEOPLE:
// 多条数据的处理
count = db.update(DBOpenHelper.DB_TABLE, values, selection, selectionArgs);
break;
case SINGLE_PEOPLE:
// 单条数据的处理
String segment = uri.getPathSegments().get(1);
count = db.update(DBOpenHelper.DB_TABLE, values, People.KEY_ID + "=" + segment, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknow URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}

}

  AndroidManifest.xml (TestContentProvider 中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.leo.testcontentprovider" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<provider
android:authorities="com.leo.peopleprovider"
android:name=".PeopleProvider"
android:exported="true"/>
</application>
</manifest>

  MainActivity.java (TestContentResolver 中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
public class MainActivity extends AppCompatActivity {

...

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resolver = this.getContentResolver();
initView();
initEvent();
}

private void initView() {
...
}

private void initEvent() {
addBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put(People.KEY_NAME, nameEt.getText().toString());
values.put(People.KEY_AGE, Integer.parseInt(ageEt.getText().toString()));
values.put(People.KEY_HEIGHT, Float.parseFloat(heightEt.getText().toString()));
Uri newUri = resolver.insert(People.CONTENT_URI, values);
labelTv.setText("添加成功,URI:" + newUri);
}
});

queryBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEt.getText().toString());
Cursor cursor = resolver.query(uri,
new String[]{People.KEY_ID, People.KEY_NAME, People.KEY_AGE, People.KEY_HEIGHT},
null, null, null);
if (cursor == null) {
labelTv.setText("数据库中没有数据");
return;
}
labelTv.setText("数据库:" + String.valueOf(cursor.getCount()) + "条记录");
String msg = "";
if (cursor.moveToFirst()) {
do {
msg += "ID: " + cursor.getString(cursor.getColumnIndex(People.KEY_ID)) + ",";
msg += "姓名: " + cursor.getString(cursor.getColumnIndex(People.KEY_NAME)) + ",";
msg += "年龄: " + cursor.getInt(cursor.getColumnIndex(People.KEY_AGE)) + ",";
msg += "身高: " + cursor.getFloat(cursor.getColumnIndex(People.KEY_HEIGHT)) + "\n";
} while (cursor.moveToNext());
}
displayTv.setText(msg);
}
});

queryAllBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Cursor cursor = resolver.query(People.CONTENT_URI,
new String[]{People.KEY_ID, People.KEY_NAME, People.KEY_AGE, People.KEY_HEIGHT},
null, null, null);
if (cursor == null) {
labelTv.setText("数据库中没有数据");
return;
}
labelTv.setText("数据库:" + String.valueOf(cursor.getCount()) + "条记录");
String msg = "";
if (cursor.moveToFirst()) {
do {
msg += "ID: " + cursor.getString(cursor.getColumnIndex(People.KEY_ID)) + ",";
msg += "姓名: " + cursor.getString(cursor.getColumnIndex(People.KEY_NAME)) + ",";
msg += "年龄: " + cursor.getInt(cursor.getColumnIndex(People.KEY_AGE)) + ",";
msg += "身高: " + cursor.getFloat(cursor.getColumnIndex(People.KEY_HEIGHT)) + "\n";
} while (cursor.moveToNext());
}
displayTv.setText(msg);
}
});

deleteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEt.getText().toString());
int count = resolver.delete(uri, null, null);
String msg = count + " 条数据被删除";
labelTv.setText(msg);
}
});

deleteAllBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resolver.delete(People.CONTENT_URI, null, null);
String msg = "数据全部删除";
labelTv.setText(msg);
}
});

updateBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put(People.KEY_NAME, nameEt.getText().toString());
values.put(People.KEY_AGE, Integer.parseInt(ageEt.getText().toString()));
values.put(People.KEY_HEIGHT, Float.parseFloat(heightEt.getText().toString()));
Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEt.getText().toString());
int result = resolver.update(uri, values, null, null);
String msg = "更新ID为" + idEt.getText().toString() + "的数据" + (result > 0 ? "成功" : "失败");
labelTv.setText(msg);
}
});
}
}

Demo 下载

  Demo 下载地址:http://download.csdn.net/download/leoyan_blog/9783601