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进程通信访问前者的服务。
相关文章推荐
- MTK Android拨打电话如何获取适时状态
- MTK平台拨打电话流程(Contacts--App层)
- Android:MTK的Dialer模块联系人搜索
- React Native 实现原生模块 实现拨打电话功能
- Android:MTK的Dialer模块联系人搜索
- Android 如何判断拨打电话对方是否接听
- Android开发实例 简单拨打电话
- Linphone 拨打电话流程
- 调起系统拨打电话
- 简单的电话拨打
- Android无需申请权限拨打电话的两种方式
- cordova 实现拨打电话-只需两步(H5)
- html5页面中 触发 拨打电话、发短信 的方式
- Android 拨打电话和发送短信
- Unity实现拨打电话
- Android 6.0 获取拨打电话的权限
- web页面实现拨打电话,发短信等功能
- android 拨打电话
- 微信小程序:拨打电话
- 拨打电话(三种方式)