zoukankan      html  css  js  c++  java
  • Android -- ContentProvider 内容提供者,创建和调用

    1. 概述

    ContentProvider android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。关于数据共享,以前我们学习过文件操作模式,知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE Context.MODE_WORLD_WRITEABLE同样也可以对外共享数据。那么,这里为何要使用ContentProvider 对外共享数据呢?是这样的,如果采用文件操作模式对外共享数据,数据的访问方式会因数据存储的方式而不同,导致数据的访问方式无法统一,如:采用xml文件对外共享数据,需要进行xml解析才能读取数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读取数据。

    使用ContentProvider对外共享数据的好处是统一了数据的访问方式

    当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:

    public class PersonContentProvider extends ContentProvider{

       public boolean onCreate()

       public Uri insert(Uri uri, ContentValues values)

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

       public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

       public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

       public String getType(Uri uri)}

    第二步需要在AndroidManifest.xml使用<provider>对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:

    <!--需要设定权限exported="true",其他程序可以调用-->
            <provider
                android:name="com.itheima.note.provider.NoteInfoProvider"
                android:authorities="com.itheima.note.noteprovider"
                android:exported="true">
      </provider>

    ContentProvider类主要方法的作用:

    public boolean onCreate()

    该方法在ContentProvider创建后就会被调用, Android开机后, ContentProvider在其它应用第一次访问它时才会被创建。

    public Uri insert(Uri uri, ContentValues values)

    该方法用于供外部应用往ContentProvider添加数据。

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

    该方法用于供外部应用从ContentProvider删除数据。

    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

    该方法用于供外部应用更新ContentProvider中的数据。

    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

    该方法用于供外部应用从ContentProvider中获取数据。

    public String getType(Uri uri)

    该方法用于返回当前Url所代表数据的MIME类型。如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:要得到所有person记录的Uricontent://cn.itcast.provider.personprovider/person,那么返回的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id10person记录,Uricontent://cn.itcast.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”

    当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:

    public Uri insert(Uri uri, ContentValues values)

    该方法用于往ContentProvider添加数据。

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

    该方法用于从ContentProvider删除数据。

    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

    该方法用于更新ContentProvider中的数据。

    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

    该方法用于从ContentProvider中获取数据。

    这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,假设给定的是:Uri.parse(“content://cn.itcast.providers.personprovider/person/10”),那么将会对主机名为cn.itcast.providers.personproviderContentProvider进行操作,操作的数据为person表中id10的记录。

    2. 示例代码

    ContentProvider的建立, 在上篇SQLite的创建的基础上,

    NoteInfoProvider.java, 建立 需要继承ContentProvider

    public class NoteInfoProvider extends ContentProvider {
    
    	private static final int QUERY = 1;
    	private static final int INSERT = 2;
    	private static final int DELETE = 3;
    	private static final int UPDATE = 4;
    
    	// 参数code 代表如果uri不匹配的返回值
    	// 在当前应用程序的内部 声明一个路径的检查者
    	private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    	private SQLiteDatabase db;
    
    	static {
    		// 建立一个匹配规则
    		// 1.如果发现一个路径 com.itheima.note.noteprovider/query 查询的操作
    		matcher.addURI("com.itheima.note.noteprovider", "query", QUERY);
    		matcher.addURI("com.itheima.note.noteprovider", "insert", INSERT);
    		matcher.addURI("com.itheima.note.noteprovider", "delete", DELETE);
    		matcher.addURI("com.itheima.note.noteprovider", "update", UPDATE);
    	}
    
    	@Override
    	public boolean onCreate() {
    		NoteSQLiteOpenHelper helper = new NoteSQLiteOpenHelper(getContext());
    		db = helper.getWritableDatabase();
    		return false;
    	}
    
    	/**
    	 * 内容提供者暴露的查询的方法.
    	 */
    	@Override
    	public Cursor query(Uri uri, String[] projection, String selection,
    			String[] selectionArgs, String sortOrder) {
    		// 1.重要的事情 ,检查 uri的路径.
    		int code = matcher.match(uri);
    		if (code == QUERY) {
    			// 查询处理
    			NoteSQLiteOpenHelper helper = new NoteSQLiteOpenHelper(getContext());
    			SQLiteDatabase db = helper.getReadableDatabase();
    			Cursor cursor = db.rawQuery("select * from account", null);
    			//不要手动去关闭close db
    			return cursor;
    		} else {
    			throw new IllegalArgumentException("路径不能被识别,我不认识你...");
    		}
    	}
    
    	//MIME 类型
    	@Override
    	public String getType(Uri uri) {
    		int code = matcher.match(uri);
    		if (code == QUERY) {
    			//返回一条数据
    			return "vnd.android.cursor.item/note";
    			//返回多条数据
    			//return "vnd.android.cursor.dir/note"
    		}
    	
    		
    		return null;
    	}
    
    	@Override
    	public Uri insert(Uri uri, ContentValues values) {
    		int code = matcher.match(uri);
    		if (code == INSERT) {
    			db.insert("account", null, values);
    		} else {
    			throw new IllegalArgumentException("路径不能被识别,我不认识你...");
    		}
    
    		return null;
    	}
    
    	@Override
    	public int delete(Uri uri, String selection, String[] selectionArgs) {
    		int code = matcher.match(uri);
    		if (code == DELETE) {
    			db.delete("account", selection, selectionArgs);
    		} else {
    			throw new IllegalArgumentException("路径不能被识别,我不认识你...");
    		}
    
    		return 0;
    	}
    
    	@Override
    	public int update(Uri uri, ContentValues values, String selection,
    			String[] selectionArgs) {
    		int code = matcher.match(uri);
    		if (code == UPDATE) {
    			db.update("account", values, selection, selectionArgs);
    		} else {
    			throw new IllegalArgumentException("路径不能被识别,我不认识你...");
    		}
    		return 0;
    	}
    
    }

    AndroidManifest.xml, 需要配置provider 和 给权限

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.itheima.note"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <instrumentation
            android:name="android.test.InstrumentationTestRunner"
            android:targetPackage="com.itheima.note" />
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <uses-library android:name="android.test.runner" />
    
            <activity
                android:name="com.itheima.note.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>
    
    		<!--需要设定权限exported="true",其他程序可以调用-->
            <provider
                android:name="com.itheima.note.provider.NoteInfoProvider"
                android:authorities="com.itheima.note.noteprovider"
    			android:exported="true">
    		</provider>
            
            
        </application>
    
    </manifest>

    MainActivity.java  其他App调用 内容提供者, 增删改查数据

    public class MainActivity extends Activity {
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    	
    	}
    	public void query(View view){
    		//得到内容提供者的解析器  中间人
    		ContentResolver resolver = getContentResolver();
    		Uri uri = Uri.parse("content://com.itheima.note.noteprovider/query");
    		Cursor cursor = resolver.query(uri, null, null, null, null);
    		while(cursor.moveToNext()){
    			String name = cursor.getString(cursor.getColumnIndex("name"));
    			int id = cursor.getInt(cursor.getColumnIndex("id"));
    			float money = cursor.getFloat(cursor.getColumnIndex("money"));
    			System.out.println("id="+id+",name="+name+",money="+money);
    		}
    		cursor.close();
    	}
    	public void insert(View view){
    		ContentResolver resolver = getContentResolver();
    		Uri uri = Uri.parse("content://com.itheima.note.noteprovider/insert");
    		ContentValues values = new ContentValues();
    		values.put("name", "买洗头膏");
    		values.put("money", 22.58f);
    		resolver.insert(uri, values);
    	}
    	public void update(View view){
    		ContentResolver resolver = getContentResolver();
    		Uri uri = Uri.parse("content://com.itheima.note.noteprovider/update");
    		ContentValues values = new ContentValues();
    		values.put("name", "买洗头膏");
    		values.put("money", 42.58f);
    		resolver.update(uri, values, "name=?", new String[]{"买洗头膏"});
    	}
    	public void delete(View view){
    		ContentResolver resolver = getContentResolver();
    		Uri uri = Uri.parse("content://com.itheima.note.noteprovider/delete");
    		resolver.delete(uri, "name=?", new String[]{"买洗头膏"});
    	}
    }
    



     

  • 相关阅读:
    IntelliJ IDEA 最新注册码
    tidyverse|数据分析常规操作-分组汇总(sumamrise+group_by)
    ComplexHeatmap|根据excel表绘制突变景观图(oncoplot)
    Tidyverse| XX_join :多个数据表(文件)之间的各种连接
    LDheatmap | SNP连锁不平衡图(LD)可视化,自己数据实现版!
    Tidyverse|数据列的分分合合,爱恨情仇
    R-ggpmisc|回归曲线添加回归方程,R2,方差表,香不香?
    R-rbind.fill|列数不一致的多个数据集“智能”合并,Get!
    R|tableone 快速绘制文章“表一”-基线特征三线表
    R|生存分析
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3647982.html
Copyright © 2011-2022 走看看