[Android][Framework] 从一个小问题了解STK加载内容的方式

STK就是SIMToolKit。

问题如图,STK一个case的输入框,不应该能输入+:

这个界面从哪来的? 实际上,我们插入SIM卡,手机就会显示SimToolKit,打开就能看到一些和运营商相关的菜单。换了不同的卡菜单也会变。所以大概可以猜到,SIM卡里写有一些配置文件,STK会解析这些文件。

项目原因,正好可以拿到一些配置文件,如图:

通过Smartstation把配置文件写到模拟SIM卡中,然后插卡交给STK读取处理这些信息。

阅读Java文件,找到出问题的case代码:

case 30021: 
    GetInput getinput21 = new GetInput("Enter 67#*+.digits, SMS default alphabet, Terminal to hide text, packing required, help information available,\"+\" can not input.",4,8);
    getinput21.digitsOnly();
    getinput21.noEcho();
    getinput21.textString().packed();
    getinput21.helpInformationAvailable(true);
    super.pch.sendCommand(getinput21.toByteArray());
    super.state = 0;
    break;

从文件可以知道,输入框是个GetInput对象。 输入对象配置了digitsOnlynoEchopacked等属性。

怎么处理配置文件?

有了配置文件,插SIM卡到手机,STK会处理这些数据。

在OpenGrok上搜索代码,可以找到输入部分,在STK的packages/apps/Stk/src/com/android/stk/StkInputActivity.java文件中。

下面看一下configInputDisplay方法,配置输入显示。

private void configInputDisplay() {
    TextView numOfCharsView = (TextView) findViewById(R.id.num_of_chars);
    TextView inTypeView = (TextView) findViewById(R.id.input_type);

    int inTypeId = R.string.alphabet;

    // set the prompt.
    mPromptView.setText(mStkInput.text);

    // Set input type (alphabet/digit) info close to the InText form.
    if (mStkInput.digitOnly) {
        mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
        inTypeId = R.string.digits;
    }
    inTypeView.setText(inTypeId);

    if (mStkInput.icon != null) {
        setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(
                mStkInput.icon));
    }

    // Handle specific global and text attributes.
    switch (mState) {
    case STATE_TEXT:
        int maxLen = mStkInput.maxLen;
        int minLen = mStkInput.minLen;
        mTextIn.setFilters(new InputFilter[] {new InputFilter.LengthFilter(
                maxLen)});

        // Set number of chars info.
        String lengthLimit = String.valueOf(minLen);
        if (maxLen != minLen) {
            lengthLimit = minLen + " - " + maxLen;
        }
        numOfCharsView.setText(lengthLimit);

        if (!mStkInput.echo) {
            mTextIn.setInputType(InputType.TYPE_CLASS_NUMBER
                                 | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
        }
        // Set default text if present.
        if (mStkInput.defaultText != null) {
            mTextIn.setText(mStkInput.defaultText);
        } else {
            // make sure the text is cleared
            mTextIn.setText("", BufferType.EDITABLE);
        }

        break;
    case STATE_YES_NO:
        // Set display mode - normal / yes-no layout
        mYesNoLayout.setVisibility(View.VISIBLE);
        mNormalLayout.setVisibility(View.GONE);
        break;
    }
}

代码中出现mStkInput.digitOnly这样的判断,可以推断mStkInput就是和配置文件里的GetInput对象。

mStkInput来自frameworks/opt/telephony/src/java/com/android/internal/telephony/cat/Input.java

定义如下:

Input() {
    text = "";
    defaultText = null;
    icon = null;
    minLen = 0;
    maxLen = 1;
    ucs2 = false;
    packed = false;
    digitOnly = false;
    echo = false;
    yesNo = false;
    helpAvailable = false;
    duration = null;
    iconSelfExplanatory = false;
}

回到前面的class,因为STK file里有说明getinput21.digitsOnly();,所以会进入下面逻辑:

// Set input type (alphabet/digit) info close to the InText form.
if (mStkInput.digitOnly) {
    mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
    inTypeId = R.string.digits;
}

这里mTextIn是一个EditText,setKeyListener就是过滤字符的作用。

/**
 * For entering dates in a text field.
 */
public class StkDigitsKeyListener extends NumberKeyListener {
    @Override
    protected char[] getAcceptedChars() {
        return CHARACTERS;
    }

    public int getInputType() {
        return EditorInfo.TYPE_CLASS_PHONE;
    }

    public static StkDigitsKeyListener getInstance() {
        if (sInstance != null) {
            return sInstance;
        }
        sInstance = new StkDigitsKeyListener();
        return sInstance;
    }

    /**
     * The characters that are used.
     *
     * @see KeyEvent#getMatch
     * @see #getAcceptedChars
     */
    public static final char[] CHARACTERS = new char[] {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '#', '+'};

    private static StkDigitsKeyListener sInstance;
}

可以看到,CHARACTERS定义了可以输入的字符,其中包含’+’。如果不需要’+’,把这里的声明修改掉就OK

其实我也不做Tele,但通过这个过程,可以大概了解一些STK相关的原理。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

Android Remote Views

听名字就可以看出,remote views是一种远程view,感觉有点像远程service,其实remote views是view的一个结构,他可以在其他的进程...

20470
来自专栏Android相关

AAC---LiveData

LiveData是一个与Activity/Fragment生命周期相关(lifecycle-aware)的Observer类。而这种相关性(awareness ...

12220
来自专栏非著名程序员

Retrofit初探和简单使用

? Retrofit简单介绍 Retrofit是Square提供的开源产品,为Android平台的应用提供一个类型安全的REST客户端。它是基于注解,提供 J...

21290
来自专栏Android知识点总结

Android原生下载(下篇)多文件下载+多线程下载

41240
来自专栏Android知识点总结

O1-开源框架使用之EventBus

说明使用POSTING,发布与订阅在同一个线程,也就是子线程,更新UI会崩 说明使用MAIN,不管发布者在哪,订阅者都在main线程,可更新UI,但不能耗时操...

11220
来自专栏分享达人秀

Activity任务栈和启动模式

通过前面的学习,Activity的基本使用都已掌握,接下来一起来学习更高级的一些内容。 Android采用任务栈(Task)的方式来管理Act...

21060
来自专栏cloudskyme

gwt之mvc4g

Mvc4g是一个简单的框架来实现的GWT应用程序的MVC模式。 主要思想 其主要思想是,以减轻开发人员的工作,以单独的视图从模型。该框架是一个XML文件,将允...

34260
来自专栏漏斗社区

天空飘来五字:Android逆向smali

本期,我们将继续Android逆向动态分析之smali篇。内容包括smali语言介绍与动态调试。

13420
来自专栏向治洪

android插件开发机制

插件机制实质上就是由主体程序定义接口,然后由插件去实现这些接口,以达到功能模块化。Android系统是基于Linux内核的,其安全机制也继承了Linux的特性...

23370
来自专栏Hellovass 的博客

动态生成分享图片

本文描述了如何实现该需求的思路,代码可能不通用,但是该思路应该可以解决很多类似的需求…

49630

扫码关注云+社区

领取腾讯云代金券