Android 6.0拨号界面响应工程码流程
来源:互联网 发布:软件规模度量单位 编辑:程序博客网 时间:2024/04/20 13:46
背景
最近看到一个需要在拨号界面输入工程码,弹出指定界面的功能。类似输入”*#06#”弹出手机IMEI号,当然根据具体需求可以弹出隐藏在手机里面不针对终端用户使用的功能。下面就具体分析一下该功能的流程。
具体分析
在6.0中,拨号界面的显示和响应逻辑在DialpadFragment中。这个界面有一个TextEdit对象mDigits,里面容纳我们拨号的时候,输入的号码。
这个界面在初始化这个mDigits的时候就在上面添加了一个监听字符变化的监听器:
mDigits.addTextChangedListener(this);
这个监听器是一个TextWatcher类型的对象,当你输入字符之后,会触发下面的响应函数:
public void afterTextChanged(Editable input) { // When DTMF dialpad buttons are being pressed, we delay SpecialCharSequenceMgr sequence, // since some of SpecialCharSequenceMgr's behavior is too abrupt for the "touch-down" // behavior. if (!mDigitsFilledByIntent && SpecialCharSequenceMgr.handleChars(getActivity(), input.toString(), mDigits)) { // A special sequence was entered, clear the digits mDigits.getText().clear(); } }
从而触发SpecialCharSequenceMgr的静态成员函数handleChars。
public static boolean handleChars(Context context, String input, EditText textField) { //get rid of the separators so that the string gets parsed correctly String dialString = PhoneNumberUtils.stripSeparators(input); if (handleDeviceIdDisplay(context, dialString) || handlePRLVersion(context, dialString) || handleRegulatoryInfoDisplay(context, dialString) || handlePinEntry(context, dialString) || handleAdnEntry(context, dialString, textField) || handleSecretCode(context, dialString)) { return true; } return false; }
注意看if里面的这些函数,可以看到一些是处理”*#06#”之类硬编码进代码里面的工程码。如果自己要自定义的话,那么就会调用最后一个函数handleSecretCode。在这个函数里面,逻辑就很清晰了。
/** * Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*. * If a secret code is encountered an Intent is started with the android_secret_code://<code> * URI. * * @param context the context to use * @param input the text to check for a secret code in * @return true if a secret code was encountered */static boolean handleSecretCode(Context context, String input) { // Secret codes are in the form *#*#<code>#*#* int len = input.length(); if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) { final Intent intent = new Intent(SECRET_CODE_ACTION, Uri.parse("android_secret_code://" + input.substring(4, len - 4))); context.sendBroadcast(intent); return true; } if (!TextUtils.isEmpty(context.getString(R.string.oem_key_code_action))) { if (len > 10 && !input.startsWith("*#*#") && input.startsWith("*#") && input.endsWith("#")) { Intent intent = new Intent(context.getString(R.string.oem_key_code_action));intent.putExtra(context.getString(R.string.oem_code), input); context.sendBroadcast(intent); return true; } } return false;}
工程码是“*#*#5567#*#*”或者“*#44565#”的形式。都是通过发送广播的形式,将不同的action发送出去。第一种发送的Intent是:
new Intent("android.provider.Telephony.SECRET_CODE", Uri.parse("android_secret_code://5567"));
注意,这个Uri里面解析出来,scheme是“android_secret_code”,host就是5567了。这个对应到一个BroadcastReceiver的data元素的内容。具体请搜索了解Intent-filter匹配规则。
第二种发送的Intent是:
//oem_key_code_action在xml中定义,在qualcomm中是为空的。oem_code也是为空的。所以如果各位需要自定义oem相关的内容,最好在给这两个赋值,并且在响应的activity中添加对应的内容。new Intent("oem_key_code_action").putExtra("oem_code", input);
针对第一种情况,在Packages/apps/下面搜索这个action,会发现在Email模块里面的AndroidManifest.xml中有对这个action和data的响应:
<receiver android:name=".service.EmailBroadcastReceiver" android:enabled="true" android:permission="com.android.email.permission.ACCESS_PROVIDER"> <!-- To handle secret code to activate the debug screen. --> <intent-filter> <action android:name="android.provider.Telephony.SECRET_CODE" /> <data android:scheme="android_secret_code" android:host="36245" /> </intent-filter></receiver>
注意,这个对应上了action,以及对应的data。查看一下这个Receiver:
//EmailBroadcastReceiver.javapublic void onReceive(Context context, Intent intent) { EmailBroadcastProcessorService.processBroadcastIntent(context, intent) }
当然你也可以在这个onReceiver里面启动一个activity,取决于你的实际需求。通过实际在拨号界面”*#*#36245#*#*”确实弹出了Email模块的设置界面。
整体UML图如下
图一 工程码响应流程
应用
如果是自己需要在项目中使用,只需要在对应模块的AndroidManifest中声明一个BroadcastReceiver,来响应指定action(注意,针对第一种情况和第二种情况的action不一样。对于第二种情况,需要自己声明对应的”oem_key_code_action”和”oem_code”)和Data。具体参考Email模块的AndroidManifest文件。然后在这个BroadcastReceiver里面的onReceive函数里面startActivity,启动你想要启动的界面即可。
- Android 6.0拨号界面响应工程码流程
- Android拨号界面输入*#*#<code>#*#*转入自定义Activity流程
- Android 6.0拨号界面号码格式化
- android 拨号流程
- Android 5.0 拨号流程
- android拨号流程
- Android拨号流程
- Android开发-动态添加与button响应(手机拨号界面的实现)
- Android 7.0拨号流程分析
- Android N 拨号流程分析
- android中通过拨号键打开contacts相关界面的流程分析
- android中通过拨号键打开contacts相关界面的流程分析
- Android 跳转到拨号界面及自动拨号
- android界面响应事件
- Android 弹出拨号器选择界面
- Android调用拨号界面、拨打电话功能
- android 调用拨号返回调用界面
- Android开发-点击进入拨号界面-AndroidStudio
- Delphi 10.1 Berlin下TStringGrid单元格样式设定
- mysql表名忽略大小写设置
- Java并发编程:Executor框架
- fgetc
- ImageView 宽度顶边显示,高度保持比例
- Android 6.0拨号界面响应工程码流程
- java布局——流式布局
- Oracle Instant Client(即时客户端) 安装与配置
- [JQ权威指南]使用全局函数get()向服务器请求数据
- Verilog基础知识4(常用集成门电路的逻辑符号对照表)
- NVMe over Fabric诞生及发展(协议细节及市场现状篇)
- CodeForces 474AKeyboard
- c++ 覆盖 隐藏以及一些继承的关系
- java布局——网格布局