文档章节

ContentProvider:自定义的应用

f
 flyqilong
发布于 2016/02/21 20:50
字数 1563
阅读 3
收藏 0
//继承ContentProvider的自定义类
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 com.example.Sqlutil.MySqliteOpenHelper;

//以下代码是继承ContentProvider类用它里面的增删改查方法,其他应用操作时就是调用这里的方法
/*在清单文件中声明注册 ContentProvider ://在<activity>里面配置
 <provider android:name=".MyWordsProvider"
 android:authorities="com.steven.wordscontentprovider"
 android:exported="true"
 />
 //android:name 属性的值是: 继承ContentProvider 类的子类的完整路径;
 //android:authorities 属性的值是: content:URI 中 authority 部分。一般就是将 name 属性的值全小写,可以自己写,但要记住。
 //android:exported 属性是否允许其他应用调用。如果是 false ,则该 ContentProvider 不允许其他应用调用
 */
public class MyContentProvider extends ContentProvider {
	// authorties功能清单中您配置暴露给其他应用使用的属性名字
	private static String authorties = "com.example.providercustomUtils.mycontentprovider";
	private MySqliteOpenHelper openHelper;// 继承SQLiteOpenHelper的类
	private static UriMatcher matcher;// 匹配器/匹配类:当外部应用调用它内部的方法时,要匹配外部应用传进来的uri
	private static final int MATCH_STUDENT = 110;
	private static final int MATCH_NAME = 119;
	private static final int MATCH_SCORE = 120;
	static {// 静态代码块只执行一次
		matcher = new UriMatcher(UriMatcher.NO_MATCH);// 如果uri不匹配,即不正确时 ,返回-1;
		// 第一个参数:uri中authorties,第二个参数:path路径,建议写上表名;第三个:匹配正确的返回值(自定义的值)
		// matcher.addURI(authority, path, code),可以写多个matcher
		matcher.addURI(authorties, "studentinfo", MATCH_STUDENT);
		matcher.addURI(authorties, "studentinfo/*", MATCH_NAME);
		matcher.addURI(authorties, "studentinfo_id/#", MATCH_SCORE);
		// 注意:文本跟数字matcher都存在时,path所取的名字要不同,/*这个是文本标志,/#个是数字的标志
	}

	// 以下只用到一个Uri
	@Override
	// 首次访问执行一次,做初始化的操作,比如去继承SQLiteOpenHelper的类去执行建表或数据库操作等
	public boolean onCreate() {
		openHelper = new MySqliteOpenHelper(getContext());
		return false;
	}

	// openHelper.getReadableDatabase() : 如果空间不足,不能写,只能读
	// openHelper.getWritableDatabase(); 如果空间不足,既不能写,也不能读(报错)
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// 查询首先用一个Switch,因为有多个mathcer时有多个操作
		Cursor cursor = null;
		SQLiteDatabase db = openHelper.getReadableDatabase();
		switch (matcher.match(uri)) {
		// 路径正确时,返回匹配正确的值,就查询
		case MATCH_STUDENT:
			cursor = db.query("studentinfo", projection, selection,
					selectionArgs, null, null, sortOrder);
			break;

		case MATCH_NAME:
			String name = uri.getLastPathSegment();// 获取URI最后的文本,即传过来的文字,字符等
			cursor = db.query("studentinfo", projection, "sname like ?",
					new String[] { name + "%" }, null, null, null);// 模糊查询
			break;
		case MATCH_SCORE:
			long score = ContentUris.parseId(uri);
			// 数字跟uri获取id的方式一样获取,不能像上面uri.getLastPathSegment()那样操作了
			cursor = db.query("studentinfo", projection, "score=?",
					new String[] { score + "" }, null, null, null);
			break;
		}
		return cursor;
	}

	@Override
	public String getType(Uri uri) {
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase db = openHelper.getReadableDatabase();
		Uri insertUri = null;
		switch (matcher.match(uri)) {
		case MATCH_STUDENT:
			long rowid = db.insert("studentinfo", null, values);
			insertUri = ContentUris.withAppendedId(uri, rowid);
			// 原始URI生成,等价于上面的:long row=db.insert();
			// uri=String path="content://"+authorties+"/studentinfo"+"/"+row;
			break;
		// 返回值是URI,所以要用工具类构造(ContentUris)
		default:
			break;
		}
		return insertUri;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {

		SQLiteDatabase db = openHelper.getReadableDatabase();
		int row = 0;
		switch (matcher.match(uri)) {
		case MATCH_STUDENT:
			// 返回的是影响行数
			row = db.delete("studentinfo", selection, selectionArgs);
			break;

		default:
			break;
		}
		return row;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = openHelper.getReadableDatabase();
		int row = 0;
		switch (matcher.match(uri)) {
		case MATCH_STUDENT:
			// 返回的是影响行数
			db.update("studentinfo", values, selection, selectionArgs);
			break;

		default:
			break;
		}
		return row;
	}

}


//继承SQLiteOpenHelper的数据库类
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class MySqliteOpenHelper extends SQLiteOpenHelper {
	// super(context, name, factory, version),要重写构造方法,父类参数意义
	// context上下文;name:dbName,数据库名;factory:游标工厂;version版本号,可以自己设置
	// 我们可以自己重写,让它传入的参数变少,只用传入上下文

	// 定义一些静态参数,让它传进的参数变少
	private static final String DBNAME = "student2.db";
	// 数据库会在第一次升级软件时创建,存放地址:data/data/项目.包名/datebase()
	private static final int VERSION = 1;// 版本可以自己取

	public MySqliteOpenHelper(Context context) {
		super(context, DBNAME, null, VERSION);
		/*
		 * public MySqliteOpenHelper(Context context, String name, CursorFactory
		 * factory, int version) { super(context, name, factory, version); }
		 */
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// 创建数据库表,首次升级时调用,初始化一些数据
		String sql = "create table studentinfo "
				+ " (sid integer primary key autoincrement not null,"
				+ " sname varchar(30) not null," + " sex varchar(2) not null,"
				+ " score integer not null)";
		db.execSQL(sql);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// 大于旧版本时,就升级
		if (newVersion > oldVersion) {
			db.execSQL("drop table if exists studentinfo ");
			// 实际操作是先备份数据,再进行删除升级
		}
	}

}

//清单文件配置
 <!-- provider配置提供给其他应用跟配置activity差不多,exported="true"true代表给外面调用 -->
        <provider
            android:name="com.example.providercustomUtils.MyContentProvider"
            android:authorities="com.example.providercustomUtils.mycontentprovider"
            android:exported="true" >
        </provider>

//以下是我新建一个项目进行跨应用的测试类

//用来测试自定义ContentProvider类,即跨应用的使用测试(测试的自定义项目名称是:AndDay16ContentProviderCustom)
public class StudnetProviderTest extends AndroidTestCase {
	// scheme://authority/path
	// authority为com.example.providercustomUtils.mycontentprovider
	// 要记得你在另外一个项目应用的配置的authorities,不能有错,后面加上路径、表名等构成Uri
	private String student_uri = "content://com.example.providercustomUtils.mycontentprovider/studentinfo";
	// student_name访问文本,被操作的应用那里要写一个匹配器 ,/*这个是文本标志
	private String student_name = "content://com.example.providercustomUtils.mycontentprovider/studentinfo/小";// 就想访问数据库字段,模糊查询
	// student_score访问的是数字,被操作的应用那里要写一个匹配器,/#个是数字的标志
	private String student_score = "content://com.example.providercustomUtils.mycontentprovider/studentinfo_id/90";
	private ContentResolver resolver;
	private Cursor cursor;

	public void queryTest() {
		resolver = getContext().getContentResolver();
		cursor = resolver.query(Uri.parse(student_score), new String[] { "sid",
				"sname", "sex", "score" }, null, null, null);
		while (cursor.moveToNext()) {
			String sname = cursor.getString(cursor.getColumnIndex("sname"));
			String sex = cursor.getString(cursor.getColumnIndex("sex"));
			String score = cursor.getString(cursor.getColumnIndex("score"));
			Log.i("MainActivity", sname + "-" + sex + "-" + score);
			// String sname = cursor.getString(1);
			// String sex = cursor.getString(2);
			// String score = cursor.getString(3);
		}
		cursor.close();
	}

	public void addTest() {
		resolver = getContext().getContentResolver();
		ContentValues values = new ContentValues();
		values.put("sname", "小小");
		values.put("sex", "女");
		values.put("score", 98);
		Uri insertUri = resolver.insert(Uri.parse(student_uri), values);
		Log.i("MainActivity", "row id" + ContentUris.parseId(insertUri));// 系统带的ContentUris.parseId,把uri放进去可以返回一个插入后的id
	}

}
//测试时在Mianifest.xml功能文件引入测试单元
 <!-- 引入Android单元测试框架  <application>外面加入-->
    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.andday16providercustomtest" >
    </instrumentation>
    <!-- 单元测试的依赖包 在 <application 的里面加入-->
        <uses-library android:name="android.test.runner" />


© 著作权归作者所有

f
粉丝 3
博文 93
码字总数 53900
作品 0
Android工程师
私信 提问
ContentProvider学习

当一个应用程序需要把自己的数据暴露给其他程序使用时,该就用程序就可通过提供ContentProvider来实现;其他应用程序就可通过ContentResolver来操作ContentProvider暴露的数据。 一旦某个应用...

天下杰论
2012/09/19
0
0
关于ContentProvider数据共享与其他共享方式区别的理解

关于不同应用程序之间的数据共享,已有的方式包括SharedPreferences和文件存储或者数据库,这几种操作的一个特点是,第三方程序直接操作数据,可以根据自己的需要随意进行数据操作,而不需要...

刘遇安
2012/09/21
0
0
Android四大组件ContentProvider

ContentProvider主要用于在不同应用程序之间实现数据共享功能。允许一个程序访问另一个程序,并保证被访数据的安全性。 Android系统自带的电话簿、短信、媒体库等提供了类似的接口。还可以通...

DouDouLee
2016/03/11
19
0
ContentProvider和ContentResolver的使用

ContentProvider ContentProvider 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数...

Lilycoding
02/26
0
0
自定义ContentProvider(内容提供者)简单使用例子

功能:跨app访问本app数据库一些基本操作 本app中: 1、在配置清单里配置权限和自定义ContentProvider对外暴露给其他应用访问的路径 代码 <?xml version="1.0" encoding="utf-8"?> <manifest......

初来小修
2016/02/13
91
0

没有更多内容

加载失败,请刷新页面

加载更多

Wondershare Recoverit - 专业数据恢复神器,支持U盘、存储卡等外部设备!

Wondershare Recoverit 今天带来的这款软件叫做Wondershare Recoverit,是一款专业实用的数据恢复软件,也是一款比较久的数据恢复软件了,可以恢复所有文件类型。 包括照片、视频、文档和其他...

_Somuns
26分钟前
7
0
SpringCloud gateway 修改返回数据

SpringCloud gateway 修改返回数据 版本说明 开源软件 版本 springboot 2.1.6.RELEASE jdk 11.0.3 gradle 主要引入了springboot 2.1,lombok plugins { id 'org.springframework.boot' v......

buddie
今天
9
0
PHP实现单人多人聊天源码免费分享 | 电脑报修系统

源码清单 1. 简易版登陆式聊天源码。 2. 电脑报修轻系统源码。 3. 关注下面公众号回复“聊天”,免费获取。 聊天系统 虽然微信,QQ是即时通讯的元老。但是他们限制很多,所以很多人都想做一个...

北桥苏
今天
6
0
跟面部识别开愚人玩笑?做一个时尚口罩就能实现

全文共3208字,预计学习时长6分钟 图片来源:Upsplash/Pavel Anoshin 目前,人脸识别的使用率正在不断上升,随之而来关于面部识别道德问题的争论也愈发激烈。从机场到社交媒体,面部识别的应...

读芯术
今天
1
0
Git同步更新操作GitHub和码云仓库上面的代码

一、前言 问题: 小编在生活中,一般都是将代码保存到github上,但由于国内的码云仓库确实速度比github快很多,用起来也很方便,于是后来就慢慢转码云了,当然小编在github上的代码也不想放弃...

郑清
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部