如何创建一个ContentProvider,提供给其他App访问
来源:互联网 发布:pc手机微信三合一源码 编辑:程序博客网 时间:2024/05/01 15:17
一、概述
内容提供者是封装一套给其他APP访问此APP数据的接口,并提供安全的权限机制,如何数据不用提供给其他应用访问的话,使用数据库就可以了,内容提供者更加强调的是需要跨应用。
二、编码思路
1、使用SQliteOpenHelper类,创建一个数据库。
2、写一个类继承ContentPrivoder实现抽象方法
3、定义一套访问的此ContentPrivoder的唯一路径
4、用ContentResolver对象去访问ContentPrivoder进行增删改查
1、创建DBHelper类继承SqLiteOpenHelper类
package com.kuxiao.train.contentprovider.db;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;public class DBhelper extends SQLiteOpenHelper { private static DBhelper mDBhelper = null; private static final String DB_NAME = "myDB.db";//数据库名字 private static final int DB_VERSION = 1;//数据库版本号 //建表语句 public static final String CREATE_TABLE = "create table user_info(_id Integer primary key autoincrement," + "user_id Integer,user_name text,user_address text,user_password text,user_number Integer)"; //删表语句 public static final String DROP_TABLE = "drop table if exists user_info"; private DBhelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } //单例模式 public static DBhelper getInstance(Context context) { if (mDBhelper == null) { synchronized (new Object()) { if (mDBhelper == null) { mDBhelper = new DBhelper(context); } } } return mDBhelper; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(DROP_TABLE); db.execSQL(CREATE_TABLE); }}
2、创建一个类继承ContentProvider类,实现方法,并定义好访问匹配
package com.kuxiao.train.contentprovider.db;import android.content.ContentProvider;import android.content.ContentUris;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;import android.util.Log;public class UserContentProvider extends ContentProvider { private static final String TAG = "UserContentProvider"; private DBhelper mDBhelper = null; // Uri匹配器 private static final UriMatcher MATCHER = new UriMatcher( UriMatcher.NO_MATCH); public static final int USER = 1;// 操作单条数据 public static final int USERS = 2;// 操作多条数据 static { // 增加俩条匹配规则 MATCHER.addURI("com.kuxiao.train.contentprovider.UserContentProvider", "user_info/#", USER); MATCHER.addURI("com.kuxiao.train.contentprovider.UserContentProvider", "user_info", USERS); } @Override public boolean onCreate() { mDBhelper = DBhelper.getInstance(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // Cursor cursor = null; SQLiteDatabase db = mDBhelper.getReadableDatabase(); switch (MATCHER.match(uri)) { case USER: long id = ContentUris.parseId(uri); String select = "_id = " + id; if(selection != null && !selection.equals("")) { select += "and" + selection; } cursor = db.query("user_info", projection, select, selectionArgs, null, null, sortOrder); break; case USERS: cursor = db.query("user_info", projection, selection, selectionArgs, null, null, sortOrder); break; } return cursor; } @Override public String getType(Uri uri) { switch (MATCHER.match(uri)) { case USER: return "vnd.android.cursor.item/com.kuxiao.train.contentprovider.UserContentProvider/user_info"; case USERS: return "vnd.android.cursor.dir/com.kuxiao.train.contentprovider.UserContentProvider/user_info"; } return null; } @Override public Uri insert(Uri uri, ContentValues values) { Uri resultUri = null; switch (MATCHER.match(uri)) { case USER: break; case USERS: SQLiteDatabase db = mDBhelper.getReadableDatabase(); long id = db.insert("user_info", null, values);//返回插入影响数据库的行数 resultUri = ContentUris.withAppendedId(uri, id); break; } Log.i(TAG, resultUri.toString()); return resultUri; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int con = -1; int frag = MATCHER.match(uri); SQLiteDatabase db = mDBhelper.getWritableDatabase(); switch (frag) { case USER: //解析客户端传过来的id long id = ContentUris.parseId(uri); String vaule_name = "_id = " + id; if(selection != null &&!selection.equals("")) { //如果客户端传过来的选择语句不为空将进行累加 vaule_name += "and" + selection; } con = db.delete("user_info", vaule_name, selectionArgs); break; case USERS: con = db.delete("user_info", selection, selectionArgs); break; } db.close(); return con; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int con = -1; // update user_info set name = ?,address = ? where id = ?; SQLiteDatabase db = mDBhelper.getWritableDatabase(); switch (MATCHER.match(uri)) { case USER: long id = ContentUris.parseId(uri); String value_name = "_id = " + id; if(selection != null && !selection.equals("")) { value_name += "and" + selection; } con = db.update("user_info", values, value_name, selectionArgs); break; case USERS: con = db.update("user_info", values, selection, selectionArgs); break; } db.close(); Log.i(TAG, "----->>>影响的行数为 " +con); return con; }}
3、单元测试
package test;import android.content.ContentResolver;import android.content.ContentUris;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.test.AndroidTestCase;import android.util.Log;public class Test extends AndroidTestCase { public void insert() { // 获取ContentResolver对象 ContentResolver contentResolver = getContext().getContentResolver(); // 构建解析路径:content://<authority>/<path>/<id> 单条 // content://<authority>/<path> 多条 Uri uri = Uri .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info"); ContentValues values = new ContentValues(); values.put("user_id", 3); values.put("user_name", "张万里"); values.put("user_address", "dalian"); values.put("user_password", "yw123456789"); values.put("user_number", 953751759); contentResolver.insert(uri, values); } public void update() { // 获取ContentResolver对象 ContentResolver resolver = getContext().getContentResolver(); // 构建Uri content:// + 授权 + 表名 Uri uri = Uri .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info/6"); ContentValues values = new ContentValues(); values.put("user_id", 2); values.put("user_name", "刘海洋"); values.put("user_address", "beijing"); values.put("user_password", "I love you liu haiyang"); values.put("user_number", 123456789); resolver.update(uri, values, null, null); } public void delete() { // 获取ContentResolver对象 ContentResolver resolver = getContext().getContentResolver(); // 构建Uri content:// + 授权 + 表名 Uri uri = Uri .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info"); ContentValues values = new ContentValues(); resolver.delete(uri, null, null); } public void query() { ContentResolver contentResolver = getContext().getContentResolver(); Uri uri = Uri .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info"); Cursor cursor = contentResolver.query(uri, null, null, null, null); while (cursor.moveToNext()) { Log.i("UserContentProvider", "------->>>>>>" + cursor.getInt(cursor.getColumnIndex("user_id"))); Log.i("UserContentProvider", "------->>>>>>" + cursor.getString(cursor.getColumnIndex("user_name"))); Log.i("UserContentProvider", "------->>>>>>" + cursor.getString(cursor.getColumnIndex("user_address"))); Log.i("UserContentProvider", "------->>>>>>" + cursor.getString(cursor.getColumnIndex("user_password"))); Log.i("UserContentProvider", "------->>>>>>" + cursor.getInt(cursor.getColumnIndex("user_number"))); } }}
四、主意事项
1、在清单文件增加授权
<provider android:name=".db.UserContentProvider"//授权一般是包名+类名 android:authorities="com.kuxiao.train.contentprovider.UserContentProvider"/>
2、定义访问路径标示符,操作单条与多条的区别
private static final UriMatcher MATCHER = new UriMatcher( UriMatcher.NO_MATCH); public static final int USER = 1;// 操作单条数据 public static final int USERS = 2;// 操作多条数据 static { // 增加俩条匹配规则 //路径为:授权+数据库表名+标示符 (单条要在表名后加上/#号) MATCHER.addURI("com.kuxiao.train.contentprovider.UserContentProvider", "user_info/#", USER); MATCHER.addURI("com.kuxiao.train.contentprovider.UserContentProvider", "user_info", USERS); }
3、重写getType方法是操作单条还是多条的区别
@Override public String getType(Uri uri) { //根据传过来的uri解析 返回对应的字符串,参考开发文档 switch (MATCHER.match(uri)) { case USER: return "vnd.android.cursor.item/com.kuxiao.train.contentprovider.UserContentProvider/user_info"; case USERS: return "vnd.android.cursor.dir/com.kuxiao.train.contentprovider.UserContentProvider/user_info"; } return null; }
4、通过内容解析者访问时,路径定义
// 构建Uri content:// + 授权 + 表名 // 构建解析路径:content://<authority>/<path>/<id> 单条 // content://<authority>/<path> 多条 Uri uri = Uri .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info/6");//单条 Uri uri = Uri .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info"); //多条
五、特别说明:此都是小白成长记,有何不妥,欢迎指教。
0 0
- 如何创建一个ContentProvider,提供给其他App访问
- ContentProvider提供者的使用,一个app访问另一个app的数据库
- 如何让Oracle的表能提供给其他用户访问?
- ContentProvider的创建与访问
- 如何创建自己的ContentProvider
- Android 如何自定义一个ContentProvider
- ContentProvider(4):怎样获取其他APP分享的数据
- ContentProvider将程序中的数据暴露给其他程序访问
- 第十七篇 ContentProvider之访问其他程序中的数据
- 如何将app打包成ipa文件,提供给客户测试(越狱机)
- 如何将自己的App作为外部数据源提供给Android系统搜索?
- ContentProvider 一个应用程序访问另一个应用程序
- ContentProvider 实例详解一(创建一个自己的ContentProvider)
- Ubuntu如何访问其他分区
- Android_如何为一个app创建桌面快捷方式
- android限制app的敏感ContentProvider的可访问性
- 创建一个app流程
- 如何访问一个文件的创建、修改时间、文件属性
- MySQL索引原理及慢查询优化
- 稀疏表示学习之路之基本概述
- Linux环境下Python操作word
- 函数嵌套例子
- 【BZOJ 2152】聪聪可可 点分治
- 如何创建一个ContentProvider,提供给其他App访问
- 远程重启服务器
- 深入理解react native布局(一)居中
- spring的事务配置5中方式
- java IO流学习
- loadrunner运行app脚本负载测试时passed transaction 为0
- [LeetCode]21. Merge Two Sorted Lists(C++)
- Quartz 2D 绘图(线条、矩形、圆弧、贝塞尔曲线、图片、文字)
- android 7.0 system UI之快速启动栏的分析(一)