接着上面的实现,逐步拓展几个功能。
比如实现查看通讯录,以及直接通过点击联系人条目实现拨号。
实际上功能往往伴随着组件的熟练掌握和使用。当掌握所有组件的使用的时候大概就可以随心所欲玩出花来。
对于拿到通讯录并展示主要涉及到的技术就是——ListView组件的使用(学完RecyclerView也可以完成这个功能,而且好像更常用耶,但是目前这个简单点,暂时学习使用)。
看了上一次的基本才能理解这一次在干啥,上一次文章直通车:Android开发——实现一个拨号器(一)_Biangbangbing的博客-CSDN博客
在主页面点击联系人按钮,跳转到通讯录页面。
通讯录页面显示若干联系人条目,一个条目的内容包括:联系人姓名,电话号(还可以自行设计增添其他内容)。
增加一个联系人页面,一对应的活动类;另外还要增加一个条目的布局设计,以及游标类,联系人类。
1.最开始要记得设计好在主页面,点击联系人按键之后,跳转到通讯录这个页面。
2.再看通讯录页面的布局设计activity_contact.xml
3.看ListView的一个条目应该张什么样。activity_list_item.xml(这个没有设计相应的活动,以逆袭需要在layout文件下手动建立)
4.接着来看活动类如何设计——如何拿到实际的通讯录信息,并且将数据填充到listview的每一个条目里。
package com.example.bydialer.listView;
public class Contactor {
private String name;
private String telno;
public Contactor(String name, String telno) {
this.name = name;
this.telno = telno;
}
public void setName(String name) {
this.name = name;
}
public void setTelno(String telno) {
this.telno = telno;
}
public String getName() {
return name;
}
public String getTelno() {
return telno;
}
}
这个地方视频没有讲解的很清楚,有一篇博文写的很清晰:挂大佬文章——>BaseAdapter使用教程及方法详解 - 简书
package com.example.bydialer.listView;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.bydialer.R;
import java.util.ArrayList;
public class MyListAdapter extends BaseAdapter {
private Context context;
private LayoutInflater layoutInflater;
private ContentResolver contentResolver;
private ArrayList list;
public MyListAdapter(Context context,ArrayList list){
this.context = context;
this.layoutInflater = LayoutInflater.from(context);
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
static class ViewHolder{
public TextView name,telno;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
convertView = this.layoutInflater.inflate(R.layout.activity_list_item,null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.telno = (TextView) convertView.findViewById(R.id.telno);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
//给控件赋值
holder.name.setText(list.get(position).getName());
holder.telno.setText(list.get(position).getTelno());
return convertView;
}
}
package com.example.bydialer;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.bydialer.listView.Contactor;
import com.example.bydialer.listView.MyListAdapter;
import java.util.ArrayList;
public class ContactActivity extends AppCompatActivity {
private ContentResolver contentResolver;
private ArrayList list = new ArrayList<>();
private ListView mlv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact);
mlv = findViewById(R.id.lv);
//获取内容访问者
this.contentResolver = getContentResolver();
//拿到所有通讯录的姓名
Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");
Cursor cursor=contentResolver.query(uri,null,null,null,null);
while(cursor.moveToNext()){
@SuppressLint("Range") String _id=cursor.getString(cursor.getColumnIndex("_id")); //拿到id
@SuppressLint("Range") String display_name=cursor.getString(cursor.getColumnIndex("display_name")); //拿到姓名
Log.i("test",""+_id+"\t\t\t"+display_name);
Uri uriData=Uri.parse("content://com.android.contacts/raw_contacts/"+_id+"/data"); //根据id拿到这个对象的所有信息
Cursor contactsInfo=contentResolver.query(uriData,null,null,null,null);
while (contactsInfo.moveToNext()){
@SuppressLint("Range") String mimetype=contactsInfo.getString(contactsInfo.getColumnIndex("mimetype"));
@SuppressLint("Range") String data1=contactsInfo.getString(contactsInfo.getColumnIndex("data1"));
if("vnd.android.cursor.item/phone_v2".equals(mimetype)){
list.add(new Contactor(display_name,data1));
Log.i("test",""+mimetype+"\t\t\t"+data1);
}
}
}
mlv.setAdapter(new MyListAdapter(ContactActivity.this,this.list));
mlv.setOnItemClickListener( new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
TextView tv = (TextView) findViewById(R.id.telno);
String str = tv.getText().toString();
System.out.println("str:"+str);
if ((str !=null) && (!str.trim().equals(""))){
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+str));
startActivity(intent);
}
}
});
}
}
这样基本功能就设计完了,测试跑一下
=>然后就发现自己的问题,原本去找电话号码的时候没有加view.,是直接findViewById,这 样找到的应该是随机一个。view.findViewById才是从list的当前点击的这个条目view中找 电话号的TextView这一项,修改之后就可以准确给点击的条目拨打电话了。
ps:图片中修改的是ContactActivity.java 点击条目拨打的方法,最上面给的时候还没有修改。
上次文章的链接也还没改呀。
上次也挂出来的项目链接:GitHub - Biangbangbing/ByDial
其他功能有待学习更多的组件以及叠buff。欢迎各位大佬提出建议!