赞
踩
ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要将自己的数据暴露给其他应用程序使用时,该应用程序就可以通过提供ContentProvider来实现,其他应用程序就可以通过ContentResolver来操作ContentProvider暴露的数据。
ContentProvider是Android四大组件之一,使用时候需要在AndroidManifest.xml中进行配置。
一旦某个应用程序通过ContentProvider暴露的自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可以通过该接口来操作该应用程序中的数据。包括增、删、改、查等。
ContentProvider以某种Uri的形式对外提供数据,运行其他应用程序访问或修改数据。其他应用程序使用ContentResolver根据Uri去访问操作指定数据。
实现步骤:1. 定义自己的ContentProvider类,需要继承Android提供的ContentProvider类。
2. 在Manifest中注册其。 需要指定 authorities 属性
如何暴露数据?除了需要集成ContentProvider类,还需要提供以下几个方法。
content://com.example.xyhq.provider/phone
它可以分为三部分:
1. content:// 这个是Android规定的,是固定格式
2. com.example.xyhq.provider 这就是ContentProvider中的 authorities属性,系统就是通过这个属性来找到操作哪个ContentProvider的
3. phone 数据部分,当访问者需要访问不同的资源时,这个部分是动态改变的。
content://com.example.xyhq.provider/phone/5 表示访问phone数据中,ID为5的记录
content://com.example.xyhq.provider/phone/5/name 表示访问phone数据中,ID为5的记录的name字段。
content://com.example.xyhq.provider/phones 访问全部数据
我们可以通过 Uri.parse() 将一个字符串转换为Uri
Context提供了 getContentResolver()方法来获取ContentResolver对象 ,获取到之后就可以调用ContentResolver中的各种方法。
Android系统为常用的数据类型提供了很多预定义的ContentProvider(声音、视频、图片、联系人等),他们大多位于android.provider 包中。Android提供的常用的ContentProvider有以下几种:
1. Browser 读取或修改书签、浏览历史或网络搜索
2. CallLog 查看或更新通话历史
3. Contacts 获取、修改或保存联系人信息
4. LiveFolders 由ContentProvider提供内容的特定文件夹
5. MediaStore 访问声音、视频,图片
6. Setting 查看和获取蓝牙设置,铃声 和 其他设备偏好。
7. SyncStateContract 用于使用数据数组账号关联数据的ContentProvider约束。希望使用标准方式保存数据的provider时可以使用。
8. UserDictionary 在可预测文本输入时,提供用户定义单词给输入法使用。应用程序和输入法能增加数据到该字典。单词能关联频率信息和本地化信息。
需要的权限:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
主Activity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button mButton1;
private ListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton1 = (Button) findViewById(R.id.btn1);
mButton1.setOnClickListener(this);
mListView = (ListView) findViewById(R.id.lv_test);
}
@Override
public void onClick(View view) {
searchUser();
}
/**
* 查询联系人
*/
private void searchUser() {
//定义两个list来放数据
ArrayList<String> names = new ArrayList<>();
ArrayList<String> phone = new ArrayList<>();
//获取Cursor
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (phones.moveToNext()) {
//拿到name 和电话号码
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String phonename = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
//如果是一个正常的手机号码,则添加到列表中
if (isMobileNO(phoneNumber)) {//如果是电话,则添加到list中。
phone.add(phoneNumber);
names.add(phonename);
}
}
phones.close();
MyAdapter adapter = new MyAdapter(this, names, phone);
mListView.setAdapter(adapter);
mButton1.setText("一共"+names.size()+"条");//size是从0开始,所以比通讯录显示的数量少
}
/**
* 验证手机格式
*/
public static boolean isMobileNO(String mobiles) {
/*
* 移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
* 联通:130、131、132、152、155、156、185、186 电信:133、153、180、189、(1349卫通)、177
* 总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9
*/
String telRegex = "[1][3578]\\d{9}";// "[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。
if (TextUtils.isEmpty(mobiles))
return false;
else
return mobiles.matches(telRegex);
}
}
适配器:
public class MyAdapter extends BaseAdapter {
ArrayList<String> names;
ArrayList<String> phone;
Context mContext;
public MyAdapter(Context mContent, ArrayList<String> names, ArrayList<String> phone) {
this.mContext = mContent;
this.names = names;
this.phone = phone;
}
@Override
public int getCount() {
return names.size();
}
@Override
public Object getItem(int i) {
return names.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
if (view == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
holder = new ViewHolder();
holder.tv_name = (TextView) view.findViewById(R.id.item_name);
holder.tv_phone = (TextView) view.findViewById(R.id.item_phone);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tv_name.setText(names.get(i));
holder.tv_phone.setText(phone.get(i));
return view;
}
class ViewHolder {
TextView tv_name;
TextView tv_phone;
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="test.yihan.testcontentprovicer.MainActivity">
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Hello World!" />
<ListView
android:layout_width="match_parent"
android:id="@+id/lv_test"
android:layout_height="match_parent"/>
</LinearLayout>
ListView小布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="10dp"
android:layout_height="match_parent">
<TextView
android:id="@+id/item_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/item_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Activity :
public class AddActivity extends AppCompatActivity {
private EditText mEtName;
private EditText mEtPhone;
private Button mSubmit;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
initViews();
}
private void initViews() {
mEtName = (EditText) findViewById(R.id.et_name);
mEtPhone = (EditText) findViewById(R.id.et_phone);
mSubmit = (Button) findViewById(R.id.btn_submit);
mSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name = mEtName.getText().toString();
String phone = mEtPhone.getText().toString();
//创建一个空的contentvalues
ContentValues values = new ContentValues();
//向rawContentUri 插入一个空值,获取返回的rawContactId
Uri rawContentUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContentUri);
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
//设置内容类型
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
//向联系人中插入name
getContentResolver().insert(ContactsContract.Data.CONTENT_URI,values);
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
//设置内容类型
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER,phone);
values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
getContentResolver().insert(ContactsContract.Data.CONTENT_URI,values);
Toast.makeText(AddActivity.this, "11", Toast.LENGTH_SHORT).show();
}
});
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="name" />
<EditText
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="phone" />
<Button
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="提交" />
</LinearLayout>
代码示例:>http://download.csdn.net/detail/qq_27561483/9632962
实现在输入框中输入内容自动匹配联系人:
主界面布局里面放一个AutoCompleteTextView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<AutoCompleteTextView
android:layout_width="match_parent"
android:id="@+id/auto_tv"
android:completionThreshold="1"
android:textColor="@android:color/holo_red_dark"
android:layout_height="50dp" />
</LinearLayout>
主界面代码里面:
public class MainActivity extends PermissionActivity {
private String [] columns = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, columns, null, null, null);
ContactListAdapter adapter = new ContactListAdapter(this,cursor);
AutoCompleteTextView mTv = (AutoCompleteTextView) findViewById(R.id.auto_tv);
mTv.setAdapter(adapter);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
适配器:
public class ContactListAdapter extends CursorAdapter implements Filterable {
private ContentResolver resolver;
private String[] columns = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
public ContactListAdapter(Context context, Cursor c) {
super(context, c);
resolver = context.getContentResolver();
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
LayoutInflater inflater = LayoutInflater.from(context);
TextView view = (TextView) inflater.inflate(android.R.layout.simple_dropdown_item_1line, viewGroup, false);
view.setText(cursor.getString(1));
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView) view).setText(cursor.getString(1));
}
@Override
public CharSequence convertToString(Cursor cursor) {
return cursor.getString(1);
}
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
FilterQueryProvider filterQueryProvider = getFilterQueryProvider();
if (filterQueryProvider != null) {
return filterQueryProvider.runQuery(constraint);
}
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode(constraint.toString()));
return resolver.query(uri, columns, null, null, null);
}
}
最后就是要注意的权限问题了
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
放上demo:http://download.csdn.net/detail/qq_27561483/9633185
实现自己的ContentProvider:http://blog.csdn.net/wangkuifeng0118/article/details/7028953
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。