ContentProvider是一个对外发布数据库操作的接口。
普通的SQLite数据库里面的数据库操作,只有当前应用程序自己的可以调用,其他程序无法调用。
如果想让其他程序来调用你的数据库,就需要自己为数据库建立一个ContentProvider,同时其他程序可以通过ContentResolver来调用Provider里封装好的方法。
自己在实际开发中不会编写ContentProvider,主要是编写resolver操作,来调用系统写好的Provider,相当于调用系统的数据库,完成自己需要的功能。
例如:
读取系统数据库中的联系人信息,通话日志,SD卡中所有的音频文件目录,视频文件目录,图片目录。
读取通讯录,通话记录等别忘记获取权限
activity代码clear注意清空本身还有等于该变量的其他变量,所以用=null,但是问题出现了adapter.notifyDataSetChanged();可以更改界面,但是现在指针指向的数据位置发生改变,修改了值但不是原先位置上的值,所以得adapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,allValues);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
package com.kane.contentrrsolver;
import java.util.ArrayList;
import java.util.List;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.Toast;
/**
* 查询通讯录和拨打电话都需要权限
* @author lenovo
*
*/
public class MainActivity extends Activity {
private ListView listView;
private Button contactBtn,callLogBtn;
private ArrayAdapter<String> adapter;//这里显示通讯录,无所谓样式,。用最简单的
private List<String> allValues=new ArrayList<String>();
private List<String> allPhoneNos=new ArrayList<String>();
private List<String> allValues2=new ArrayList<String>();
private List<String> allPhoneNos2=new ArrayList<String>();
List<String> allValues1=allValues;
List<String> allPhoneNos1=allPhoneNos;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView)findViewById(R.id.list);
contactBtn=(Button)findViewById(R.id.my_contact);
callLogBtn=(Button)findViewById(R.id.my_call_log);
ContentResolver resolver=getContentResolver();
//读取数据,这里完全查询,不用条件
Cursor c=resolver.query(Contacts.CONTENT_URI, null, null, null, null);
c.moveToFirst();
while (!c.isAfterLast()) {
StringBuilder builder=new StringBuilder();
//加入通讯录姓名
builder.append(c.getString(c.getColumnIndex(Contacts.DISPLAY_NAME)));
//取得通讯录联系人的id,为了遍历获得手机号,一个人可能对应多个手机号
String contactid=c.getString(c.getColumnIndex(Contacts._ID));
//查出关联的电话号码,这里是条件查询
Cursor c2=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, Phone.CONTACT_ID+" = ?", new String[] {contactid},null);
builder.append("---->");
String number="";
c2.moveToFirst();
while (!c2.isAfterLast()){
builder.append(c2.getString(c2.getColumnIndex(Phone.NUMBER))+",");
//记录循环中的最后一个电话
number=c2.getString(c2.getColumnIndex(Phone.NUMBER));
c2.moveToNext();
}
c2.close();
allPhoneNos.add(number);
allValues.add(builder.toString());
c.moveToNext();
}
c.close();
//读取通话记录
Cursor c3=getContentResolver().query(CallLog.Calls.CONTENT_URI,null,null,null,null);
c3.moveToFirst();
while (!c3.isAfterLast()) {
c3.moveToNext();
StringBuilder builder2=new StringBuilder();
//加入姓名
String name=c3.getString(c3.getColumnIndex(CallLog.Calls.CACHED_NAME));
if (name==null||name.equals("")) {
name="unKnown";
}
builder2.append(name+"---->");
String number2 = c3.getString(c3.getColumnIndex(Calls.NUMBER));
builder2.append(number2);
builder2.append("---->");
int type=c3.getInt(c3.getColumnIndex(Calls.TYPE));
String typename="";
switch (type) {
case Calls.INCOMING_TYPE:
typename="已接电话";
break;
case Calls.OUTGOING_TYPE:
typename="已拨电话";
break;
case Calls.MISSED_TYPE:
typename="未接电话";
break;
}
builder2.append(typename);
allPhoneNos2.add(number2);
allValues2.add(builder2.toString());
c3.moveToNext();
}
c3.close();
allValues1=allValues;
allPhoneNos1=allPhoneNos;
adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,allValues);
listView.setAdapter(adapter);
//可以加入对某一项的监听,拨打电话
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// 取得当前点击的号码
String num=allPhoneNos.get(arg2);
//切换到拨打电话的界面
Intent intent=new Intent();
//设置要切换的系统动作
intent.setAction(Intent.ACTION_CALL);
//设置拨打电话的格式一定要是“tel:”
intent.setData(Uri.parse("tel:"+num));
startActivity(intent);
}
});
//allValues,allPhoneNos为带入的公共值,每次点击都发生变化
callLogBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
allValues=null;
allValues=allValues2;
allPhoneNos=null;
allPhoneNos=allPhoneNos2;
adapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,allValues);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
contactBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
allValues=null;
allValues=allValues1;
allPhoneNos=null;
allPhoneNos=allPhoneNos1;
adapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,allValues);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
}
}
界面代码
<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" >
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9" >
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >
<Button
android:id="@+id/my_contact"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="通讯录" />
<Button
android:id="@+id/my_call_log"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="通话记录" />
</LinearLayout>
</LinearLayout>