Android拨号盘特殊字符串处理

Android拨号盘特殊字符串(例如*#06#显示IMEI或者MEID)处理的类是:

packages/apps/Dialer/src/com/android/dialer/SpecialCharSequenceMgr.java,入口是handleChars,这个方法在拨号盘EditText字符有变化的时候会调用:

  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 (ZteEngineerCode.handleZteEngineerCode(context, dialString)
                || handleDeviceIdDisplay(context, dialString)
                || handleRegulatoryInfoDisplay(context, dialString)
                || handlePinEntry(context, dialString)
                || handleAdnEntry(context, dialString, textField)
				|| ZteEngineerCode.handleZteEngineerCode(context, dialString)
                || handleSecretCode(context, dialString)
                /// M: for plug-in @{
                || ExtensionManager.getInstance().getDialPadExtension().handleChars(context,
                        dialString)
                /// @}
                ) {
            return true;
        }

        return false;
    }
一个有多个处理函数组成的if判断语句作为主体,只有有一个方法返回true就返回。
 static boolean handleDeviceIdDisplay(Context context, String input) {
        TelephonyManager telephonyManager =
                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        if (telephonyManager != null && input.equals(MMI_IMEI_DISPLAY)) {
            int labelResId = (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) ?
                    R.string.imei : R.string.meid;

            List<String> deviceIds = new ArrayList<String>();
            for (int slot = 0; slot < telephonyManager.getPhoneCount(); slot++) {
                String deviceId = telephonyManager.getDeviceId(slot);
                if (!TextUtils.isEmpty(deviceId)) {
                    deviceIds.add(deviceId);
                }
            }

            /// M: Add single IMEI plugin. @{
            deviceIds = ExtensionManager.getInstance().getDialPadExtension().getSingleIMEI(
                    deviceIds);
            /// @}

            AlertDialog alert = new AlertDialog.Builder(context)
                    .setTitle(labelResId)
                    .setItems(deviceIds.toArray(new String[deviceIds.size()]), null)
                    .setPositiveButton(android.R.string.ok, null)
                    .setCancelable(false)
                    .show();
            return true;
        }
        return false;
    }
拿*#06#举例,使用TelephonyManager获取相应信息后弹出AlertDialog显示。

ZteEngineerCode是mtk相关的暗码处理类,流程类似handleChars,单独类分离出去不和原生代码掺杂在一起

handleRegulatoryInfoDisplay处理*#07#,发送了个Intent出去,处理该intent的是设置中的代码:

        <!-- Show regulatory info (from settings item or dialing "*#07#") -->
        <activity android:name="RegulatoryInfoDisplayActivity"
                  android:label="@string/regulatory_information"
                  android:taskAffinity=""
                  android:enabled="@bool/config_show_regulatory_info">
            <intent-filter>
                <action android:name="android.settings.SHOW_REGULATORY_INFO" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                android:value="true" />
        </activity>
显示手机相关的一些信息,不过我看源码中这个相关字符串是空的,实际手机验证啥也没弹出来,activity收到intent后会马上关闭。

handlePinEntry处理一些Mmi码,详细见MMI SS USSD扫盲贴

 static boolean handlePinEntry(final Context context, final String input) {
        if ((input.startsWith("**04") || input.startsWith("**05")) && input.endsWith("#")) {
        ...
           return TelecomUtil.handleMmi(context, input, null);
        ... 
 }
**04和**05开头的mmi码都是设置pin的,所以该方法有pin这个字眼,很少人知道有个东西吧。

handleAdnEntry,adn就是卡联系人,输入数字(1~4位)加#结束,拨号盘会自动加载sim卡对应index卡联系人的号码(如果有的话)

handleSecretCode发送一个广播,*#*#开头和#*#*结尾的字符串都会看成是secretcode:

  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;
        }

        return false;
    }
还是设置中的例子,*#*#4636#*#*可以开启一个activity,显示手机很多信息,如注册的网络信息,电池信息,wifi信息等。

        <receiver android:name="TestingSettingsBroadcastReceiver">
            <intent-filter>
                 <action android:name="android.provider.Telephony.SECRET_CODE" />
                 <data android:scheme="android_secret_code" android:host="4636" />
            </intent-filter>
       </receiver>
如果需要加入暗码需求统一使用广播模式是最好的,不用更改代码其它应用就可以有暗码入口,不过可惜运营商定制机器有很多强制要实现的暗码。




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值