首页 > 代码库 > Android之ContentProvider

Android之ContentProvider

ContentProvider是Android的四大组件之一。

先说说我对这个东西的理解吧,ContentProvider就是用来存数据,用来共享数据的,比如:手机通讯录的联系人的信息以及手机上面存的相片,视频等等。

比较官方的解释:

Android中的Content provider机制可支持在多个应用中存储和读取数据。这也是跨应用共享数据的方式之一,还有文件,sharePreference,SQLite数据库等方式存储共享数据库,但是ContentProvider更好的提供了数据共享接口的统一性。在android系统中,没有一个公共的内存区域,供多个应用共享存储数据。

先写一个比较简单实用的例子吧!

获取通讯联系人的列表

1.需要在AndroidManifest.xml文件中允许读取联系人的信息

<uses-permission android:name="android.permission.READ_CONTACTS"/>

2.然后创建一个Activity直接读取信息就行。

package zf.ui;import java.util.ArrayList;import java.util.List;import zf.adapter.ContactItemListAdapter;import zf.entity.ContactEntity;import zf.ui.R;import android.app.Activity;import android.database.Cursor;import android.os.Bundle;import android.provider.ContactsContract;import android.util.Log;import android.widget.ListView;public class ContactsActivity extends Activity {	private ListView contactsList ;	private List<ContactEntity> list = new ArrayList<ContactEntity>();	@Override	protected void onCreate(Bundle savedInstanceState) {		// TODO Auto-generated method stub		super.onCreate(savedInstanceState);		setContentView(R.layout.contacts_activity);		contactsList = (ListView)findViewById(R.id.contacts_list);		// 需要读取的信息列表(包括通讯录的ID,通讯录对应的姓名以及电话号码)		String []projecttion = {				ContactsContract.CommonDataKinds.Phone.CONTACT_ID,				ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,				ContactsContract.CommonDataKinds.Phone.NUMBER		};		// 获取ContentResolver对象,ContentResolver对象主要是用来获取ContentProvider里面的内容以及修改ContentProvider里面的内容的		// 获取的信息,保存在Cursor中		Cursor cursor = getContentResolver().query(				ContactsContract.CommonDataKinds.Phone.CONTENT_URI,				projecttion,                null,                null,                null);		Log.d("zf",""+cursor.getCount());		String name="";		// 判断存在数据显示出来就显示出来		while(cursor.moveToNext()){			ContactEntity contact = new ContactEntity();			contact.setName(cursor.getString(1));			contact.setPhonenum(cursor.getString(2));			list.add(contact);		}		contactsList.setAdapter(new ContactItemListAdapter(ContactsActivity.this,list));	}	}

3.与之配套的还有还有一个填充数据的Adapter

package zf.adapter;import java.util.ArrayList;import java.util.List;import zf.entity.ContactEntity;import zf.ui.R;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;public class ContactItemListAdapter extends BaseAdapter {	// 联系人列表	private List<ContactEntity> contactlist = new ArrayList<ContactEntity>();	private Context mcontext;	private LayoutInflater mlayout;	public ContactItemListAdapter(Context context,List<ContactEntity> list){		this.mcontext = context;		mlayout = LayoutInflater.from(context);		this.contactlist = list;	}		@Override	public int getCount() {		// TODO Auto-generated method stub		return contactlist.size();	}	@Override	public Object getItem(int position) {		// TODO Auto-generated method stub		return contactlist.get(position);	}	@Override	public long getItemId(int position) {		// TODO Auto-generated method stub		return position;	}	@Override	public View getView(int position, View convertView, ViewGroup parent) {		// TODO Auto-generated method stub		ContactEntity contact = contactlist.get(position);		ViewHolder holder = null;		if(null == convertView){			convertView = mlayout.inflate(R.layout.contact_item, null);			holder = new ViewHolder();			holder.name = (TextView) convertView.findViewById(R.id.name);			holder.phonenum = (TextView) convertView.findViewById(R.id.num);			convertView.setTag(holder);		}		else{			holder = (ViewHolder) convertView.getTag();		}		holder.name.setText(contact.getName());		holder.phonenum.setText(contact.getPhonenum());		return convertView;	}		public class ViewHolder{		public TextView imei;		public TextView name;		public TextView phonenum;	}}

这里有的一个问题是为什么只有当联系人的姓名和手机号都填了才显示出来,否则不显示出来。

例子2:自己写一个ContentProvider可以供其他的应用调用里面的数据

1.创建自己的ContentProvider(自己理解的,开机以后系统就会自动的开启),需要继承ContentProvider,比重载里面的几个方法

package zf.provider;import android.content.ContentProvider;import android.content.ContentValues;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import android.net.Uri;public class MyProvider extends ContentProvider{	private static final String sqlCreatInfo = "CREATE TABLE IF NOT EXISTS myInfo(ID Integer PRIMARY KEY,NAME Text,AGE Integer);";	private SQLiteOpenHelper dataBaseOpenHelper;	@Override	public boolean onCreate() {		// TODO Auto-generated method stub		// 创建一个数据库表用来存数据		dataBaseOpenHelper = new SQLiteOpenHelper(this.getContext(), null, null, 1, null) {						@Override			public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {				// TODO Auto-generated method stub							}						@Override			public void onCreate(SQLiteDatabase db) {				// TODO Auto-generated method stub				db.execSQL(sqlCreatInfo);			}		};		return false;	}	@Override	public Cursor query(Uri uri, String[] projection, String selection,			String[] selectionArgs, String sortOrder) {		// TODO Auto-generated method stub		SQLiteDatabase database = dataBaseOpenHelper.getReadableDatabase();		return database.query("myInfo", projection, selection, selectionArgs, null, null, sortOrder);	}	@Override	public String getType(Uri uri) {		// TODO Auto-generated method stub		return null;	}	@Override	public Uri insert(Uri uri, ContentValues values) {		// TODO Auto-generated method stub		SQLiteDatabase database = dataBaseOpenHelper.getWritableDatabase();		String str = database.getPath();		database.insert("myInfo", "name", values);		return null;	}	@Override	public int delete(Uri uri, String selection, String[] selectionArgs) {		// TODO Auto-generated method stub		return 0;	}	@Override	public int update(Uri uri, ContentValues values, String selection,			String[] selectionArgs) {		// TODO Auto-generated method stub		return 0;	}}

2.在AndroidManifest里面注册(在application下面),好像只有exported属性为true,其他的应用才可以调用

<provider            android:name="zf.provider.MyProvider"            android:authorities="zf.provider.MyProvider"            android:exported="true" >        </provider>

3.创建另外一个应用,然后就可以调用了(调用的方法还是同上面的)

package zf.ui;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;  import android.util.Log;public class MainActivity extends Activity {	@Override	protected void onCreate(Bundle savedInstanceState) {		// TODO Auto-generated method stub		super.onCreate(savedInstanceState);		ContentResolver resolver =  getContentResolver();		Uri uri = Uri.parse("content://zf.provider.MyProvider/myInfo");		//添加一条记录		ContentValues values = new ContentValues();		values.put("ID", 1001);		values.put("NAME", "zf");		values.put("AGE", 18);		resolver.insert(uri, values);		Cursor cursor = resolver.query(uri, new String[]{"ID","NAME","AGE"}, null, null, null);		while(cursor.moveToNext()){			Log.d("zf", "" + cursor.getString(1));		}	}}

ContentProvider应该还有更多的应用,欢迎补充啊

Android之ContentProvider