栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

android四大组件之ContentProvider(内容提供器)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

android四大组件之ContentProvider(内容提供器)

今天是2022年元旦,普天同庆的日子当然要记一篇CSDN庆祝下拉,又不是永远可以这么无忧无虑!

闲言少叙,直奔主题!

ContentProvider主要用于在不同的程序之间实现数据共享的功能,这是android提供了一套完整的机制,允许一个程序访问另外一个程序中的数据,同时还保证被访数据安全性。

ContentProvider用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内容提供器给我们的程序提供外部的数据共享接口

1.我们先通过访问android系统自带的电话簿,来学习提供器如何跨程序访问数据!

任何应用,想要访问内容提供器中共享的数据,就要借助ContentResolver类,Context中的getContentResolver()可以获得实例!ContentResolver提供了一系列方法对数据进行CRUD操作,insert方法用于添加数据,update用于更新,delete用于删除,query用于查询!是不是感觉很熟悉,没错,这跟SQliteDatabase里的CRUD方法差不多,不过不同的是这些方法接收的参数不是表名,而是接收一个名为内容Uri的参数,内容Uri给内容提供器中数据建立了唯一标识符,它由两部分组成,1,权限,2,路径

权限:权限是用于对不同程序做区分,一般都采用包名的方式进行命名,譬如包名是com.shurol.app,那权限就可以命名为com.shurol.app.provider。

路径:则是对于同一程序中不同表做区分,譬如程序中有数据表table1,那路径命名为/table1

最后还需要在字符串头部加上协议声明!

所以完整的URI字符为:content://com.shurol.app.provider/table1

得到这个URI字符串后还不能直接作为参数,还需要将其解析为Uri对象,解析方法如下

Uri uri=Uri.parse("content://com.shurol.app.provider/table1");

接下来直接上代码,先直接利用内容提供器获取系统的通讯录。

public List getData() {
		List list = new ArrayList();//preson里只存放name,number,两个数据
		Cursor cursor = null;
		try {
			cursor=getContentResolver().query(
					ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
					null, null);//ContactsContract.CommonDataKinds.Phone.CONTENT_URI是系统提供的访问通讯录的Uri
			while (cursor.moveTonext()) {
				String name=cursor.getString(cursor
						.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
				String number=cursor.getString(cursor
						.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
				list.add(new Preson(
						name,number));

			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			if(cursor!=null)cursor.close();
		}
		
		return list;
	}

上面这个方法就是获取系统的通讯录,把每个联系人的姓名跟电话读出来放入到准备好的存放Preson集合里!并返回集合!

接着我们创建自己的内容提供器,重新新建一个项目1,默认给新的app里用SQlite新建两张表,table1,table2,这里称项目1的应用叫APP1,我们在App1界面可以直观看到这两个数据表的信息,并且一会创建APP2来对APP1进行数据操作的时候,可以动态查看数据变化!先看我手机截图!

 我在APP1里先动态往两张数据库的表添加了这些数据,一看就知道我是文艺青年!

这两个表SQLite怎么创建表我这里就不赘述了,不了解的可以看我博客关于SQlite的用法!新建一个类命名为MyProvider,继承ContentProvider,我们主要实现这个类的六个抽象方法!先上代码,再慢慢分析!我们可以在URI路径后面再加上一个id,譬如:

content://com.shurol.app.provider/table1/1,这样代表访问table表中id为1的数据,每个方法都有注释,对数据库进行CRUD操作不熟悉的先去了解!

public class MyProvider extends ContentProvider {
	private MyDatabaseHelper dbHelper;
	private static UriMatcher urimatcher;
	public static final int TABLE1_DIR = 0;
	public static final int TABLE1_ITEM = 1;
	public static final int TABLE2_DIR = 2;
	public static final int TABLE2_ITEM = 3;
	public static final String AUTHORITY = "com.example.contentproviderphone.provider";
	
	static {
		urimatcher = new UriMatcher(UriMatcher.NO_MATCH);
		urimatcher.addURI("com.example.contentproviderphone", "table1",
				TABLE1_DIR);
		urimatcher.addURI("com.example.contentproviderphone", "table1/#",
				TABLE1_ITEM);
		urimatcher.addURI("com.example.contentproviderphone", "table2",
				TABLE2_DIR);
		urimatcher.addURI("com.example.contentproviderphone", "table2/#",
				TABLE2_ITEM);
	}
	
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		int deleteRows = 0;
		switch (urimatcher.match(uri)) {
		case TABLE1_DIR:
			deleteRows = db.delete("table1", selection, selectionArgs);
			break;
		case TABLE1_ITEM:
			String table1id = uri.getPathSegments().get(1);
			deleteRows = db.delete("table1", "id=?", new String[] { table1id });
			break;
		case TABLE2_DIR:
			deleteRows = db.delete("table2", selection, selectionArgs);
			break;
		case TABLE2_ITEM:
			String table2id = uri.getPathSegments().get(1);
			deleteRows = db.delete("table2", "id=?", new String[] { table2id });
			break;
		default:
			break;
		}
		return deleteRows;
	}
	
	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		switch (urimatcher.match(uri)) {
		case TABLE1_DIR:

			return "vnd.android.cursor.dir/vnd.com.example.contentproviderphone.provider.table1";
		case TABLE1_ITEM:

			return "vnd.android.cursor.item/vnd.com.example.contentproviderphone.provider.table1";
		case TABLE2_DIR:

			return "vnd.android.cursor.dir/vnd.com.example.contentproviderphone.provider.table2";
		case TABLE2_ITEM:

			return "vnd.android.cursor.item/vnd.com.example.contentproviderphone.provider.table2";
		default:
			break;
		}
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues value) {
		// TODO Auto-generated method stub
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		Uri uriReturn = null;
		switch (urimatcher.match(uri)) {
		case TABLE1_DIR:

		case TABLE1_ITEM:
			long newid = db.insert("table1", null, value);
			uriReturn = Uri.parse("content://" + AUTHORITY + "/table1/" + newid);
			break;
		case TABLE2_DIR:

		case TABLE2_ITEM:
			long newid2 = db.insert("table2", null, value);
			uriReturn = Uri.parse("content://" + AUTHORITY + "/table2/" + newid2);
			break;
		default:
			break;
		}
		return uriReturn;
	}

	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		dbHelper = new MyDatabaseHelper(getContext(), "MyStore.db", null, 2);
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Cursor curson = null;
		switch (urimatcher.match(uri)) {
		case TABLE1_DIR:
			curson = db.query("table1", projection, selection, selectionArgs,
					null, null, sortOrder);
			break;
		case TABLE1_ITEM:
			String tableID = uri.getPathSegments().get(1);
			Log.d("data", tableID);
			curson = db.query("table1", projection, "id=?",
					new String[] { tableID }, null, null, sortOrder);
			break;
		case TABLE2_DIR:
			curson = db.query("table2", projection, selection, selectionArgs,
					null, null, sortOrder);
			break;
		case TABLE2_ITEM:
			String table2ID = uri.getPathSegments().get(1);
			curson = db.query("table2", projection, "id=?",
					new String[] { table2ID }, null, null, sortOrder);
			break;
		default:
			break;
		}
		return curson;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		int updatedRow = 0;
		switch (urimatcher.match(uri)) {
		case TABLE1_DIR:

			updatedRow = db.update("table1", values, selection, selectionArgs);
			break;
		case TABLE1_ITEM:
			String tableID = uri.getPathSegments().get(1);
			updatedRow = db.update("table1", values, "id=?",
					new String[] { tableID });
			break;
		case TABLE2_DIR:
			updatedRow = db.update("table2", values, selection, selectionArgs);
			break;
		case TABLE2_ITEM:
			String table2ID = uri.getPathSegments().get(1);
			updatedRow = db.update("table2", values, "id=?",
					new String[] { table2ID });
			break;
		default:
			break;
		}
		return updatedRow;
	}

}

 到这里,APP1里的所有代码就完成了,接着新建APP2的程序,简单用内容提供器的方法访问和操作APP1提供好的数据!

上APP2代码

public class MainActivity extends Activity implements onClickListener {
	Button bt_insert, bt_update, bt_select, bt_delete;
	TextView tv_table1, tv_table2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		bt_insert = (Button) findViewById(R.id.bt_insert);
		bt_update = (Button) findViewById(R.id.bt_update);
		bt_select = (Button) findViewById(R.id.bt_showdata);
		bt_delete = (Button) findViewById(R.id.bt_delete);
		tv_table1 = (TextView) findViewById(R.id.tv_table1);
		tv_table2 = (TextView) findViewById(R.id.tv_table2);
		bt_insert.setonClickListener(this);
		bt_update.setonClickListener(this);
		bt_select.setonClickListener(this);
		bt_delete.setonClickListener(this);
	}

	@Override
	public void onClick(View view) {
		// TODO Auto-generated method stub
		switch (view.getId()) {
		case R.id.bt_insert:
			// 添加数据
			Uri uri = Uri
					.parse("content://com.example.contentproviderphone.provider/table1");
			ContentValues values = new ContentValues();
			values.put("name", "三国演义");
			values.put("author", "罗贯中");
			values.put("pages", 254);
			values.put("price", 22.34);
			getContentResolver().insert(uri, values);
			break;
		case R.id.bt_update:
			Uri uri2 = Uri
					.parse("content://com.example.contentproviderphone.provider/table2/2");
			ContentValues valuse2 = new ContentValues();
			valuse2.put("price", 100.00);
			getContentResolver().update(uri2, valuse2, null, null);
			break;
		case R.id.bt_delete:
			Uri uri3 = Uri.parse("content://com.example.contentproviderphone.provider/table1/1");
			getContentResolver().delete(uri3, null, null);
			break;
		case R.id.bt_showdata:
			StringBuffer sb = new StringBuffer();
			Uri uri4 = Uri
					.parse("content://com.example.contentproviderphone.provider/table1");
			Cursor cursor = getContentResolver().query(uri4, null, null, null,
					null);
			while (cursor.moveTonext()) {
				sb.append(cursor.getString(cursor.getColumnIndex("name")) + ","
						+ cursor.getString(cursor.getColumnIndex("name")) + ","
						+ cursor.getInt(cursor.getColumnIndex("pages")) + ","
						+ cursor.getDouble(cursor.getColumnIndex("price"))
						+ "n");
				tv_table1.setText(sb.toString());

			}
			break;

		default:
			break;
		}
	}

APP2界面有四个按钮,还有两个TextView,用来展示table1,table2里的数据。好了,代码相信很简单,一看就懂,一学就废!我自己已经扛不住了,脖子好酸!程序员的悲哀!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/692476.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号