赞
踩
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(); } }
运行结果:
这奏是两个程序之间的数据交换.
下面我们再来看看应用程序如何获取系统内部数据:
以联系人为例:
未完待续~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。