android内容提供者contentProvider

来源:互联网 发布:复制文件 linux 编辑:程序博客网 时间:2024/06/04 17:39

一、基本概念

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

二、内容提供者使用步骤

(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 {@Overrideprotected 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 * 当数据库第一次 创建的时候调用 那么这个方法特别适合做 表结构的初始化  *  */@Overridepublic 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"});}@Overridepublic 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  变大写   小写加yprivate 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);}@Overridepublic boolean onCreate() {//[3]初始化 myopenHelpler 对象    就可以获取到sqlitedatabases对象 我们就可以操作数据库 myOpenHelper = new MyOpenHelper(getContext());System.out.println("我运行了……");return false;}@Overridepublic 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路径不匹配 请检测路径");}}@Overridepublic String getType(Uri uri) {return null;}@Overridepublic 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路径不匹配 请检测路径");}}@Overridepublic 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;}@Overridepublic 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 {@Overrideprotected 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] 创建uriUri 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);}}}}
四、操作演示

0 0
原创粉丝点击