Android 跨应用共享数据Demo

说明一下

本项目有个问题需要说明一下,就是provideronCreate()方法会先于ActivityonCreate()方法执行,所以DatabaseTest项目一运行,就会先执行provideronCreate()方法,创建数据库

前提

本项目在前面DatabaseTest项目的基础上进行更改,首先将MyDatabaseHelper中使用Toast弹出数据库创建成功的提示去掉,因为跨程序访问时我们不能直接使用Toast。然后创建一个内容提供器,在包上单机右键 New->Other->Content Provider

这样就能自动导入相关的<provider>进行注册

1
2
3
4
5
<provider
android:authorities="com.example.databasetest.provider"
android:name=".DatabaseProvider"
android:enabled="true"
android:exported="true"/>
DatabaseProvider 代码
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
public class DatabaseProvider extends ContentProvider {
public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;
public static final int CATAGORY_DIR = 2;
public static final int CATAGORY_ITEM = 3;
public static final String AUTHORITY = "com.example.databasetest.provider";
public static UriMatcher uriMatcher;
private MyDatabaseHelper dbhelper;

static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
uriMatcher.addURI(AUTHORITY, "catagory", CATAGORY_DIR);
uriMatcher.addURI(AUTHORITY, "catagory/#", CATAGORY_ITEM);
}

public DatabaseProvider() {
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbhelper.getWritableDatabase();
int deletedRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
deletedRows = db.delete("Book", selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
deletedRows = db.delete("Book", "id = ?", new String[]{bookId});
break;
case CATAGORY_DIR:
deletedRows = db.delete("Category", selection, selectionArgs);
break;
case CATAGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
deletedRows = db.delete("Category", "id = ?", new String[]{categoryId});
break;
default:
break;
}
return deletedRows;
}

@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)){
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.book";
case BOOK_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.book";
case CATAGORY_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.category";
case CATAGORY_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.categoty";
}
return null;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbhelper.getWritableDatabase();
Uri uriReturn = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
case BOOK_ITEM:
long newBookId = db.insert("Book", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
break;
case CATAGORY_DIR:
case CATAGORY_ITEM:
long newCategoryId = db.insert("Category", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newCategoryId);
break;
default:
break;
}
return uriReturn;
}

//应用一运行 provider注册 会先执行该方法 来创建数据库
@Override
public boolean onCreate() {
dbhelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbhelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
cursor = db.query("Book", projection, "id = ?", new String[]{bookId}, null, null, sortOrder);
break;
case CATAGORY_DIR:
cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder);
break;
case CATAGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
cursor = db.query("Category", projection, "id = ?", new String[]{categoryId}, null, null, sortOrder);
break;
default:
break;
}
return cursor;
}

@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbhelper.getWritableDatabase();
int updateRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
updateRows = db.update("Book", values, selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
updateRows = db.update("Book", values, "id = ?", new String[]{bookId});
break;
case CATAGORY_DIR:
updateRows = db.update("Category", values, selection, selectionArgs);
break;
case CATAGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
updateRows = db.update("Categoty", values, "id = ?", new String[]{categoryId});
break;
default:
break;
}
return updateRows;
}
}
几个注意点
  • onCreate()中借用MyDataBaseHelper完成数据库的创建或升级,并且provideronCreate()方法会先于ActivityonCreate()方法执行
  • query()返回cursor
  • insert()返回能够表示这条新增数据的URI
  • update()delete()返回受影响的行数
  • getPathSegments()会将内容URI权限之后的部分用/分割,并把结果放到字符串列表当中,其第0个位置放的是路径,第1个位置就是id了。
跨应用访问数据

接着在模拟器卸载重装当前应用,再创建一个新项目:ProviderTest

1.布局
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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="向 Book 表添加数据"
android:id="@+id/insert"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询 Book 表中的数据"
android:id="@+id/query"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/update"
android:text="修改 Book 表中的数据"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/delete"
android:text="删除 Book 表中的数据"/>

</LinearLayout>
2.主活动
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
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private String newId;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button button_insert = findViewById(R.id.insert);
button_insert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
ContentValues values = new ContentValues();
values.put("name","老人与海");
values.put("author", "海明威");
values.put("pages",345);
values.put("price",10.88);
Uri newUri = getContentResolver().insert(uri, values);
newId = newUri.getPathSegments().get(1);
}
});

Button button_delete = findViewById(R.id.delete);
button_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.databasetest.provider/book/"+newId);
getContentResolver().delete(uri, null, null);
}
});

Button button_update = findViewById(R.id.update);
button_update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.databasetest.provider/book/"+newId);
ContentValues values = new ContentValues();
values.put("name", "绿野仙踪");
values.put("pages", 666);
values.put("price", 88.88);
getContentResolver().update(uri, values, null, null);
}
});

Button button_query = findViewById(R.id.query);
button_query.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
Cursor cursor = getContentResolver().query(uri, null, null, null,null);
if(cursor != null){
while (cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));

Log.d(TAG, "书名:"+name);
Log.d(TAG, "作者:"+author);
Log.d(TAG, "页数:"+pages);
Log.d(TAG, "价格:"+price);
}
}
}
});
}
}

运行:

0%