android——实现跨程序访问数据

大鹏一日同风起,扶摇直上九万里。这篇文章主要讲述android——实现跨程序访问数据相关的知识,希望能为你提供帮助。
使用之前的SQLite存储的应用程序。首先需要在这个应用程序中创建内容提供器,右击com.example.administrator.exp7包→New→Other→Content Provider,会弹出这样的对话框,

android——实现跨程序访问数据

文章图片

 
其中Class name 是内容提供器的名字,Authorities是包名com.example.administrator.exp7,Exported表示是否允许外部程序访问内容提供器,Enabled表示是否启用这个内容提供器。
然后修改MyContentProvider中的代码:
1 public class MyContentProvider extends ContentProvider { 2//用于识别URI的自定义代码 3public static final int BOOK_DIR = 0; 4 5public static final int BOOK_ITEM = 1; 6 7public static final int CATEGORY_DIR = 2; 8 9public static final int CATEGORY_ITEM = 3; 10 11public static final String AUTHORITY = "com.example.administrator.exp7"; 12 13private MyDatabaseHelper dbHelper; 14 15//创建UriMatcher的实例 16private static UriMatcher uriMatcher; 17 18//将自定义代码和希望的URI匹配 19static { 20uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 21uriMatcher.addURI(AUTHORITY,"book",BOOK_DIR); 22uriMatcher.addURI(AUTHORITY,"book/#",BOOK_ITEM); 23uriMatcher.addURI(AUTHORITY,"category",CATEGORY_DIR); 24uriMatcher.addURI(AUTHORITY,"category/#",CATEGORY_ITEM); 25 26} 27@Override 28/* 29初始化时调用 30通常会在这里完成对数据库的创建和升级等操作,返回true表示初始化成功。 31只有当存在ContentResolver尝试访问程序中的数据时,才会进行初始化。 32*/ 33public boolean onCreate() { 34dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null , 2); 35return true; 36} 37 38/* 39查询数据 40uri 确定查询的是那一张表 41projection 查询那一列 42selection 和 selectionArgs查询那些行 43sortOrder 对结果进行排序 44返回的数据存放在Cursor对象中 45*/ 46@Override 47public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 48 49SQLiteDatabase db = dbHelper.getReadableDatabase(); 50Cursor cursor = null; 51 52//判断希望被访问的数据是什么数据 53switch (uriMatcher.match(uri)){ 54case BOOK_DIR: 55//查询table1表中的所有数据 56cursor = db.query("Book",projection, selection, selectionArgs,null ,null,sortOrder); 57break; 58case BOOK_ITEM: 59//查询table1表中的单条数据 60String bookId = uri.getPathSegments().get(1); 61cursor = db.query("Book",projection, "id = ?", new String[] { bookId },null ,null,sortOrder); 62break; 63case CATEGORY_DIR: 64cursor = db.query("Category",projection, selection, selectionArgs,null ,null,sortOrder); 65break; 66case CATEGORY_ITEM: 67//查询table2表中的单条数据 68String categoryId = uri.getPathSegments().get(1); 69cursor = db.query("Category",projection, "id = ?", new String[] { categoryId },null ,null,sortOrder); 70break; 71default: 72break; 73} 74return cursor; 75} 76 77/* 78根据传入的数据URI来返回相应的MIME类型 79*/ 80@Override 81public String getType(Uri uri) { 82 83switch (uriMatcher.match(uri)){ 84case BOOK_DIR: 85return "vnd.android.cursor.dir/vnd.com.example.administrator.exp7.provider.book"; 86case BOOK_ITEM: 87return "vnd.android.cursor.item/vnd.com.example.administrator.exp7.provider.book"; 88case CATEGORY_DIR: 89return "vnd.android.cursor.dir/vnd.com.example.administrator.exp7.provider.category"; 90case CATEGORY_ITEM: 91return "vnd.android.cursor.item/vnd.com.example.administrator.exp7.provider.category"; 92default: 93break; 94} 95return null; 96} 97/* 98添加数据 99uri 确定添加的是那一张表 100values 保存待添加的数据 101返回一条表示这条新记录的URI 102*/ 103@Override 104public Uri insert(Uri uri, ContentValues values) { 105 106SQLiteDatabase db = dbHelper.getWritableDatabase(); 107Uri uriReturn = null; 108 109//判断希望被增加的数据是那个表的 110switch (uriMatcher.match(uri)){ 111 112case BOOK_DIR: 113case BOOK_ITEM: 114long newBookId = db.insert("Book",null,values); 115uriReturn = Uri.parse("content://"+ AUTHORITY + "/book/" + newBookId); 116break; 117case CATEGORY_DIR: 118case CATEGORY_ITEM: 119long newCategoryId = db.insert("Category",null,values); 120uriReturn = Uri.parse("content://"+ AUTHORITY + "/category/" + newCategoryId); 121break; 122default: 123break; 124} 125return uriReturn; 126} 127/* 128删除数据 129selection 和 selectionArgs 删除那些行 130返回被删除的行数 131*/ 132@Override 133public int delete(Uri uri, String selection, String[] selectionArgs) { 134SQLiteDatabase db = dbHelper.getWritableDatabase(); 135int deletedRows = 0; 136 137switch (uriMatcher.match(uri)){ 138case BOOK_DIR: 139deletedRows = db.delete("Book", selection, selectionArgs); 140break; 141case BOOK_ITEM: 142String bookId = uri.getPathSegments().get(1); 143deletedRows = db.delete("Book","id = ?", new String[] { bookId }); 144break; 145case CATEGORY_DIR: 146deletedRows = db.delete("Category",selection, selectionArgs); 147break; 148case CATEGORY_ITEM: 149String categoryId = uri.getPathSegments().get(1); 150deletedRows = db.delete("Category","id = ?", new String[] { categoryId }); 151break; 152default: 153break; 154} 155return deletedRows; 156} 157/* 158更新已有的数据 159uri 确定更新的是那一张表 160values 新数据 161selection 和 selectionArgs 更新那些行 162会返回更新的行数 163*/ 164@Override 165public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 166 167SQLiteDatabase db = dbHelper.getWritableDatabase(); 168int updatedRows = 0; 169 170switch (uriMatcher.match(uri)){ 171 172case BOOK_DIR: 173updatedRows = db.update("Book", values, selection, selectionArgs); 174break; 175case BOOK_ITEM: 176String bookId = uri.getPathSegments().get(1); 177updatedRows = db.update("Book", values, "id = ?", new String[] { bookId }); 178break; 179case CATEGORY_DIR: 180updatedRows = db.update("Category", values, selection, selectionArgs); 181break; 182case CATEGORY_ITEM: 183String categoryId = uri.getPathSegments().get(1); 184updatedRows = db.update("Category", values, "id = ?", new String[] { categoryId }); 185break; 186default: 187break; 188} 189return updatedRows; 190} 191 }

先看onCreate()方法完成了数据库的创建或升级,创建了一个MyDatabaseHelper 的实例dbHelper,并返回true。
然后是用于查询的query函数,先通过dbHelper.getReadableDatabase()方法获得可以操作数据库的SQLiteDatabase 对象的实例db,根据传入的Uri判断希望被访问的数据是哪一张表,在调用SQLiteDatabase 的query()方法进行查询,这里还使用了uri.getPathSegments().get(1),这个方法会将内容URI权限后的部分以"/"进行分割,第一个"/"之前的可用get(0)获得,这次想要获得的id要使用get(1)获得。
insert()方法先使用Uri判断想要添加的数据是哪一张表,然后调用SQLiteDatabase 的insert()方法在相应的表中添加数据,这个方法会返回添加的数据的Id,然后使用Uri.parse()方法讲一个内容URI解析成一个Uri对象,这个对象是以id结尾的。
delete()也是先先通过dbHelper.getReadableDatabase()方法获得可以操作数据库的SQLiteDatabase 对象的实例db,然后根据传入的Uri判断希望被访问的数据是哪一张表,在调用SQLiteDatabase 的delete()进行删除,被删除的行数作为返回值返回。
updata()也是类似,区别就是调用SQLiteDatabase 的updata()方法进行更新,受影响的行数会作为返回值返回。
以上是数据被访问的应用com.example.administrator.exp7的内容适配器的代码。
 
然后是读取数据的应用程序,先是布局文件的编写,有四个按钮执行添加、查询、更新、删除的功能。
1 < ?xml version="1.0" encoding="utf-8"?> 2 < LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3android:layout_width="match_parent" 4android:layout_height="match_parent" 5android:orientation="vertical"> 6 7 8< Button 9android:id="@+id/add_data" 10android:layout_width="match_parent" 11android:layout_height="wrap_content" 12android:text="新增数据" /> 13 14< Button 15android:id="@+id/query_data" 16android:layout_width="match_parent" 17android:layout_height="wrap_content" 18android:text="查询数据" /> 19 20< Button 21android:id="@+id/updata_data" 22android:layout_width="match_parent" 23android:layout_height="wrap_content" 24android:text="更新数据" /> 25 26< Button 27android:id="@+id/delete_data" 28android:layout_width="match_parent" 29android:layout_height="wrap_content" 30android:text="删除数据" /> 31 < /LinearLayout>

然后修改MainActivity中的代码:
1 public class MainActivity extends AppCompatActivity { 2 3privateString newId; 4 5@Override 6protected void onCreate(Bundle savedInstanceState) { 7super.onCreate(savedInstanceState); 8setContentView(R.layout.activity_main); 9 10//注册按钮 11Button addData = https://www.songbingjia.com/android/(Button) findViewById(R.id.add_data); 12Button queryData = (Button) findViewById(R.id.query_data); 13Button updataData = (Button) findViewById(R.id.updata_data); 14Button deleteData = (Button) findViewById(R.id.delete_data); 15 16 17//添加数据 18addData.setOnClickListener(new View.OnClickListener() { 19@Override 20public void onClick(View v) { 21Uri uri = Uri.parse("content://com.example.administrator.exp7/book"); 22ContentValues values = new ContentValues(); 23values.put("name", "a book name"); 24values.put("author", "a book author"); 25values.put("pages", 1000); 26values.put("price",22); 27Uri newUri = getContentResolver().insert(uri,values); 28newId = newUri.getPathSegments().get(1); 29} 30}); 31 32//查询数据 33queryData.setOnClickListener(new View.OnClickListener() { 34@Override 35public void onClick(View v) { 36Uri uri = Uri.parse("content://com.example.administrator.exp7/book"); 37Cursor cursor = getContentResolver().query(uri, null, null, null, null); 38 39//输出数据 40if(cursor != null){ 41while (cursor.moveToNext()){ 42String name = cursor.getString(cursor.getColumnIndex("name")); 43String author = cursor.getString(cursor.getColumnIndex("author")); 44int pages = cursor.getInt(cursor.getColumnIndex("pages")); 45double price = cursor.getDouble(cursor.getColumnIndex("price")); 46Log.d("MainActivity","name is "+ name); 47Log.d("MainActivity","author is "+ author); 48Log.d("MainActivity","pages is "+ pages); 49Log.d("MainActivity","price is "+ price); 50Log.d("MainActivity"," newId is "+newId); 51} 52cursor.close(); 53} 54} 55}); 56 57//更新数据 58updataData.setOnClickListener(new View.OnClickListener() { 59@Override 60public void onClick(View v) { 61Uri uri = Uri.parse("content://com.example.administrator.exp7/book/" + newId); 62ContentValues values = new ContentValues(); 63values.put("name", "other name"); 64values.put("pages", 2200); 65values.put("price",21); 66getContentResolver().update(uri,values,null,null); 67} 68}); 69 70//删除数据 71deleteData.setOnClickListener(new View.OnClickListener() { 72@Override 73public void onClick(View v) { 74Uri uri = Uri.parse("content://com.example.administrator.exp7/book/" + newId); 75getContentResolver().delete(uri, null,null); 76} 77}); 78 79} 80 }

添加数据的时候,先调用Uri.parse()方法将URI语句解析成Uri对象,将数据存储在ContentValuesd的对象中,然后调用getContentResolver().insert()方法执行添加数据的操作,会返回一个Uri对象,然后使用newUri.getPathSegments().get(1)得到刚刚添加数据的id。
查询数据时一样,先解析URI语句,然后使用getContentResolver().query()方法进行查询操作,将数据存储在cursor对象中,然后在遍历cursor将查询到的数据输出出来。
更新数据的时候,先解析URI语句,这里的URI语句中含有刚刚添加的数据的id就是更新刚刚添加的数据,同样将要更新数据存储在ContentValuesd的对象中。再调用getContentResolver().update()进行更新数据的操作。
删除数据调用getContentResolver().delete()进行删除操作。
【android——实现跨程序访问数据】

    推荐阅读