转载请标明出处:
http://blog.csdn.net/gj782128729/article/details/52522999;
本文出自:【高境的博客】
1. 访问私有数据库
创建一个项目,在项目中利用SQLiteOpenHelper创建一个名称为account的数据库,并在数据库中创建一张名为info的表。
public class MyOpenHelper extends SQLiteOpenHelper {
public MyOpenHelper(Context context) {
super(context, "account.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table info (_id integer primary key autoincrement,name varchar(20),money varchar(20))");
db.execSQL("insert into info('name','money') values ('张三','2000')");
db.execSQL("insert into info ('name','money') values ('李四','5000')");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
}
}
在MainActivity中需要调用以下代码才能创建数据库:
private MyOpenHelper myOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myOpenHelper = new MyOpenHelper(this);
myOpenHelper.getReadableDatabase();
}
运行程序,我们利用DDMS中的FileExplorer查看我们的数据库文件:
从上图可以看到创建了一个account.db的数据库,查看文件权限可以看到,对其他用户没有权限。
SQLiteDatabase有一个静态的方法,可以直接加载某个路径下的数据库文件。我们再创建一个项目工程,在这个工程中用这个静态方法访问account.db。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SQLiteDatabase db = SQLiteDatabase.openDatabase("/data/data/com.itheima.transation/databases/account.db", null, SQLiteDatabase.OPEN_READWRITE);
Cursor cursor = db.query("info", null, null, null, null, null, null);
if (cursor!=null && cursor.getCount()>0){
while (cursor.moveToNext()) {
String name=cursor.getString(cursor.getColumnIndex("name"));
String money=cursor.getString(cursor.getColumnIndex("money"));
System.out.println("name"+name + "money"+money);
}
}
}
运行结果:
以上结果说明我们使用SQLiteDatabase.openDatabase()方法打开数据库需要有权限才能够访问。我们改变account.db的访问权限,使其他用户也能访问该文件:
再次运行程序,访问account.db数据库,这时候就能够访问到数据库中的数据了。查看日志输出如下:
这种方式虽然能够访问到其他应用程序的数据库,但是这种方式需要手动改变其他应用程序数据库的访问权限,并且这是一种非常不安全的操作,如果改变应用数据库的访问权限,其他程序很容易修改数据库的内容。那么如何才能访问其他应用程序的数据库呢?Google给我们提供了Android中另一个组件ContentProvider内容提供者来解决这个问题。
2. 内容提供者
ContentProvider(内容提供者)是Android中的四大组件之一,在一般的开发中,可能使用的比较少。
ContentProvider为不同的软件之间数据共享,提供统了一套接口。也就是说,如果我们想让其他的应用使用我们自己程序内的数据,就可以使用ContentProvider定义一组对外开放的接口,从而使得其他的应用可以使用咱们应用的文件、数据库内存储的信息。
当然,自己开发的应用需要给其他应用共享信息的需求可能比较少见,但是在Android系统中,很多系统自带应用,比如联系人信息,图片库,音频库等应用,为了对其他应用暴露数据,所以就使用了ContentProvider机制。所以,学习ContentProvider的基本使用,在遇到获取联系人信息,图片库,音频库等需求的时候,才能更好的开发。
2.1. 内容提供者的原理
内容提供者定义了一组对外开放的接口,使其他应用可以访问自己的应用的数据库内容,下图是外部应用访问系统联系人应用数据库的原理图:
从上图可以看出,普通外部应用不可以直接访问私有的数据库,只能通过内容提供者访问私有数据库,内容提供者处于应用内部,在内容提供者中定义了一些访问路径匹配等操作,当外部应用通过路径访问私有数据库时,内容提供者根据路径匹配出具体的操作,将私有数据返回给外部应用。
2.2. 内容提供者的使用
(a)创建一个类继承ContentProvider,实现其中的方法
public class AccountProvider extends ContentProvider {
//当内容提供者创建的时候调用
@Override
public boolean onCreate() {
return true;
}
//用于查询数据库数据,返回值是Cursor即结果的数据集
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
}
//返回MIME类型的字符串,如果返回null,说明没有数据类型
@Override
public String getType(Uri uri) {
return null;
}
//用于向数据库插入记录
@Override
public Uri insert(Uri uri, ContentValues values) {
}
//用于删除数据库记录
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
}
//用于更新数据库记录
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
}
}
(b)清单文件中配置内容提供者
<provider
android:name="com.itheima.transation.AccountProvider"
//设置主机名
android:authorities="com.itheima.account.provider" >
</provider>
(c)定义路径匹配规则
//定义当路径匹配成功后对指定的组件返回的返回码
private static final int QUERYSUCESS = 1;
private static final int ADDSUCESS = 2;
private static final int DELSUCESS = 3;
private static final int UPDATESUCESS = 4;
//创建Uri的匹配对象
static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
//增加匹配规则,参数1为主机名,参数2为路径,参数3为当路径匹配成功后对指定的组件返回的返回码,必须是正数。该主机名必须和清单文件中配置的主机名一致。
matcher.addURI("com.itheima.account.provider", "query", QUERYSUCESS);
matcher.addURI("com.itheima.account.provider", "add", ADDSUCESS);
matcher.addURI("com.itheima.account.provider", "delete", DELSUCESS);
matcher.addURI("com.itheima.account.provider", "update", UPDATESUCESS);
}
注意:主机名必须和清单文件中配置的主机名一致。
Uri的组成规则:协议名://主机名或authority/路径/ID。Uri的组成可以参考下图: