您的位置:首页 > 其它

MTK的Dialer模块的拨打电话

2016-09-01 13:41 316 查看


一、应用层的流程  


1.1、拨号盘初步处理



@DialpadFragment.java
private void handleDialButtonPressed(int type) {
if (isDigitsEmpty()) { // No number entered.
handleDialButtonClickWithEmptyDigits();
} else {
//得到号码
final String number = mDigits.getText().toString();

// 对号码进行判断
.
if (number != null
&& !TextUtils.isEmpty(mProhibitedPhoneNumberRegexp)
&& number.matches(mProhibitedPhoneNumberRegexp)) {
Log.i(TAG, "The phone number is prohibited explicitly by a rule.");
if (getActivity() != null) {
DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
R.string.dialog_phone_call_prohibited_message);
dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
}

// Clear the digits just in case.
clearDialpad();
} else {
final Intent intent;
/** M: [IP Dial] check the type of call @{ */
//判断号码的类型
if (type != Constants.DIAL_NUMBER_INTENT_NORMAL) {
intent = IntentUtil.getCallIntent(IntentUtil.getCallUri(number),
(getActivity() instanceof DialtactsActivity ?
((DialtactsActivity) getActivity()).getCallOrigin() : null),
type);
} else {
intent = IntentUtil.getCallIntent(number,
(getActivity() instanceof DialtactsActivity ?
((DialtactsActivity) getActivity()).getCallOrigin() : null));
}
/** @} */
DialerUtils.startActivityWithErrorToast(getActivity(), intent);
hideAndClearDialpad(false);
}
}
}





当点击拨号按钮的时候,从输入框(mDigits)中取出号码,首先对号码进行判断,当号码不为空且拨号限制规则不为空,并且号码属于不合法规则的时候,就给出提示。如果不是,那么就判断号码的类型,如果不是常规号码:
@IntentUtil.java
public static Intent getCallIntent(Uri uri, String callOrigin, int type) {
final Intent intent = getCallIntent(uri, callOrigin, null);
if ((type & Constants.DIAL_NUMBER_INTENT_IP) != 0) {
intent.putExtra(Constants.EXTRA_IS_IP_DIAL, true);
}

if ((type & Constants.DIAL_NUMBER_INTENT_VIDEO) != 0) {
intent.putExtra(Constants.EXTRA_IS_VIDEO_CALL, true);
}
//M: [IMS Call] For IMS Call feature @{
if ((type & Constants.DIAL_NUMBER_INTENT_IMS) != 0) {
intent.putExtra(Constants.EXTRA_IS_IMS_CALL, true);
}
return intent;
}
号码变成Uri是通过:IntentUtil.getCallUri(number)
@IntentUtil.java
public static Uri getCallUri(String number) {
return CallUtil.getCallUri(number);
}


@CallUtil.java
public static Uri getCallUri(String number) {
if (PhoneNumberHelper.isUriNumber(number)) {
return Uri.fromParts(PhoneAccount.SCHEME_SIP, number, null);
}
return Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null);
}
注:IMS查找百度是IP多媒体系统详细解释,有兴趣的小伙伴可以多了解一下


如果是常规号码:
@IntentUtil.java
public static Intent getCallIntent(String number, String callOrigin) {
return getCallIntent(CallUtil.getCallUri(number), callOrigin, null);
}
因此返回的intent为:
final Intent intent = getCallIntent(uri, callOrigin, null);
最后启动activity的语句是:
DialerUtils.startActivityWithErrorToast(getActivity(), intent);

相对应的代码为:
@DialerUtils.java
public static void startActivityWithErrorToast(Context context, Intent intent, int msgId) {
try {
if ((IntentUtil.CALL_ACTION.equals(intent.getAction())
&& context instanceof Activity)) {
// All dialer-initiated calls should pass the touch point to the InCallUI
Point touchPoint = TouchPointManager.getInstance().getPoint();
if (touchPoint.x != 0 || touchPoint.y != 0) {
Bundle extras = new Bundle();
extras.putParcelable(TouchPointManager.TOUCH_POINT, touchPoint);
intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras);
}
//通过服务拨出号码,服务启动跳转到正在拨号界面
final TelecomManager tm =
(TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
tm.placeCall(intent.getData(), intent.getExtras());
/// M: add log for debugging
if (DEBUG) {
Log.d(TAG, "startActivityWithErrorToast placeCall with intent " + intent);
}
} else {
//返回到拨号盘界面
context.startActivity(intent);
}
} catch (ActivityNotFoundException e) {
Toast.makeText(context, msgId, Toast.LENGTH_SHORT).show();
}
}


启动服务拨打电话:
@TelecomManager.java
public void placeCall(Uri address, Bundle extras) {
ITelecomService service = getTelecomService();
if (service != null) {
if (address == null) {
Log.w(TAG, "Cannot place call to empty address.");
}
try {
service.placeCall(address, extras == null ? new Bundle() : extras,
mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#placeCall", e);
}
}
}


判断intent的action是不是CALL_ACTION,如果是通过服务拨打电话,否则返回到拨号界面。

延展:TelecomManager    资料来自资料链接
     TelecomManager在framework的android.telecom包里面,它在ContextImpl被创建,并加入到注册列表里,属于系统级的服务,

registerService(TELECOM_SERVICE, new ServiceFetcher() {

public Object createService(ContextImpl ctx) {

return new TelecomManager(ctx.getOuterContext());

}});
      应用要获取其实例,可以通过其from方法,也可以直接通过context.getSystemService(Context.TELECOM_SERVICE)这个语句来获取。TelecomManager的功能则主要是对TelecomService提供的远程接口的封装,然后提供给应用使用,例如对于showInCallScreen方法,TelecomServiceImpl提供服务端的远程方法,TelecomManager提供客户端访问接口,DialpadFragment等应用组件使用这个接口。虽然TelecomServiceImpl是在packages目录下,TelecomManager在frameworks目录下,但前者作为一个服务,在单独进程里为后者提供服务,后者则为应用进程提供接口服务,再通过binder进程通信访问前者的服务。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: