Android四大组件之ConentProvider.

Android中的四大组件有一个叫做ContentProvider的东西,这货是用来干什么的呢?

下面听小弟给你细细道来:

基本介绍:

           Android中有四大组件分别是Activity,ContentProvider,Service,BroadcastReceiver,它们都需要在AndroidManifest.xml文件中进行配置.

           ContentProvider组件主要用于Android系统中应用程序之间交换数据,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过ContentProvider来实现;其他应用程序就可以通过ContentResolver来操作ContentProvider暴露的数据.

           当一个应用程序通过ContentProvider暴露了自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可以通过该接口操作该应用程序内部的数据,包括增加,删除,修改,查询数据等.

大概思路:

            

ContentProvider以某种Uri的形式对外提供数据,允许其他应用访问或修改数据;其他应用程序使用ContentResolver根据Uri去访问操作指定数据;

开发ContentProvider步骤:

         1.定义自己的ContentProvider类,该类需要继承Android提供的ContentProvider基类.

         2.向Android系统注册这个ContentProvider,也就是在AndroidManifest.xml文件中注册这个ContentProvider,就和注册Activity一样,注册ContentProvider时需要为它绑定一个Uri;

         注:向Android中注册ContentProvider,只需在AndroidManifest.xml配置文件中<application.../>元素下添加如下子元素即可:

 

<!- -下面配置中name属性指定为ContentProvider类,
       authorities就相当于为该ContentProvider指定域名,exported设置为true就是允许其他应用访问该应用内部
- ->
<provider
          android:name="com.xiyou.MProvider"
          android:authorities="com.xiyou.provider.mprovider"
          android:exported="true"/>

 通过注册上面的provider别的应用就可以通过这个Uri访问MProvider所暴露的数据.

 

 继承ContentProvider的这个MProvider类通常要提供以下几种方法,以让外部应用访问:

                 public boolean onCreate():该方法在ContentProvider创建后会被调用,当其他应用程序第一次访问ContentProvider,该ContentProvider会被创建出来,并立即回调该onCreate()方法.

                 public Uri insert(Uri uri,  ContentValues values):根据该Uri插入values对应的数据.

                 public int delete(Uri uri, String selection, String[] selectionArgs):根据Uri删除select条件所匹配的全部数据.

                 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):根据Uri修改select条件所匹配的全部记录.

                 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):根据Uri查询出select条件所匹配的全部记录,其中projection就是一个列名列表,表明只选择出指定的数据列. 

                 public String getType(Uri uri):该方法用于返回当前Uri所代表的数据的MIME类型.如果该Uri对应数据可能包括多条记录,那么MIME类型字符串应该以vnd.android.cursor.dir/开头;如果该Uri对应的数据只包含一条记录,那么返回MIME类型字符串应该以vnd.android.cursor.item/开头.

 

从每一个方法的参数中我们可以看出Uri是一个非常重要的参数,那么下面我们来了解了解Uri:

 

                我们先来给出一个简单的URL:http://www.xiyou.edu.cn/test.php

                分解开来看:

                http://:URL的协议部分;只要通过HTTP协议访问网站,这个部分是固定的.

                www.xiyou.edu.cn:域名部分.只要访问指定的网站,这个部分总是固定的.

                test.php:网站资源部分.当访问者需要访问不同资源时,这个部分根据资源的不同而改变.

 

                ContentProvider要求的Uri与此类似,例如如下Uri:content://com.xiyou.provider.mprovider/test

                分解开来看:

                content://:此部分是Android的ContentProvider规定的,就想网上的协议默认是http://一样.暴露ContentProvider,访问ContentProvider的协议默认是content://.

                com.xiyou.provider.mprovider:这个部分是就是ContentProvider的authority.系统就是由这个部分来找到操作哪个ContentProvider只要访问指定的ContentProvider,这个部分总是固定的.

                test:资源部分,当访问者需要访问不同的资源时,这个部分是动态改变的 

 

使用ContentResolver操作数据如下方法:

               通过getContentResolver()方法获取ContentResolver对象,获得ContentResolver对象后通过调用ContentResolver的如下方法操作ContentProvider中的数据.

               insert(Uri uri, ContentValues values):向对应的ContentProvider中插入values对应的数据.

               delete(Uri uri, String where, String[] selectionArgs):删除Uri对应的ContentProvider中where提交匹配的数据.

               update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri对应的ContentProvider中where提交匹配的数据.

               query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder):查询Uri对应的ContentProvider中select提交的匹配的数据.

               

                    ContentProvider,Uri,COntentResolver三者之间有着某些关系:

                    

     下面开发一个ContentProvider和ContentResolver的例子来给大家看看:

     ContentProvider程序:

     

package com.example.firstprovider;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.view.Menu;

public class MainActivity extends ContentProvider {

	// 第一次创建该ContentProvider时调用该方法
	@Override
	public boolean onCreate() {

		System.out.println("==onCreate()方法被调用==");

		return true;
	}

	// 实现查询方法,该方法应该返回查询得到的Cursor
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		System.out.println(uri + "==query()方法被调用==");
		System.out.println("selection参数为:" + selection);

		return null;
	}

	// 该方法的返回值代表了该ContentProvider所提供的数据的MIME类型.
	@Override
	public String getType(Uri uri) {
		return null;
	}

	// 实现插入的方法,该方法应该返回新插入的记录的Uri
	@Override
	public Uri insert(Uri uri, ContentValues values) {

		System.out.println(uri + "==insert()方法被调用==");
		System.out.println("values参数为:" + values);
		return null;
	}

	// 实现删除方法,该方法应该返回被更新的记录条数
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {

		System.out.println(uri + "==deletet()方法被调用==");
		System.out.println("selection参数为:" + selection);

		return 0;
	}

	// 实现更新方法,该方法应该返回被更新的记录条数
	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {

		System.out.println(uri + "==update()方法被调用==");
		System.out
				.println("selection参数为:" + selection + ",values参数为:" + values);
		return 0;
	}

}

 

 

 

ContentProvider程序的AndroidManifest.xml

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.firstprovider"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.firstprovider.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=".MainActivity"
            android:authorities="com.xiyou.provider.firstprovider"
            android:exported="true"
            ></provider>
    </application>

</manifest>

 

 

 

 

 

ContentResolver程序:

布局代码中只有四个button所以未给出:

 

package com.example.firstresolver;

import android.net.Uri;
import android.os.Bundle;
import android.R.integer;
import android.app.Activity;
import android.app.DownloadManager.Query;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

	Button query, insert, update, delete;
	Uri uri = Uri.parse("content://com.xiyou.provider.firstprovider/");
	ContentResolver contentResolver;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		contentResolver = this.getContentResolver();
		query = (Button) findViewById(R.id.query);
		update = (Button) findViewById(R.id.update);
		insert = (Button) findViewById(R.id.insert);
		delete = (Button) findViewById(R.id.delete);
		query.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				query(v);
			}
		});
		insert.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				insert(v);
			}
		});
		delete.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				delete(v);
			}
		});
		update.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				update(v);
			}
		});

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public void query(View source) {
		// 调用ContentResolver的query()方法
		// 实际返回的是该Uri对应的ContentProvider的query()的返回值
		Cursor c = contentResolver.query(uri, null, "query_where", null, null);
		Toast.makeText(this, "远程ContentProvider返回的Cursor为:" + c,
				Toast.LENGTH_SHORT).show();
	}

	public void insert(View source) {
		ContentValues contentValues = new ContentValues();
		contentValues.put("name", "xiyoucx");
		// 调用ContentResolver的insert()方法
		// 实际返回的是该Uri对应ContentProvider的insert()方法返回值
		Uri newUri = contentResolver.insert(uri, contentValues);
		Toast.makeText(this, "远程ContentProvider返回的新插入记录的Uri为:" + newUri,
				Toast.LENGTH_SHORT).show();
	}

	public void update(View source) {
		ContentValues contentValues = new ContentValues();
		contentValues.put("name", "xiyoucx");
		// 调用ContentResolver的update()方法
		// 实际返回的是该Uri对应的contentp的update()返回值
		int count = contentResolver.update(uri, contentValues, "update_values",
				null);
		Toast.makeText(this, "远程ContentProvider返回的新插入记录数为:" + count,
				Toast.LENGTH_SHORT).show();
	}

	public void delete(View source) {
		// 调用ContentResolver的delete()方法
		// 实际返回的是该Uri对应的contentp的delete()的返回值
		int count = contentResolver.delete(uri, "delete_where", null);
		Toast.makeText(this, "远程ContentProvider返回的删除记录数为:" + count,
				Toast.LENGTH_SHORT).show();
	}

}


运行结果:

 

 

这奏是两个程序之间的数据交换.

 

下面我们再来看看应用程序如何获取系统内部数据:

以联系人为例:

 

               未完待续~~

               

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值