Android-数据存储(Content Provider 跨应用调用数据范例)

Android-数据存储(Content Provider 跨应用调用数据实例)

1.回顾

  上篇 数据存储篇 已经学习完了,Android的数据存储 包括 SharedPrefence , SQLite  , 文件存储 ,Content Provider ; 而还有一种 是存储在网络上 就不说了;

  之前 写了一个 调用 通信录 ,获得 用户联系人的 例子 ,使用 Content Provider 实现;


2. 重点

  (1)复习 Content Provider 

  (2)Content Provider 实现 权限 解释

  (3)调用演示实例


3. 复习

   (1)ContentProvider 实现 通过 Uri 实现 对 数据的增删改查;

   (2)可以跨应用 调用数据;

   (3)ContentProvider 通过 ContentResolver 实现 增删改查,两个类对应的 方法包括参数一模一样;

  (4)ContentProvider 在 生成数据App端封装,后在 Androidmianfest.xml 中注册(包括权限设置);

  (5)ContentResolver 在 请求数据的App中封装,后通过 生成数据App端提供的Uri地址 实现 增删改查数据操作;


4. ContentProvider 权限解释

    声明:AppProvider:代表 生成数据App端 (数据提供端);AppResovler :代表 请求数据 App端

     4.1 权限解释

  <provider 
            android:name="com.example.sqlite.TContentProvider" 
            android:authorities="com.example.sqlite"
            android:exported="true"
            />

      (1)在 Androidmianfest.xml 文件下的 的 Application 标签中添加 provider 标签

<Application 
             ....>
         ....  
        <provider ...... />
</Application>
      (2)一般情况下,包含必须的三个属性

                  name : 为  自定义 ContentProvider 类 的包名(在 AppProvider 应用中 ,继承 ContentProvider

           authorities :为  这个 ContentProvider 的 uri 地址 ;

              exported : 为 是否可以其他应用所访问,默认不写为 false , true 是可以访问;
           

         有这三个 就已经可以实现 数据共享了 ;

    

    4.2 权限提升

              前三个属性 和上面一样,下面是 又多的三个属性

    <provider 
            android:name="com.example.sqlite.TContentProvider" 
            android:authorities="com.example.sqlite"
            android:exported="true"
            android:permission="com.example.sqlitedemo"
            android:readPermission="com.example.sqlite.read"
            android:writePermission="com.example.sqlite.write"
            />

             

             4.2.1  permission 

                          给应用 注册 和  提供访问的读写权限 ; 

                      (1) AppProvider 应用 声明权限 在与 Application 的同级标签下声明:

                            这里的 name值 和 上面 permission 值一样!!

 <permission 
        android:name="com.example.sqlitedemo"
        android:label="content provider read"
        android:protectionLevel="normal"
        ></permission>
      

                     ( 2) AppResovler 应用 实现数据请求 ,必须在 自己的 Androidmianfest.xml文件中,声明:

                            这里的 name 也和 permission 值一样 !!!和 Application 标签同级 ;

  <uses-permission android:name="com.example.sqlitedemo"/>

              4.2.2 readPermission 和 writePermission 

                    (1)Permission可以同时实现 读写权限 ;

                    (2)readPermission 只实现 读 权限 ,没有写入权限;

                    (3)writePermission 只实现 写入权限 ,没有实现 读取权限;

                    (4)当同时出现的时候,readPermission 和 writePermission的权限 优先级 比 Permission优先级高;

                    (5)readPermission和writePermission的 权限注册方法 和 Permission一样;

                    (6)例子 (readPermission 和 permission 的权限优先级):


AppProvider 应用配置实现:


  <provider 
            android:name="com.example.sqlite.TContentProvider" 
            android:authorities="com.example.sqlite"
            android:exported="true"
            android:permission="com.example.sqlitedemo"
            android:readPermission="com.example.sqlite.read"

            />

   permission 和 readPermission 注册权限 如下:

 <permission 
        android:name="com.example.sqlite.read"
        android:label="content provider read"
        android:protectionLevel="normal"
        ></permission>
    
     <permission 
        android:name="com.example.sqlitedemo"
        android:label="content provider read write"
        android:protectionLevel="normal"
        ></permission>

AppResovler  请求端 添加下面权限 ,会报错 ,因为permission 优先级低:

  <uses-permission android:name="com.example.sqlitedemo"/>

   但是 使用 readPermission的权限 就行了;

 <uses-permission android:name="com.example.sqlite.read"/>


                (7)当 同时出现 writePermission和 readPermission的时候,permission 属性 就会失效了,没有用了;


5.实例- 实现 SQLite数据共享

      当然和上面一样 一个 数据提供者 AppProvider  ,一个数据请求者 AppResovler  

      5.1 AppProvider 实现

        (1)实现 SQLiteOpenHelper 创建 数据库和表 ,并初始化 数据 ;

package com.example.sqlite;

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

public class DB extends SQLiteOpenHelper {

	public DB(Context context, String name) {
		
		super(context, name, null, 1);
	}

	/**
	 * 首次创建 数据库的时候调用
	 * 一般 把建库 和 键表操作 放在这里
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		// 一般 把建库 和 键表操作 放在这里
		
		db.execSQL("create table if not exists labelnet(_id integer primary key autoincrement,name text not null,pass text not null)");
        
		//初始化 20 个值
		ContentValues values=new ContentValues();
		for(int i=0;i<20;i++){
        	values.put("name","yuanmingzhuo"+i);
        	values.put("pass","hpu"+i);
        	db.insert("labelnet",null, values);
        	values.clear();
        }
	}

	/**
	 * 当数据库版本发送改名的时候,自动调用
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //当数据库版本发送改名的时候,自动调用
		
	}
	
	
	

}


        (2)实现 ContentProvider ,实现 查询方法 ;

package com.example.sqlite;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class TContentProvider extends ContentProvider {

	private SQLiteDatabase db;
	
	@Override
	public boolean onCreate() {
		//在 ContentProvider 被创建 后 调用
		
		/**
		 * 通过SQLiteOpenHelper 调用创建SQLiteDatabase对象
		 */
		DB d=new DB(this.getContext(),"yuan.db");
		db=d.getWritableDatabase();
		
		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// 根据 uri 查询 指定的 selection 条件的数据,并 可以指定 那些列和排序
		
		//执行查询操作
		
		/**
		 * 数据库表 : labelnet ,全部数据
		 */
		Cursor cursor=db.query("labelnet",null,null,null,null,null,null);
		
		/**
		 * 返回出游标对象
		 */
		return cursor;
	}

	@Override
	public String getType(Uri uri) {
		// 返回 但却 uri的 MIME 类型 , 如果 URI对应得 数据 可能包括 多条记录 ,那么MIME类型 字符串 以vnd.android.dir/开头
		 //如果只有一条 那么该 MIME 类型数据 以 vnd.android.cursor.item/ 开头
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// 根据 uri 插入 values 数据
		return null;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// 根据 uri 删除 selection 对象的 数据
		return 0;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// 根据 uri 修改 数据
		return 0;
	}

}


        (3)注册 ContentProvider ,添加 读权限,提供 uri地址;

        <!-- 注册 Provider  -->
        <provider 
            android:name="com.example.sqlite.TContentProvider" 
            android:authorities="com.example.sqlite"
            android:exported="true"
            android:permission="com.example.sqlitedemo"
            android:readPermission="com.example.sqlite.read"
            />


        (4)MainActivity 测试 读取数据 作为对比


     5.2 AppResovler  实现

         (1)通过 ContentResolver 和 uri地址 ,调用 刚刚 的查询 方法;

// 通过 ContentResolver 实现 操作 另一个应用 ContentProvider
			ContentResolver resolver = MainActivity.this.getContentResolver();
			Uri uri = Uri.parse("content://com.example.sqlite");

			// 调用查询方法(刚刚 已经在 SqliteDemo应用中)
			Cursor cursor = resolver.query(uri, null, null, null, null);

         (2)显示在Listview 中, 作为 对比数据 



6.demo 下载

http://download.****.net/detail/lablenet/9055853



   谢谢阅读!给个建议吧!Android-数据存储(Content Provider 跨应用调用数据范例)


版权声明:本文为博主原创文章,未经博主允许不得转载。