public class Main3Activity extends AppCompatActivity {
// step2:提供要解析数据对应的Uri,就是电话记录的uri
private Uri uri_callLog = CallLog.Calls.CONTENT_URI;// 系统提供的常量,表示通话记录对外暴露的Uri
// 上面常量的值就是 Uri.parse("content://call_log/calls")得到的结果.
private ContentResolver contentResolver;
private ListView lv_listview;
private MyCursorAdapter adapter;// 自定义的适配器类对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
lv_listview = (ListView) findViewById(R.id.lv_listview);
// step1:获取ContentResolver
contentResolver = getContentResolver();
queryCallLog();// 调用自定义的方法,用于查询并显示通话记录
// 注册 上下文菜单:可以删除某个通话记录
registerForContextMenu(lv_listview);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.call_menu, menu);// 上下文菜单,只有一个"删除"选项
}
// 上下文菜单点击时间处理
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = menuInfo.position;// 获得弹出上下文菜单时所选中的条目的位置
Cursor cursor = adapter.getCursor();// 调用CursorAdapter的获取cursor对象的方法
cursor.moveToPosition(position);// 把cursor作为数据源,移动到指定位置
int id = cursor.getInt(cursor.getColumnIndex("_id"));// 通话记录表calls中的字段
switch (item.getItemId()) {
case R.id.action_delete:
// 删除一条记录
int count = deleteCallLog(id);// 调用自定义的删除通话记录的方法
if (count > 0) {
Toast.makeText(Main3Activity.this, "删除成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(Main3Activity.this, "删除失败", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
queryCallLog();// 调用自定义的重新查询的方法
return super.onContextItemSelected(item);
}
/**
* 删除一条指定的通话记录
*
* @param id
* @return
*/
public int deleteCallLog(int id) {
int count = contentResolver.delete(uri_callLog, "_id=?", new String[]{id + ""});// 也可以第二个参数传"_id="+id,第三参数传null
return count;
}
/**
* 通过contentResolver,查询uri所指向的通话记录数据
* 第一个参数:要操作的应用暴露出的uri。指向通话记录的数据
* 第二个参数:要查询的字段
* 第三个参数:查询的条件
* 第四个参数:条件的参数值
* 第五个参数:排序
*/
// 查询数据
public void queryCallLog() {
// step3:通过contentResolver获取数据
//Uri uri,String[] projection列名数组,String selection查询条件,String[] selectionArgs替换占位符的数组,String sortOrder
Cursor cursor = contentResolver.query(uri_callLog, new String[]{"_id", "number", "date", "type"}, null, null, "date desc");
// SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
// R.layout.item_listview, cursor, new String[] { "_id", "number",
// "date", "type" }, new int[] { R.id.tv_id,
// R.id.tv_number, R.id.tv_date, R.id.tv_type },
// CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);//这样填进去日期就只能显示成毫秒数了,不美观
// 因此可以使用继承CursorAdapter的自定义适配器来适配Cursor数据
// 父类CursorAdapter没有无参的构造方法,必须如此传参:
adapter = new MyCursorAdapter(this, cursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); // 最后一个参数表示,如果数据源发生变化则在后面学习的Loader中可以动态更新.
lv_listview.setAdapter(adapter);
}
// 自定义的继承抽象类CursorAdapter的适配器
class MyCursorAdapter extends CursorAdapter {
// 继承抽象类,重写两个抽象方法
public MyCursorAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);// 父类没有无参的构造方法,必须如此传参
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// 指定布局文件,生成一个条目的View对象,注意,在内部类中,上下文是MainActivity.this
return LayoutInflater.from(Main3Activity.this).inflate(R.layout.item_listview, null);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// 填充数据到每个条目的内部组件上,类似于继承BaseAdapter中重写getView()方法
TextView tv_id = (TextView) view.findViewById(R.id.tv_id);
TextView tv_number = (TextView) view.findViewById(R.id.tv_number);
TextView tv_date = (TextView) view.findViewById(R.id.tv_date);
TextView tv_type = (TextView) view.findViewById(R.id.tv_type);
// 从cursor获取数据,显示到textview上
tv_id.setText("" + cursor.getInt(cursor.getColumnIndex("_id")));
tv_number.setText(cursor.getString(cursor.getColumnIndex("number")));
long dateNum = cursor.getLong(cursor.getColumnIndex("date"));// 获取以毫秒表示的date数据
Date date = new Date(dateNum);// 利用毫秒数构建Date对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
tv_date.setText(sdf.format(date));
int typeNum = cursor.getInt(cursor.getColumnIndex("type"));
if (typeNum == 1) {
tv_type.setText("呼入");
} else if (typeNum == 2) {
tv_type.setText("呼出");
} else {
tv_type.setText("未接");
}
}
}
}public class MainActivity extends Activity implements OnClickListener {
private Uri uri_raw_contact = Uri.parse("content://com.android.contacts/raw_contacts");// raw_contacts表
private Uri uri_data = Uri.parse("content://com.android.contacts/data");
private ContentResolver contentResolver;
private ListView lv_listview;
private Button btn_queryData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contentResolver = getContentResolver();
initView();// 自定义的获取组件引用和注册监听器的方法
queryContacts();// 自定义的查询联系人的方法
}
public void initView() {
lv_listview = (ListView) findViewById(R.id.lv_listview);
btn_queryData = (Button) findViewById(R.id.btn_queryData);
btn_queryData.setOnClickListener(this);
}
/**
* 获取联系人的信息,并且显示到listview上。 用SimpleAdapter进行适配
*/
public void queryContacts() {
List<Map<String, String>> list = getDataContacts();// 自定义的方法,获取联系人的信息List
// 仅用于展示信息,可以直接使用SimpleAdapter
SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.item_listview,
new String[] { "_id", "display_name", "phone", "email" },
new int[] { R.id.tv_id, R.id.tv_display_name, R.id.tv_phone, R.id.tv_email });
lv_listview.setAdapter(adapter);
}
// 自定义的用于查询联系人的方法
public List<Map<String, String>> getDataContacts() {
List<Map<String, String>> list = new ArrayList<Map<String, String>>();//初始化结果集
// A:查询raw_contact表,为了得到_id,display_name.
Cursor cursor = contentResolver.query(uri_raw_contact, new String[] { "_id", "display_name" }, null, null,null);
while (cursor.moveToNext()) {
Map<String, String> map = new HashMap<String, String>();
String _id = cursor.getString(cursor.getColumnIndex("_id"));
String display_name = cursor.getString(cursor.getColumnIndex("display_name"));
map.put("_id", _id);
map.put("display_name", display_name);
// B:根据查询到_id,查询data表,获取到data1, mimetype字段:
// select data1,mimetype from data where raw_contact_id = _id:
Cursor cursor2 = contentResolver.query(uri_data, new String[] { "data1", "mimetype" }, "raw_contact_id=?",new String[] { _id }, null);
// 存储的是_id对应的联系人的信息:
String email = "";
String phone = "";
String address = "";
while (cursor2.moveToNext()) {
String data = cursor2.getString(cursor2.getColumnIndex("data1"));
String mimetype = cursor2.getString(cursor2.getColumnIndex("mimetype"));// 虽然data表没有这个字段,只有mimetype_id字段,但此处必须这样获取,且获取回来的是一个类似于"vnd.android.cursor.item/email_v2"的字符串
if ("vnd.android.cursor.item/email_v2".equals(mimetype)) {
email = email + "|" + data;// 如果mimetype的值为email,表示此处的data中的数据是电子邮箱
} else if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {// 电话(有可能有手机的,座机的,家庭的,单位的...)
phone = phone + "|" + data;
} else if ("vnd.android.cursor.item/postal-address_v2".equals(mimetype)) {// 地址
address = address + "|" + data;
}
}
map.put("phone", phone);
map.put("email", email);
map.put("address", address);
list.add(map);//把一个联系人的所有信息存入map后,再将map存入list
}
return list;
}
// 点击按钮,实现查询功能
@Override
public void onClick(View v) {
queryContacts();//调用自定义的方法
}
}
public class MainActivity extends Activity{
private TextView tv_info;
private ContentResolver resolver;
private Uri uri = Uri.parse("content://com.user.contentprovider.users/users");
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
tv_info = (TextView)findViewById(R.id.tv_info);
resolver = getContentResolver();
}
public void click(View v){
switch (v.getId()) {
case R.id.bt_query:
//建表时的语句:create table t_user(_id integer primary key,uname,upass,money)
query();//调用自定义的查询所有数据的方法
break;
case R.id.bt_insert:
insert();//调用自定义的插入数据的方法
break;
case R.id.bt_update:
//请自行实现
break;
default:
break;
}
}
private void insert() {
//调用自定义的插入数据的方法(硬编码)
ContentValues values = new ContentValues();
values.put("uname", "zhang");
values.put("upass", "321");
values.put("money", "99");
Uri nUri = resolver.insert(uri, values);//sqlite会自动指定主键id
long newId = ContentUris.parseId(nUri);//获取新插入的id
Toast.makeText(this, ""+newId, 0).show();
}
private void query() {
//自定义的查询所有数据的方法
Cursor c = resolver.query(uri , new String[]{"_id","uname","upass","money"}, null, null,null);
String text = "";
while(c.moveToNext()){
text +=c.getString(0)+","+c.getString(1)+","+c.getString(2)+","+c.getString(3)+"\n";
}
tv_info.setText(text);
}
}
1780



被折叠的 条评论
为什么被折叠?



