三、友录-通话记录功能

目标:实现通话记录页面记录最近与联系人的通话记录,包括已接,已拨,以及对未接和陌生号码做标识。

有了前面的框架,下面实现具体代码就不像前面那么复杂啦~

一、构建布局文件

layout-->fragment_call中构建通话记录页面

//标题栏

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:text="通话记录"
            android:textColor="#ffffffff"
            android:textSize="20sp" />

//显示通话记录的listview

    <ListView
        android:id="@+id/lv_call"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:listSelector="#00000000" >//去掉系统默认点击每个通话记录条目item时的背景颜色
    </ListView>

layout--->call_listview_item 新建通话记录中每条记录的item 

    <RelativeLayout
        android:id="@+id/photo_call_item"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp" >
        <ImageView
            android:id="@+id/ivphoto_call_item"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/ic_launcher" />
        <ImageView
            android:id="@+id/ivWarn_call_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:src="@drawable/ic_warning"
            android:visibility="gone" />//未接电话的红色标记图标,在联系人头像的右下方
    </RelativeLayout>
<TextView
        android:id="@+id/tvName_call_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="18dp"
        android:layout_toRightOf="@+id/photo_call_item"
        android:text="联系人" />
    <LinearLayout
        android:id="@+id/ll_call_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/tvName_call_item"
        android:layout_below="@+id/tvName_call_item"
        android:layout_marginTop="5dp"
        android:orientation="horizontal" >
        <ImageView
            android:id="@+id/ivphoneCall_call_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:src="@drawable/ic_outgoing_call"
            android:visibility="gone" />//呼出电话图标
        <TextView
            android:id="@+id/tvNumber_call_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text="135-2342-3848" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text="京城" />
    </LinearLayout>
    <TextView
        android:id="@+id/time_call_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="15dp"
        android:layout_marginTop="20dp"
        android:text="16:40" />

二、开始填充数据,写代码

1,首先构建一个实体类,该类记录了通话记录的基本信息:如姓名,电话,头像,通话时间等

public class Call {
private int _id;//数据记录id
private int photo_id;//头像id
private String name;//姓名
private String number;//电话
private long time;//电话发生的时间(时间戳)
private int type;//type的取值:1,呼入电话,2,呼出电话,3,未接电话

get(){},set(){}...........

}

2,添加一个监听接口,当从数据库中加载数据完毕时回调用此接口中的方法,将参数传入此方法中

import java.util.List;
import bean.Call;
public interface OnLoadCallFinishListener {
//当从数据库中加载通话记录信息完毕后,会调用此方法
//并把获得的数据作为参数传入
void OnLoadCallFinish(List<Call> calls);
}

3,构建业务类CallBiz:

public class CallBiz {
private Context context;
public CallBiz(Context context){
this.context=context;
}
//获取当前所有联系人信息
public void asyncgetAllCalls(onLoadCallFinishListener listener){
YouluUtil.asyncgetAllCalls(context,listener);//交给YouluUtil工具类去实现
}
/**
* 获得通话记录联系人的头像图片
*/
public void asyncgetCallAvatar(int photoId,onLoadAvatarFinishListener listener){
YouluUtil.asyncgetAvatar(context,photoId,listener);
}
public String getTime(long timeStample){
return YouluUtil.getTime(timeStample);
}
public void deleteCall(Call call, NBCallAdapter adapter) {
YouluUtil.deleteCall(context,call,adapter);
}
}

4,完善CallAdapter

public class CallAdapter extends BaseAdapter{
//全局资源访问
Context context;
//装通话记录的条目
List<Call> calls;
//膨胀条目的布局类
LayoutInflater inflater;
//与主页面fragment中间衔接的业务类
CallBiz biz;
@Override
public int getCount() {
return calls.size();
}
@Override
public Call getItem(int position) {
return calls.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder vh;
if (convertView==null) {
convertView=inflater.inflate(R.layout.call_listview_item,parent,false);
vh=new ViewHolder();
vh.tvName=(TextView) convertView.findViewById(R.id.tvName_call_item);
vh.tvNumber=(TextView) convertView.findViewById(R.id.tvNumber_call_item);
vh.ivAvatar=(ImageView) convertView.findViewById(R.id.ivphoto_call_item);
vh.ivWarn=(ImageView) convertView.findViewById(R.id.ivWarn_call_item);
vh.ivPhoneout=(ImageView) convertView.findViewById(R.id.ivphoneCall_call_item);
vh.time=(TextView) convertView.findViewById(R.id.time_call_item);
convertView.setTag(vh);
}else{
vh=(ViewHolder) convertView.getTag();
}
Call call=getItem(position);
//获取通话记录人头像
biz.asyncgetCallAvatar(call.getPhoto_id(),new OnLoadAvatarFinishListener() {
@Override
public void onLoadAvatarFinish(Bitmap bitmap) {
vh.ivAvatar.setImageBitmap(bitmap);
}
});
//用户姓名字体颜色处理,未接电话显示红色字体
if (call.getType()==3) {
vh.tvName.setTextColor(Color.RED);
}
//陌生人姓名处理:显示红色,并用惊叹号标记
if (call.getName().equals("未知号码")) {
vh.tvName.setTextColor(Color.RED);
vh.ivWarn.setVisibility(View.VISIBLE);
}
vh.tvName.setText(call.getName());
vh.tvNumber.setText(call.getNumber());
//呼出电话小图标的显示
if (call.getType()==2) {
vh.ivPhoneout.setVisibility(View.VISIBLE);
}
//通话时间的处理
vh.time.setText(biz.getTime(call.getTime()));
return convertView;
}
public class ViewHolder{
TextView tvName,tvNumber,time;//电话联系人姓名,电话,通话时间
ImageView ivAvatar,ivWarn,ivPhoneout;//联系人头像,未接电话或陌生人电话提示标志,呼出电话标志
}
}

5,在YouluUtil工具类中添加以上用到的方法

//1,adapter中设置时间时调用到getTime方法

public static String getTime(long time) {
//调用getTime方法的时间点
long now=System.currentTimeMillis();
int day=(int) (now/1000/60/60/24-time/1000/60/60/24);
switch (day) {
case 0:
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm");
return sdf.format(time);
case 1:
SimpleDateFormat sdf2=new SimpleDateFormat("HH:mm");
return "昨天"+sdf2.format(time);
case 2:
return "前天";
default:
SimpleDateFormat sdf3=new SimpleDateFormat("yyyy/MM/dd");
return sdf3.format(time);

}
}

//2.callFragment页面中初始化视图时长按item删除时调用此方法
public static void deleteCall(final Context context, final Call call,
final CallAdapter adapter) {
AlertDialog.Builder builder=new AlertDialog.Builder(context);
builder.setIcon(android.R.drawable.ic_menu_info_details);
builder.setTitle("删除通知");
builder.setMessage("确实要删除通话记录吗?");
builder.setNegativeButton("再想想", null);
builder.setPositiveButton("删除", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ContentResolver cr=context.getContentResolver();
cr.delete(CallLog.Calls.CONTENT_URI, Calls._ID+"=?", new String[]{String.valueOf(call.get_id())});
//从listview数据源中删除
adapter.remove(call);
}
});
//特别容易忘的核心代码
builder.create().show();
}

//3,CallFragment刷新页面加载通话记录时调用此方法
public static void asyncgetAllCalls(final Context context,final OnLoadCallFinishListener listener) {
new AsyncTask<Void, Void, List<Call>>(){
@Override
protected List<Call> doInBackground(Void... params) {
List<Call> calls=new ArrayList<Call>();
ContentResolver cr=context.getContentResolver();
Cursor cursor=cr.query(CallLog.Calls.CONTENT_URI,
new String[]{CallLog.Calls._ID,"photo_id",CallLog.Calls.TYPE,CallLog.Calls.NUMBER,
CallLog.Calls.DATE,CallLog.Calls.CACHED_NAME}, null, null, CallLog.Calls.DATE+" desc");
while (cursor.moveToNext()) {
Call call=new Call();
call.set_id(cursor.getInt(0));
call.setNumber(cursor.getString(3));
call.setPhoto_id(YouluUtil.getPhotoIdByNumber(context,call.getNumber()));
call.setType(cursor.getInt(2));
if (TextUtils.isEmpty(cursor.getString(5))) {
call.setName("未知号码");
}else{

call.setName(cursor.getString(5));//别忘了这句话,给通话记录的姓名赋上值,否则adapter中就会报空指针

}
call.setTime(cursor.getLong(4));
calls.add(call);
}
cursor.close();
return calls;
}
protected void onPostExecute(java.util.List<Call> result) {
listener.OnLoadCallFinish(result);
};
}.execute();
}
protected static int getPhotoIdByNumber(Context context, String number) {
int photoId=0;
ContentResolver cr=context.getContentResolver();
Uri uri=Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, number);
Cursor cursor=cr.query(uri, new String[]{PhoneLookup.PHOTO_ID}, null, null, null);
if (cursor.moveToNext()) {
photoId=cursor.getInt(0);
}
cursor.close();
return photoId;
}

6,修改读取手机通话记录的权限,一定要记得:

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

下面是运行结果~:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值