android内容提供者contentProvider

一、基本概念

内容提供者就好比是中间人,通过它可以将本应用的一些方法暴露出去,然后其它应用通过内容解析者获取该应用的内容。

二、内容提供者使用步骤

(1)定义内容提供者,即定义一个类继承contentProvider

(2)在清单文件里配置该contentProvider

<provider
     android:name="com.zgs.CreatePrivateDB.AccountProvider"
     android:authorities="com.zgs.provider"
     android:exported="true" > <!-- 一定要设为true,否则其它程序无法调用 -->
</provider>
(3)定义一个Uri匹配器UriMatcher

(4)写一个静态代码块,添加匹配规则

(5)按照我们添加的匹配规则暴露想暴露的方法

(6)只要是通过内容提供者暴露出来的数据其他应用只需要通过内容解析者即可获取

实例演示应用程序2读取应用程序1数据库的内容

二、应用程序1

①应用程序1项目目录结构

②MainActivity.java代码

package com.zgs.CreatePrivateDB;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		/*对应第一种查询方式时要启动该段代码,若是使用内容提供者的话就不用了
		MyOpenHelper helper = new MyOpenHelper(getApplicationContext());
		SQLiteDatabase db = helper.getReadableDatabase();

		//把张三和李四的数据取出来  
		Cursor cursor = db.query("info", null, null, null, null, null, null);
		if (cursor!=null&&cursor.getCount()>0) {
			while(cursor.moveToNext()){
				String name = cursor.getString(1);
				String money = cursor.getString(2);
				System.out.println("name:"+name+"-----"+money);
			}
			cursor.close();
		}*/
	}
}
③MyOpenHelper.java代码
package com.zgs.CreatePrivateDB;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class MyOpenHelper extends SQLiteOpenHelper {

	/**
	 * name 数据库的名字 
	 * factory 游标工厂 
	 * version 版本
	 */
	public MyOpenHelper(Context context) {
		super(context, "Account.db", null, 1);
	}

	/**
	 * Called when the database is created for the first time
	 * 当数据库第一次 创建的时候调用 那么这个方法特别适合做 表结构的初始化 
	 * 
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		//★★★★★注意id用下划线是因为以后CursorAdapter里面要去得到的cursor对象必须有_id列
		db.execSQL("create table info(_id integer primary key autoincrement,name varchar(20),money varchar(20))");
		db.execSQL("insert into info(name,money) values(?,?)", new String[]{"张三","5000"});
		db.execSQL("insert into info(name,money) values(?,?)", new String[]{"李四","3000"});
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

	}

}
④AccountProvider.java代码
package com.zgs.CreatePrivateDB;

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 AccountProvider extends ContentProvider {

	//[1]定一个一个uri路径匹配器 
	private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
	private static final int QUERYSUCESS = 0;  //ctrl+shift+X  变大写   小写加y
	private static final int INSERTSUCESS = 1;
	private static final int UPDATESUCESS = 2;
	private static final int DELETESUCESS = 3;
	private MyOpenHelper myOpenHelper;
	//[2]创建一个静态代码块 在这个里面添加 uri 
	static{

		/**
		 *                             类似于   http://www.baidu.com 
		 * authority 注意: 和清单文件里面定义的一样  com.zgs.provider/query 
		 *  
		 */
		sURIMatcher.addURI("com.zgs.provider", "query", QUERYSUCESS);
		sURIMatcher.addURI("com.zgs.provider", "insert", INSERTSUCESS);
		sURIMatcher.addURI("com.zgs.provider", "update", UPDATESUCESS);
		sURIMatcher.addURI("com.zgs.provider", "delete", DELETESUCESS);
	}

	@Override
	public boolean onCreate() {
		//[3]初始化 myopenHelpler 对象    就可以获取到sqlitedatabases对象 我们就可以操作数据库 
		myOpenHelper = new MyOpenHelper(getContext());
		System.out.println("我运行了……");
		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		int code = sURIMatcher.match(uri);
		if (code ==QUERYSUCESS ) {
			//说明路径匹配成功
			SQLiteDatabase db = myOpenHelper.getReadableDatabase();
			//调用query方法
			Cursor cursor = db.query("info", projection, selection, selectionArgs, null, null, sortOrder);
			//发送一条消息 说明说明数据库被操作了 
			//getContext().getContentResolver().notifyChange(uri, null);
			//			db.close();
			//小细节 ☆ 这个cursor不能关 
			return cursor;
		}else{
			//说明路径不匹配
			//			return null;
			throw new IllegalArgumentException("uri路径不匹配 请检测路径");

		}
	}

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

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		int code = sURIMatcher.match(uri);
		if (code == INSERTSUCESS) {
			//说明路径匹配成功 
			SQLiteDatabase db = myOpenHelper.getReadableDatabase();
			long insert = db.insert("info", null, values);
			Uri uri2 = Uri.parse("com.zgsInsert/"+insert); 
			if (insert>0) {
				//发送一条消息 说明说明数据库被操作了 
				getContext().getContentResolver().notifyChange(uri, null);
			}
			//			db.close();//关闭数据库
			return uri2;

		}else {
			throw new IllegalArgumentException("uri路径不匹配 请检测路径");
		}
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int code = sURIMatcher.match(uri);
		if (code == DELETESUCESS) {
			//匹配成功 
			SQLiteDatabase db = myOpenHelper.getReadableDatabase();
			//代表影响的行数
			int delete = db.delete("info", selection, selectionArgs);
			if (delete>0) {
				//发送一条消息 说明数据库被操作了 
				getContext().getContentResolver().notifyChange(uri, null);
			}
			return delete;
		}
		return 0;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int code = sURIMatcher.match(uri);
		if (code == UPDATESUCESS) {
			//路径匹配成功
			SQLiteDatabase db = myOpenHelper.getWritableDatabase();
			//代表影响的行数 
			int update = db.update("info", values, selection, selectionArgs);
			if(update>0){
				//发送一条消息 说明说明数据库被操作了 
				getContext().getContentResolver().notifyChange(uri, null);
			}
			return update;
		}else{
			throw new IllegalArgumentException("uri路径不匹配 请检测路径");
		}
	}

}
⑤AndroidManifest.xml代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.zgs.CreatePrivateDB"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="22" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- 配置内容提供者 -->
        <provider
            android:name="com.zgs.CreatePrivateDB.AccountProvider"
            android:authorities="com.zgs.provider"
            android:exported="true" > <!-- 一定要设为true,否则其它程序无法调用 -->
        </provider>
    </application>

</manifest>

二、应用程序2

①项目目录结构

②activity_main.xml界面

activity_main.xml代码

<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"
    tools:context="com.zgs.ReadPrivateDB.MainActivity" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click1"
        android:text="add" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click2"
        android:text="del" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click3"
        android:text="update" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click4"
        android:text="query" />

</LinearLayout>
④MainActivity.java代码
package com.zgs.ReadPrivateDB;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	//点击按钮 往数据库里面插入一条数据
	public void click1(View v){
		//因为第一个应用里面的私有的数据库 已经通过内容提供者暴露出来了 所以通过内容解析者去获取数据
		Uri uri = Uri.parse("content://com.zgs.provider/insert");
		ContentValues values = new ContentValues(); //实际是map  
		//key:  代表列名  value 对应的值 
		values.put("name", "zhaoliu");
		values.put("money", 1000);
		//插入一条数据
		Uri uri2 = getContentResolver().insert(uri, values);
		System.out.println("uri2:"+uri2);
	}

	//点击按钮删除 赵六删掉
	public void click2(View v){
		//[1]获取内容的解析者 
		Uri uri = Uri.parse("content://com.zgs.provider/delete");
		//[2]代表影响的函数
		int delete = getContentResolver().delete(uri, "name=?", new String[]{"zhaoliu"});
		Toast.makeText(getApplicationContext(), "删除了"+delete+"行", 1).show();
	}

	//给赵六多点钱  1000元
	public void click3(View v){
		//[1] 创建uri
		Uri uri = Uri.parse("content://com.zgs.provider/update");
		//[2]获取内容的解析者
		ContentValues values = new ContentValues();
		values.put("money", "10000000");
		int update = getContentResolver().update(uri, values, "name=?",new String[]{"zhaoliu"});
		Toast.makeText(getApplicationContext(), "更新了"+update+"行", 1).show();
	}

	public void click4(View v){
		//      ★★★★★第一种方式读取其它项目的数据库,但这要修改对应数据库的文件权限,有时要修改对应的文件夹权限
		//      ★★★★★一定要删除读取数据库的临时文件,如本例中的Accout-journal文件
		//		SQLiteDatabase db = SQLiteDatabase.openDatabase("/data/data/com.zgs.CreatePrivateDB/databases/Account", 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(1);
		//				String money = cursor.getString(cursor.getColumnIndex("money"));
		//				System.out.println("第二个应用:name:"+name+"-----"+money);
		//			}
		//			cursor.close();
		//		}
		// 第二种 查询方式  因为第一个应用里面的私有的数据库 已经通过内容提供者暴露出来了 所以通过内容解析者去获取数据
		Uri uri = Uri.parse("content://com.zgs.provider/query");
		//获取内容解析者获取数据
		Cursor cursor = getContentResolver().query(uri, new String[]{"name","money"}, null, null, null);
		if (cursor!=null) {

			while(cursor.moveToNext()){
				String name = cursor.getString(0);
				String money = cursor.getString(1);
				System.out.println("第二个应用:"+name+"---"+money);
			}
		}
	}

}
四、操作演示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值