通话记录分析 --- 通话详情 之一

1.5 详情

点击通话记录的item,下面会弹出一些选项,例如,为该通话记录新建一个联系人,添加一个联系人,发送短信,或者查看通话详情。在此主要看通话详情的实现。

通话记录分析 --- 通话详情 之一_第1张图片

5.1 intent

添加通话详情的intent调用流程图如下,

通话记录分析 --- 通话详情 之一_第2张图片

CallLogListItemViewHolder的showActions方法主要逻辑如下,

1,设置界面可见,

inflateActionViewStub();
actionsView.setVisibility(View.VISIBLE);
actionsView.setAlpha(1.0f);

2,显示界面的详细信息,

updatePrimaryActionButton(show);

inflateActionViewStub方法主要逻辑如下,

1,添加新建联系人等的监听事件,

ViewStub stub = (ViewStub) rootView.findViewById(R.id.call_log_entry_actions_stub);
•••
callButtonView = actionsView.findViewById(R.id.call_action);
callButtonView.setOnClickListener(this); //拨号监听事件
videoCallButtonView = actionsView.findViewById(R.id.video_call_action);
videoCallButtonView.setOnClickListener(this); //视频通话监听事件
createNewContactButtonView = actionsView.findViewById(R.id.create_new_contact_action);
createNewContactButtonView.setOnClickListener(this);//新建联系人监听事件
addToExistingContactButtonView =
     actionsView.findViewById(R.id.add_to_existing_contact_action);
addToExistingContactButtonView.setOnClickListener(this); //添加到已有联系人监听事件
sendMessageView = actionsView.findViewById(R.id.send_message_action);
sendMessageView.setOnClickListener(this); //发送短信监听事件
detailsButtonView = actionsView.findViewById(R.id.details_action);
detailsButtonView.setOnClickListener(this); //通话详情监听事件
•••

2,调用bindActionButtons方法为监听事件添加intent,

bindActionButtons();

bindActionButtons方法逻辑如下,

1,调用IntentProvider的getReturnCallIntentProvider方法添加拨号的intent

callButtonView.setTag(IntentProvider.getReturnCallIntentProvider(number));

2,调用IntentProvider的getReturnVideoCallIntentProvider方法添加视频拨号的intent,

videoCallButtonView.setTag(IntentProvider.getReturnVideoCallIntentProvider(number));
3,调用IntentProvider的getCallDetailIntentProvider方法为通话详情添加intent,
detailsButtonView.setTag(IntentProvider.getCallDetailIntentProvider(rowId, callIds, null));

4,添加 新建一个联系人/添加到联系人  的intent,并确定是否显示这2个view,

if (info != null && UriUtils.isEncodedContactUri(info.lookupUri)) {
  createNewContactButtonView.setTag(IntentProvider.getAddContactIntentProvider(
       info.lookupUri, info.name, info.number, info.type, true /* isNewContact */));
  createNewContactButtonView.setVisibility(View.VISIBLE);
addToExistingContactButtonView.setTag(IntentProvider.getAddContactIntentProvider(
     info.lookupUri, info.name, info.number, info.type, false /* isNewContact */));
   addToExistingContactButtonView.setVisibility(View.VISIBLE);
} else {
   createNewContactButtonView.setVisibility(View.GONE);
   addToExistingContactButtonView.setVisibility(View.GONE);
}

如果通话号码可以在联系人里面查询到,当然就不显示了;否则就显示。

5, 调用IntentProvider的getSendSmsIntentProvider方法添加发送短信的intent,

sendMessageView.setTag(IntentProvider.getSendSmsIntentProvider(number));

在此主要论述的是通话详情,因此主要看IntentProvider的getCallDetailIntentProvider方法,如下,

return new IntentProvider() {
 @Override
public Intent getIntent(Context context) {
  Intent intent = new Intent(context, CallDetailActivity.class);
  // Check if the first item is a voicemail.
  if (voicemailUri != null) {
     intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI, Uri.parse(voicemailUri));
  }
if (extraIds != null && extraIds.length > 0) {// 包含多条通话信息
     intent.putExtra(CallDetailActivity.EXTRA_CALL_LOG_IDS, extraIds);
  } else {
// If there is a single item, use the direct URI for it.    //单条通话信息
 intent.setData(ContentUris.withAppendedId(TelecomUtil.getCallLogUri(context), id));
  }
 return intent;
}
};

IntentProvider只是一个abstract类,有一个抽象的getIntent方法,

public abstract Intent getIntent(Context context);

在获取每个intent的方法中,都是返回一个匿名IntentProvider类,并且实现了getIntent方法。

这只是初始化步骤。

在CallLogAdapter的createCallLogEntryViewHolder方法中,会调用CallLogListItemViewHolder的create方法获取CallLogListItemViewHolder对象,会将mExpandCollapseListener监听器做为参数传入, CallLogListItemViewHolder的构造方法部分如下,

primaryActionView.setOnClickListener(mExpandCollapseListener);

并且在CallLogListItemViewHolder的onClick方法中,

1,当点击通话记录item时,

mExpandCollapseListener.onClick(primaryActionView);

就会回调CallLogAdapter的mExpandCollapseListener监听器的onClick方法。

这样才可以展示如下界面,

通话记录分析 --- 通话详情 之一_第3张图片

2,点击如上界面之后的onclick方法逻辑如下,

首先调用view的getTag方法获取IntentProvider对象,存储的时候就是调用setTag方法进行的。然后调用IntentProvider的getIntent方法获取Intent对象;最后调用DialerUtils的startActivityWithErrorToast方法完成处理。

final IntentProvider intentProvider = (IntentProvider) view.getTag();
if (intentProvider != null) {
   final Intent intent = intentProvider.getIntent(mContext);
   // See IntentProvider.getCallDetailIntentProvider() for why this may be null.
   if (intent != null) {
       DialerUtils.startActivityWithErrorToast(mContext, intent);
   }
}

DialerUtils的startActivityWithErrorToast方法主要逻辑如下,

1,处理拨号,

if ((IntentUtil.CALL_ACTION.equals(intent.getAction())
                            && context instanceof Activity)) {

2,处理其他请求,

context.startActivity(intent);

CallLogAdapter的mExpandCollapseListener是View.OnClickListener匿名实现类,其onClick方法如下,

if (viewHolder.getAdapterPosition() == mCurrentlyExpandedPosition) {
    // Hide actions, if the clicked item is the expanded item.
   viewHolder.showActions(false);
mCurrentlyExpandedPosition = RecyclerView.NO_POSITION;
   mCurrentlyExpandedRowId = NO_EXPANDED_LIST_ITEM;
} else {
   expandViewHolderActions(viewHolder);
}

如果显示菜单已打开,就调用CallLogListItemViewHolder的showActions方法将其隐藏;

如果未显示,就调用expandViewHolderActions方法显示,该方法如下,

viewHolder.showActions(true);
mCurrentlyExpandedPosition = viewHolder.getAdapterPosition();
mCurrentlyExpandedRowId = viewHolder.rowId;

也是调用CallLogListItemViewHolder的showActions方法将其显示。

CallLogListItemViewHolder的showActions方法有一个boolean参数,如果参数为true就显示,否则就隐藏。

你可能感兴趣的:(---【contact分析】)