使用内容提供者可以让其它应用访问我们的私有数据。
使用内容提供者步骤:
1 创建一个类继承自ContentProvider,实现需要暴露的方法(增删改查)
package com.example.wnl;
import com.wnl.db.DBHelper;
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 MyContentProvider extends ContentProvider {
private DBHelper dbHelper;
// URi匹配,匹配不成功返回UriMatcher.NO_MATCH
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int URI_MATCHED = 1;// Uri成功匹配,一组数据
private static final int URI_MATCHED_SINGLE = 2;// Uri成功匹配,一条数据
static {
/**
* @param authority
* 主机名路径的前缀 一般是应用包名
* @param path
* 路径
* @param code
* 匹配成功返回的码
*/
uriMatcher.addURI("com.example.wnl", "contact", URI_MATCHED);
uriMatcher.addURI("com.example.wnl", "contact/#", URI_MATCHED_SINGLE);
}
@Override
public boolean onCreate() {// 初始化ContentProvider
dbHelper = new DBHelper(getContext());
return true;// true ContentProvider成功加载
}
/**
* @param projection
* 查询的列
* @param selection
* 查询的条件
* @param selectionArgs
* 查询的条件参数
* @param sortOrder
* 对查询的结果进行排序
*/
@Override
// 返回数据给调用者
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int code = uriMatcher.match(uri);
if (code == URI_MATCHED) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
// 这里不要关闭数据库,因为关闭了数据库后,Cursor也自动关闭,查询不到结果
return db.query("contact", projection, selection, selectionArgs,
null, null, sortOrder);
} else if (code == URI_MATCHED_SINGLE) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
String path = uri.toString();
// 这里不要关闭数据库,因为关闭了数据库后,Cursor也自动关闭,查询不到结果
return db.query("contact", projection, "id=?",
new String[] { path.substring(path.lastIndexOf("/") + 1) },
null, null, sortOrder);
} else {
throw new IllegalArgumentException("Uri不匹配");
}
}
@Override
public String getType(Uri uri) {
int code = uriMatcher.match(uri);
if (code == URI_MATCHED) {
return "vnd.android.cursor.dir/contact";
} else if (code == URI_MATCHED_SINGLE) {
return "vnd.android.cursor.item/contact";
} else {
throw new IllegalArgumentException("数据类型不正确");
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// Uri匹配判断
int code = uriMatcher.match(uri);
if (code == URI_MATCHED) {// 匹配通过
SQLiteDatabase db = dbHelper.getWritableDatabase();
long rowId = db.insert("contact", null, values);
db.close();
return Uri.parse("content://com.example.wnl/contact" + rowId);
} else {
throw new IllegalArgumentException("Uri is not matched");
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Uri匹配判断
int code = uriMatcher.match(uri);
if (code == URI_MATCHED) {// 匹配通过
SQLiteDatabase db = dbHelper.getWritableDatabase();
int deleteCount = db.delete("contact", selection, selectionArgs);
db.close();
return deleteCount;
} else {
throw new IllegalArgumentException("Uri is not matched");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// Uri匹配判断
int code = uriMatcher.match(uri);
if (code == URI_MATCHED) {// 匹配通过
SQLiteDatabase db = dbHelper.getWritableDatabase();
int updateCount = db.update("contact", values, selection,
selectionArgs);
db.close();
return updateCount;
} else {
throw new IllegalArgumentException("Uri is not matched");
}
}
}
2 在配置文件里面配置必要信息
<provider
android:name="com.example.wnl.MyContentProvider"
android:authorities="com.example.wnl"
android:exported="true"
>
</provider>
暴露数据的应用的数据库代码:
package com.wnl.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, "contact.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql="create table contact(id integer primary key autoincrement, name varchar(20), phone varchar(20))";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
3 在需要访问暴露私有数据的应用程序中进行访问
package com.example.read;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 查询数据
*
* @param view
*/
public void read(View view) {
// 获取内容提供者解析器
ContentResolver cr = getContentResolver();
// 执行查询操作
Uri uri = Uri.parse("content://com.example.wnl/contact");// 全部查询
// Uri uri=Uri.parse("content://com.example.wnl/contact/78");//查询指定数据
String type = cr.getType(uri);
if (type.startsWith("vnd.android.cursor.dir")) {
Cursor cursor = cr.query(uri, null, null, null, null);
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
String phone = cursor.getString(2);
System.out.println("id:" + id + " " + "name:" + name + " "
+ "phone:" + phone);
}
cursor.close();
} else if (type.startsWith("vnd.android.cursor.item")) {
Cursor cursor = cr.query(uri, null, null, null, null);
cursor.moveToFirst();
int id = cursor.getInt(0);
String name = cursor.getString(1);
String phone = cursor.getString(2);
System.out.println("id:" + id + " " + "name:" + name + " "
+ "phone:" + phone);
cursor.close();
}
}
/**
* 添加数据
*
* @param view
*/
public void insert(View view) {
// 获取内容提供者解析器
ContentResolver cr = getContentResolver();
// 执行查询操作
Uri uri = Uri.parse("content://com.example.wnl/contact");
ContentValues values = new ContentValues();
values.put("name", "王五");
values.put("phone", "123456");
Uri createdUri = cr.insert(uri, values);
Toast.makeText(MainActivity.this, "添加成功" + createdUri, 0).show();
}
/**
* 删除数据
*
* @param view
*/
public void delete(View view) {
// 获取内容提供者解析器
ContentResolver cr = getContentResolver();
// 执行查询操作
Uri uri = Uri.parse("content://com.example.wnl/contact");
int count = cr.delete(uri, "name=?", new String[] { "王五" });
Toast.makeText(MainActivity.this, "删除了" + count + "条数据", 0).show();
}
/**
* 修改数据
*
* @param view
*/
public void update(View view) {
// 获取内容提供者解析器
ContentResolver cr = getContentResolver();
// 执行查询操作
Uri uri = Uri.parse("content://com.example.wnl/contact");
ContentValues values = new ContentValues();
values.put("phone", "654321");
int count = cr.update(uri, values, "name=?", new String[] { "王五" });
Toast.makeText(MainActivity.this, "修改" + count + "条数据成功", 0).show();
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="read"
android:text="读取数据" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="insert"
android:text="添加数据" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="delete"
android:text="删除数据" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="update"
android:text="修改数据" />
、
</LinearLayout>