原文链接:http://www.orlion.ga/661/

打开SQLite博文中创建的 DatabaseDemo项目,首先将 MyDatabaseHelper中使用 Toast弹出创建数据库成功的提示去除掉,因为跨程序访问时我们不能直接使用 Toast。然后添加一个 DatabaseProvider类,代码如下所示:

package ga.orlion.databasedemo;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; 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 = "ga.orlion.databasedemo.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() , "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 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 null;
} @Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd.ga.orlion.databasedemo.provider.book";
case BOOK_ITEM:
return "vnd.android.cursor.item/vnd.ga.orlion.databasedemo.provider.book";
case CATEGORY_DIR:
return "vnd.android.cursor.dir/vnd.ga.orlion.databasedemo.provider.category";
case CATEGORY_ITEM:
return "vnd.android.cursor.item/vnd.ga.orlion.databasedemo.provider.category";
}
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 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.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;
} @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;
} }

首先在类的一开始,同样是定义了四个常量,分别用于表示访问Book表中的所有数据、访问 Book表中的单条数据、访问 Category表中的所有数据和访问Category表中的单条数据。然后在静态代码块里对 UriMatcher进行了初始化操作,将期望匹

配的几种 URI格式添加了进去。接下来就是每个抽象方法的具体实现了,先来看下 onCreate()方法,这个方法的代码很短,就是创建了一个 MyDatabaseHelper的实例,然后返回 true表示内容提供器初始化成功,这时数据库就已经完成了创建或升级操作。

接着看一下 query()方法,在这个方法中先获取到了 SQLiteDatabase的实例,然后根据传入的 Uri参数判断出用户想要访问哪张表,再调用 SQLiteDatabase的 query()进行查询,并将 Cursor对象返回就好了。注意当访问单条数据的时候有一个细节,这里调用了 Uri对象的getPathSegments()方法,它会将内容 URI权限之后的部分以“/”符号进行分割,并把分割后的结果放入到一个字符串列表中,那这个列表的第 0个位置存放的就是路径,第 1个位置存放的就是 id了。得到了 id之后,再通过 selection和 selectionArgs参数进行约束,就实现了查询单条数据的功能。

再往后就是 insert()方法,同样它也是先获取到了 SQLiteDatabase的实例,然后根据传入的 Uri参数判断出用户想要往哪张表里添加数据,再调用 SQLiteDatabase的 insert()方法进行添加就可以了。注意 insert()方法要求返回一个能够表示这条新增数据的 URI,所以我们还需要调用 Uri.parse()方法来将一个内容 URI解析成 Uri对象,当然这个内容 URI是以新增数据的 id结尾的。

接下来就是 update()方法了,相信这个方法中的代码已经完全难不倒你了。也是先获取SQLiteDatabase的实例,然后根据传入的 Uri参数判断出用户想要更新哪张表里的数据,再调用 SQLiteDatabase的 update()方法进行更新就好了,受影响的行数将作为返回值返回。。这里仍然是先获取到 SQLiteDatabase的实例,然后根据传入的 Uri参数判断出用户想要删除哪张表里的数据,再调用 SQLiteDatabase的 delete()方法进行删除就好了,被删除的行数将作为返回值返回。

        <provider
            android:name="ga.orlion.databasedemo.DatabaseProvider"
            android:authorities="ga.orlion.databasedemo.provider"
            android:exported="true" >
            
        </provider>

// 《第一行代码》这里没有加android:exported="true",导致出现了权限问题。

可以看到, 这里我们使用了<provider>标签来对 DatabaseProvider这个内容提供器进行注册,在 android:name属性中指定了该类的全名,又在 android:authorities属性中指定了该内容提供器的权限。

下一步需要将 DatabaseDemo程序从模拟器中删除掉,以防止上一章中产生的遗留数据对我们造成干扰。然后运行一下项目,将 DatabaseDemo程序重新安装在模拟器上了。接着关闭掉DatabaseDemo这个项目,并创建一个新项目 ProviderDemo,我们就将通过这个程序去访问DatabaseDemo中的数据。首先添加两个按钮一个用来添加数据一个用来查看数据,然后在MainActivity.java中绑定点击事件:

package ga.orlion.providerdemo;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity { 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);
addData.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
Uri uri = Uri.parse("content://ga.orlion.databasedemo.provider/book");
ContentValues values = new ContentValues();
values.put("name", "content provider book");
values.put("author", "orlion");
values.put("pages", 200);
values.put("price", 199);
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 v) {
// 查询数据
Uri uri = Uri.parse("content://ga.orlion.databasedemo.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("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();
}
}
});
}
}

Android入门(十四)内容提供器-实现跨程序共享实例的更多相关文章

  1. Android之 内容提供器(1)——使用内容提供器访问其它程序共享的数据

    (下面内容是阅读郭霖大神的<第一行代码>总结的) 1 概述 内容提供器是Android实现跨程序共享数据的标准方式. 内容提供器的的使用方法有两种, 一是使用已有的内容提供器对其他程序的数 ...

  2. android学习十二(android的Content Provider(内容提供器)的使用)

    文件存储和SharePreference存储以及数据存储一般为了安全,最好用于当前应用程序中訪问和存储数据.内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能 ...

  3. android笔记 : Content provider内容提供器

    内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能. 内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内 ...

  4. android: 创建自己的内容提供器

    我们学习了如何在自己的程序中访问其他应用程序的数据.总体来说思 路还是非常简单的,只需要获取到该应用程序的内容 URI,然后借助 ContentResolver 进行CRUD 操作就可以了.可是你有没 ...

  5. Android搜索框以及内容提供器

    先看结果: 相关的官方文档在这里:Creating a Search Interface Android官方提供了两种方式: 弹出一个Dialog,覆盖当前的Activity界面 在AppBar中扩展 ...

  6. <Android基础> (七)内容提供器

    第七章 内容提供器 7.1 内容提供器(Content Provider) 主要应用于在不同的应用程序之间实现数据共享功能.允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性. 7.2 ...

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

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

  8. 5、Android-跨程序共享数据--内容提供器

    Android数据持久化技术:文件存储.SharedPreferences存储.数据库存储 使用这些持久化技术保存的数据只能再当前的应用程序中访问 但是对于不同应用之间的可以实现跨程序数据共享的功能 ...

  9. Android入门(十三)内容提供器

    原文链接:http://www.orlion.ga/612/ 内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一 ...

随机推荐

  1. 版本控制--github相关

    安装 Git 后,你应该做一些只需做一次的事情:系统设置——这样的设置在每台电脑上只需做一次: $ git config --global user.name "Your Name" ...

  2. 基于Axure的快速原型方法

    Axure是一个专业的快速原型设计工具,让负责定义需求和规格.设计功能和界面的专家能够快速创建应用软件或Web网站的线框图.流程图.原型和规格说明文档.作为专业的原型设计工具,它能快速.高效的创建原型 ...

  3. android studio导入jar的两种方式

    一.第一种是打开工程所在Project Structure,然后选择Dependencies,点击那个加号选择File Dependency ,然后再Libs文件夹中选择要导入的jar包 1. 2. ...

  4. VIM使用(一) VIM插件管理利器-vundle

    有关VIM的文件网上一大堆,这里只是记录一下我新配置环境的步骤.以备查看参考. sudo apt-get install gitgit clone https://github.com/gmarik/ ...

  5. 远程连接oracle服务器

    用户名 / 密码@172.16.16.203:1521/orcl

  6. [java基础知识]java安装步骤

    jre:  java运行环境.  jre =  java虚拟机 + 核心类库(辅助java虚拟机运行的文件).如果只是运行java程序,只需要安装jre.    jdk: java开发工具集   jd ...

  7. 【IOS】异步调用--- 简单使用记录

    /×× ×实现功能:店铺被删除后,先显示提示toast.然后,页面休眠5秒后,再返回到店铺列表页面.×/ - (void)processDeleteShopError { _isLoadingData ...

  8. Linux内核--网络栈实现分析(八)--应用层发送数据(下)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7547826 更多请查看专栏,地 ...

  9. vpn找不到设备,win7建立新的VPN总时显示错误711,无法启动 Remote Access Connection Manager 及 Remote Access Auto Connection Manager 错误1068

    试试相关服务!一.remote access connection manager是网络连接的服务,它依赖于Technology服务,现在你的这个服务已经启动,而Secure Socket Tunne ...

  10. Oracle Profile 使用

    一.目的: Oracle系统中的profile可以用来对用户所能使用的数据库资源进行限制,使用Create Profile命令创建一个Profile,用它来实现对数据库资源的限制使用,如果把该prof ...