Android 实现跨程序数据共享栗子
2017-09-13 17:23
267 查看
直接上代码
代码中是定义了4个常量,分别用于表示访问Book表中的所有数据,访问Book表中的单条数据,访问Category表中的所有数据,访问Category表中的单条数据.然后在静态代码块中对UriMatcher进行了初始化操作,将期望匹配的几种URI格式添加进去.
在onCreate()方法中,创建了一个MyDatabaseHelper的实例.然后返回true,表示内容提供器初始化成功,这时数据库就已经完成了创建或升级操作.
query()方法中.先获取到了SQLiteDatabase的实例,然后根据传入的Uri参数判断出用户想要访问哪张表,再调用SQLiteDatebase的query()方法进行查询,并将Cursor对象返回就好了.注意当访问单条数据的时候有一个细节,这里调用了Uri对象的getPathSegments()方法,他会将内容URI权限之后的部分以”/”符号进行分割,并把分割后的结果放入到一个字符串列表中,那这个列表的第0个位置存放的就是路径,第一个位置存放的就是id了,得到id之后,再通过selection和selectionArgs参数进行约束,就实现了查询单条数据的功能.
insert()方法中,也是先获取SQLiteDatabase的实例,然后根据出入的Uri参数判断出用户想要往哪张表中添加数据,再调用SQLiteDatabase的insert()方法进行添加就可以了.注意:insert()方法要求返回一个能够表示这条新增数据的URI,所以我们还需要调用Uri.parse()方法来将一个内容URI解析为Uri对象,当然这个内容URI是以新增数据的id结尾的.
update()方法,先获取SQLiteDatabase的实例,根据传入的Uri参数判断出用户想要更新哪张表中的数据,再调用SQLiteDatabase的update()方法进行更新,受影响的行数将作为返回值返回.
delete()方法,先获取SQLiteDatabase的实例,然后根据传入的Uri参数判断出用户想要删除哪张表中的数据,在调用SQLiteDatabase的delete()方法进行删除就好了,被删除的行数作为返回值返回.
getType()方法和上一篇文章的一样
内容提供器一定要在AndroidManifest,xml中注册才可以使用
修改activity_main.xml代码
修改MainActivity代码:
在四个按钮的点击响应事件中处理了增删改查的逻辑.
添加数据的时候,首先调用Uri.parse()方法将一个内容URI解析为Uri对象, 然后把要添加的数据都存放在ContentValues对象中,接着调用ContentResolver的insert()方法执行添加操作就可以了,注意:insert()方法会返回一个Uri对象,这个对象中包含了新增数据的id,我们通过getPathSegments()方法将这个id取出,后面会用到它.
查询数据的时候,同样是调用了Uri.parse()方法将一个内容URI解析为Uri对象,然后调用ContentResolver的query()方法去查询数据,查询的结果当然还是存放在Cursor对象中的,之后对Cursor进行遍历,从中取出查询结果,并一一打印出来.
更新数据的时候,也是将内容URI解析为Uri对象,然后把想要更新的数据存放到ContentValues对象中,在调用ContentResolver的update()方法执行更新操作就可以了,注意这里我们不想让Book表中的其他行受影响,在调用Uri.parse()方法时,给内容URI的尾部增加了一个id,而这个id正是添加数据时所返回的,这就表示我们只希望更新刚刚添加的那条数据,Book表中的其他行都不受影响.
删除数据的时候,也是使用同样的方法解析一个以id结尾的内容URI,然后调用ContentResolver的delete()方法执行删除操作就可以了,由于我们在内容URI里指定了一个id,因此只会删除掉拥有相应id的那行数据,Book表中的其他数据都不会受影响.
public class DatabaseProvider extends ContentProvider { public static final int BOOK_DIR = 0; public static final int BOOK_ITEM = 1; public static final int CATEGORY_DIR = 2; public static final int CATEGORY_ITEM = 3; public static final String AUTHORITY = "com.example.databasetest.provider"; private 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, "category", CATEGORY_DIR); uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM); } @Override public boolean onCreate() { dbHelper = new MyDatabaseHelper(getContext(), "BookStort.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 CATEGORY_DIR: cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder); break; case CATEGORY_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 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 CATEGORY_DIR: return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.category"; case CATEGORY_ITEM: return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.category"; } return null; } @Override public Uri insert(Uri uri, ContentValues values) { //添加数据 SQLiteDatabase db = dbHelper.getReadableDatabase(); 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 CATEGORY_DIR: case CATEGORY_ITEM: long newCategoryId = db.insert("Category", null, values); uriReturn = Uri.parse("content://" + AUTHORITY + "/category/" + newCategoryId); break; default: break; } return uriReturn; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { //删除数据 SQLiteDatabase db = dbHelper.getReadableDatabase(); 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 CATEGORY_DIR: deletedRows = db.delete("Category", selection, selectionArgs); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); deletedRows = db.delete("Category", "id = ?", new String[]{categoryId}); break; default: break; } return deletedRows; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { //更新数据 SQLiteDatabase db = dbHelper.getReadableDatabase(); int updatedRows = 0; switch (uriMatcher.match(uri)){ case BOOK_DIR: updatedRows = db.update("Book", values, selection, selectionArgs); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); updatedRows = db.update("Book", values, "id = ?", new String[]{bookId}); break; case CATEGORY_DIR: updatedRows = db.update("Category", values, selection, selectionArgs); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); updatedRows = db.update("Category", values, "id = ?", new String[]{categoryId}); break; default: break; } return updatedRows; } }
代码中是定义了4个常量,分别用于表示访问Book表中的所有数据,访问Book表中的单条数据,访问Category表中的所有数据,访问Category表中的单条数据.然后在静态代码块中对UriMatcher进行了初始化操作,将期望匹配的几种URI格式添加进去.
在onCreate()方法中,创建了一个MyDatabaseHelper的实例.然后返回true,表示内容提供器初始化成功,这时数据库就已经完成了创建或升级操作.
query()方法中.先获取到了SQLiteDatabase的实例,然后根据传入的Uri参数判断出用户想要访问哪张表,再调用SQLiteDatebase的query()方法进行查询,并将Cursor对象返回就好了.注意当访问单条数据的时候有一个细节,这里调用了Uri对象的getPathSegments()方法,他会将内容URI权限之后的部分以”/”符号进行分割,并把分割后的结果放入到一个字符串列表中,那这个列表的第0个位置存放的就是路径,第一个位置存放的就是id了,得到id之后,再通过selection和selectionArgs参数进行约束,就实现了查询单条数据的功能.
insert()方法中,也是先获取SQLiteDatabase的实例,然后根据出入的Uri参数判断出用户想要往哪张表中添加数据,再调用SQLiteDatabase的insert()方法进行添加就可以了.注意:insert()方法要求返回一个能够表示这条新增数据的URI,所以我们还需要调用Uri.parse()方法来将一个内容URI解析为Uri对象,当然这个内容URI是以新增数据的id结尾的.
update()方法,先获取SQLiteDatabase的实例,根据传入的Uri参数判断出用户想要更新哪张表中的数据,再调用SQLiteDatabase的update()方法进行更新,受影响的行数将作为返回值返回.
delete()方法,先获取SQLiteDatabase的实例,然后根据传入的Uri参数判断出用户想要删除哪张表中的数据,在调用SQLiteDatabase的delete()方法进行删除就好了,被删除的行数作为返回值返回.
getType()方法和上一篇文章的一样
内容提供器一定要在AndroidManifest,xml中注册才可以使用
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.databasetest"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> ... <provider android:name=".DatabaseProvider" android:authorities="com.example.databasetest.provider" android:enabled="true" android:exported="true"> </provider> </application> </manifest> //可以看到<application>标签内出现了一个新的标签<provider>,我们使用它来对DatabaseProvider这个内容提供器进行注册,android:name属性指定了DatabaseProvider的类名,android:authorities属性指定了DatabaseProvider的authority,而enabled和exported属性表示允许DatabaseProvider被其他应用程序进行访问
修改activity_main.xml代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/add_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Add To Book" /> <Button android:id="@+id/query_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Query From Book" /> <Button android:id="@+id/update_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Update Book" /> <Button android:id="@+id/delete_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Delete From Book" /> </LinearLayout>
修改MainActivity代码:
public class MainActivity extends BaseActivity { private String newId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.data_provider); Button addData = (Button)findViewById(R.id.add_data); addData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //添加数据 Uri uri = Uri.parse("content://com.example.databasetest.provider/book"); ContentValues values = new ContentValues(); values.put("name", "A Clash of Kings"); values.put("author", "George Martin"); values.put("pages", 1040); values.put("price", 22.85); Uri newUri = getContentResolver().insert(uri, values); newId = newUri.getPathSegments().get(1); } }); Button queryData = (Button)findViewById(R.id.query_data); queryData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //查询数据 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")); do 9d0f uble price = cursor.getDouble(cursor.getColumnIndex("price")); Log.d("MainActivity", "book name is " + name); Log.d("MainActivity", "book author is " + author); Log.d("MainActivity", "book pages is " + pages); Log.d("MainActivity", "book price is " + price); } cursor.close(); } } }); Button updateData = (Button)findViewById(R.id.update_data); updateData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //更新数据 Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId); ContentValues values = new ContentValues(); values.put("name", "A Storm of Swords"); values.put("pages", 1216); values.put("price", 24.05); getContentResolver().update(uri, values, null, null); } }); Button deleteData = (Button)findViewById(R.id.delete_data); deleteData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //删除数据 Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId); getContentResolver().delete(uri, null, null); } }); } }
在四个按钮的点击响应事件中处理了增删改查的逻辑.
添加数据的时候,首先调用Uri.parse()方法将一个内容URI解析为Uri对象, 然后把要添加的数据都存放在ContentValues对象中,接着调用ContentResolver的insert()方法执行添加操作就可以了,注意:insert()方法会返回一个Uri对象,这个对象中包含了新增数据的id,我们通过getPathSegments()方法将这个id取出,后面会用到它.
查询数据的时候,同样是调用了Uri.parse()方法将一个内容URI解析为Uri对象,然后调用ContentResolver的query()方法去查询数据,查询的结果当然还是存放在Cursor对象中的,之后对Cursor进行遍历,从中取出查询结果,并一一打印出来.
更新数据的时候,也是将内容URI解析为Uri对象,然后把想要更新的数据存放到ContentValues对象中,在调用ContentResolver的update()方法执行更新操作就可以了,注意这里我们不想让Book表中的其他行受影响,在调用Uri.parse()方法时,给内容URI的尾部增加了一个id,而这个id正是添加数据时所返回的,这就表示我们只希望更新刚刚添加的那条数据,Book表中的其他行都不受影响.
删除数据的时候,也是使用同样的方法解析一个以id结尾的内容URI,然后调用ContentResolver的delete()方法执行删除操作就可以了,由于我们在内容URI里指定了一个id,因此只会删除掉拥有相应id的那行数据,Book表中的其他数据都不会受影响.
相关文章推荐
- android: 实现跨程序数据共享
- android ContentProvider结合SQLiteHelper实现数据的共享<一>
- Android学习19--使用ContentProvider实现数据共享
- 继承Application实现Android数据共享
- Android--- 利用Application实现全局数据共享
- Android之使用Contentprovider对外共享数据和实现数据监听变化
- Android 面试题笔记-------ContentProvider实现数据共享的方式
- Android开发(11)-利用listview控件显示person表中的所有数据(并实现点击触发拨号程序)
- Android中利用Application实现多个Activity间共享数据
- Android Preference的使用总结(很全很详细)以及SharedPreferences多个程序之间共享数据
- Android SQLite PhoneGap sencha touch 中调用Java原生程序,数据加载到页面,并实现滑动分页
- Android 用sharepreference在各个程序之间共享数据
- 技术三等奖:Linux下实现Android手机数据传输及网络共享【评委点评】
- Linux下实现Android手机数据传输及网络共享
- Android中数据共享机制的实现——ContentProvider的应用从入门到精通
- Android通过sharedUserId机制实现APK间共享数据,App的换肤可以通过此机制实现
- Android疑惑之使用ContentProvider实现数据共享
- Android开发(11)-利用listview控件显示person表中的所有数据(并实现点击触发拨号程序)
- Android疑惑之使用ContentProvider实现数据共享
- Android初级教程——实现共享优先数据方法 Shared Preferences