使用之前的SQLite存储的应用程序。首先需要在这个应用程序中创建内容提供器,右击com.example.administrator.exp7包→New→Other→Content Provider,会弹出这样的对话框,

  其中Class name 是内容提供器的名字,Authorities是包名com.example.administrator.exp7,Exported表示是否允许外部程序访问内容提供器,Enabled表示是否启用这个内容提供器。

  然后修改MyContentProvider中的代码:

 public class MyContentProvider extends ContentProvider {
//用于识别URI的自定义代码
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.administrator.exp7"; private MyDatabaseHelper dbHelper; //创建UriMatcher的实例
private static UriMatcher uriMatcher; //将自定义代码和希望的URI匹配
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
/*
初始化时调用
通常会在这里完成对数据库的创建和升级等操作,返回true表示初始化成功。
只有当存在ContentResolver尝试访问程序中的数据时,才会进行初始化。
*/
public boolean onCreate() {
dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null , 2);
return true;
} /*
查询数据
uri 确定查询的是那一张表
projection 查询那一列
selection 和 selectionArgs查询那些行
sortOrder 对结果进行排序
返回的数据存放在Cursor对象中
*/
@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:
//查询table1表中的所有数据
cursor = db.query("Book",projection, selection, selectionArgs,null ,null,sortOrder);
break;
case BOOK_ITEM:
//查询table1表中的单条数据
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:
//查询table2表中的单条数据
String categoryId = uri.getPathSegments().get(1);
cursor = db.query("Category",projection, "id = ?", new String[] { categoryId },null ,null,sortOrder);
break;
default:
break;
}
return cursor;
} /*
根据传入的数据URI来返回相应的MIME类型
*/
@Override
public String getType(Uri uri) { switch (uriMatcher.match(uri)){
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd.com.example.administrator.exp7.provider.book";
case BOOK_ITEM:
return "vnd.android.cursor.item/vnd.com.example.administrator.exp7.provider.book";
case CATEGORY_DIR:
return "vnd.android.cursor.dir/vnd.com.example.administrator.exp7.provider.category";
case CATEGORY_ITEM:
return "vnd.android.cursor.item/vnd.com.example.administrator.exp7.provider.category";
default:
break;
}
return null;
}
/*
添加数据
uri 确定添加的是那一张表
values 保存待添加的数据
返回一条表示这条新记录的URI
*/
@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 CATEGORY_DIR:
case CATEGORY_ITEM:
long newCategoryId = db.insert("Category",null,values);
uriReturn = Uri.parse("content://"+ AUTHORITY + "/category/" + newCategoryId);
break;
default:
break;
}
return uriReturn;
}
/*
删除数据
selection 和 selectionArgs 删除那些行
返回被删除的行数
*/
@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 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;
}
/*
更新已有的数据
uri 确定更新的是那一张表
values 新数据
selection 和 selectionArgs 更新那些行
会返回更新的行数
*/
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase();
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;
}
}

  先看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的内容适配器的代码。

  然后是读取数据的应用程序,先是布局文件的编写,有四个按钮执行添加、查询、更新、删除的功能。

 <?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:id="@+id/add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="新增数据" /> <Button
android:id="@+id/query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询数据" /> <Button
android:id="@+id/updata_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="更新数据" /> <Button
android:id="@+id/delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除数据" />
</LinearLayout>

  然后修改MainActivity中的代码:

 public class MainActivity extends AppCompatActivity {

     private  String newId;

     @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //注册按钮
Button addData = (Button) findViewById(R.id.add_data);
Button queryData = (Button) findViewById(R.id.query_data);
Button updataData = (Button) findViewById(R.id.updata_data);
Button deleteData = (Button) findViewById(R.id.delete_data); //添加数据
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.administrator.exp7/book");
ContentValues values = new ContentValues();
values.put("name", "a book name");
values.put("author", "a book author");
values.put("pages", 1000);
values.put("price",22);
Uri newUri = getContentResolver().insert(uri,values);
newId = newUri.getPathSegments().get(1);
}
}); //查询数据
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.administrator.exp7/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("MainActivity","name is "+ name);
Log.d("MainActivity","author is "+ author);
Log.d("MainActivity","pages is "+ pages);
Log.d("MainActivity","price is "+ price);
Log.d("MainActivity"," newId is "+ newId);
}
cursor.close();
}
}
}); //更新数据
updataData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.administrator.exp7/book/" + newId);
ContentValues values = new ContentValues();
values.put("name", "other name");
values.put("pages", 2200);
values.put("price",21);
getContentResolver().update(uri,values,null,null);
}
}); //删除数据
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.administrator.exp7/book/" + newId);
getContentResolver().delete(uri, null,null);
}
}); }
}

  添加数据的时候,先调用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——实现跨程序访问数据的更多相关文章

  1. Android学习--跨程序共享数据之内容提供其探究

    什么是内容提供器? 跨程序共享数据之内容提供器,这是个什么功能?看到这个名称的时候最能给我们提供信息的应该是“跨程序”这个词了,是的重点就是这个词,这个内容提供器的作用主要是用于在不同的引用程序之间实 ...

  2. android: 实现跨程序数据共享

    简单起见,我们还是在上一章中 DatabaseTest 项目的基础上继续开发,通过内容提供器 来给它加入外部访问接口. 打开 DatabaseTest 项目,首先将 MyDatabaseHelper ...

  3. C:static 关键字、静态变量、跨类访问数据

    static 在OC中的使用 参考1   参考2   参考3   参保4    参考5 跨类访问成员 参考 +号方法就是类方法(静态方法),说明不用创建对象,可以直接通过类型去直接调用这个方法,在OC ...

  4. 设置IE浏览器跨域访问数据

    在开发中,经常会遇到多站点跨域访问后台服务获取数据的情况,解决方法有两种 自己写代理服务,访问代理服务,代理服务请求服务获取数据再返回: 设置浏览器可以跨域访问数据. 本文来讲如何设置IE浏览器跨域访 ...

  5. Vue用axios跨域访问数据

    Vue用axios跨域访问数据axios是vue-resource的替代品,vue-resource不再维护.安装axios:npm install axios使用vue-cli开发时,由于项目本身启 ...

  6. Context - React跨组件访问数据的利器

    Context提供了一种跨组件访问数据的方法.它无需在组件树间逐层传递属性,也可以方便的访问其他组件的数据 在经典的React应用中,数据是父组件通过props向子组件传递的.但是在某些特定场合,有些 ...

  7. 内容提供者(Content Provider)——跨程序共享数据

    内容提供者 Content Provider 应用的数据库是不允许其他应用访问的 内容提供者的作用就是让别的应用访问到你的数据库 自定义内容提供者,继承ContentProvider类,重写增删改查方 ...

  8. 通过FEDERATED存储引擎跨实例访问数据

    通过FEDERATED存储引擎同步两实例间的表数据需求情景:实例1中A库中的三个视图是实例2中的B库所依赖的,B需要A库中三个视图的实时数据.方案:通过FEDERATED来完成跨势力的查询FEDERA ...

  9. 在Vue中如何使用axios跨域访问数据

    最近在项目中需要用到axios,所以就恶补一下这个axios到底是什么东东.越来它是vue-resource的替代品,官网也说了,以后都用axios, vue-resource不在维护.那么这个axi ...

随机推荐

  1. python的简介与简单使用

    简介: python的诞生 创始人:Guido van Rossum(荷兰人:吉多) 时间:1989年 特点: 1.简单明了,容易上手 2.多平台,`全面发展,平衡发展, 3.胶水语言,有大量的库 其 ...

  2. 洛谷p1216 IOI1994 Day1T1

    洛谷p1216 IOI1994 Day1T1 洛谷原题 题目描述 观察下面的数字金字塔. 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大.每一步可以走到左下方的点也可以到达右下 ...

  3. NetCore 获取appsetting.json 文件中的配置

    1. using Microsoft.Extensions.Configuration public class HomeController : Controller { public IConfi ...

  4. .NET项目迁移到.NET Core操作指南

    为什么要从.NET迁移到.NET Core? .NET Core提供的特性 .NET Core性能提升 .NET如何迁移到.NET Core? 迁移工作量评估(API兼容性分析) 迁移方案制定 通过类 ...

  5. WinForm控件之【CheckedListBox】

    基本介绍 复选框列表控件,以复选框的形式将一个或多个项列表展示,从目前的情况来看应用非常有限并不广泛. 常设置属性.事件 CheckOnClick:值为true时单击项即可更改项的勾选状态,值为fal ...

  6. 【分治】黑白棋子的移动-C++

    题目描述 有2n个棋子(n≥4)排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为n=5的情况: ○○○○○●●●●● 移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也 ...

  7. ISTQB TA - 边界值分析中三值测试法的注意事项

    三值测试法的定义(中文版20150601大纲): 取一个不超过边界.一个在边界上.一个超过边界的值. 这三个值其实还有另外一种叫法,分别是内点.上点和离点. 内点:不超过边界的点 上点:在边界上的点 ...

  8. 在 Microsoft.VisualStudio.Setup.Engine.Install(Product product, String destination, CancellationToken token)无法在相同位置或现有实例“20cc4971”的子目录上安装指定实例“ebc82a8e”的解决方案

    在所在的安装目录根目录下搜索实例 如 20cc4971 将文件夹全部删除. 一般默认安装在C盘,所以在C盘搜索实例文件夹,将其全部删除.

  9. Java将文本文件压缩为tar.gz

    压缩 思路 准备输出流 FileOutputStream BufferedOutputStream TarOutputStream GZIPOutputStream 准备输入流 FileInputSt ...

  10. 比赛:小奔与不等四边形solution

    题目: 题目背景 有这样一道经典的数学题:已知一个四边形的边长是四个连续的正整数,求证这个四边形的面积的最大值不为整数.小奔轻松地证明了这个问题,现在问题来了,大奔要求小奔以最快的速度算出给定边长的四 ...