本文将采取问答形式展开,收集的一些平时修改android平台源码遇到的问题。基于展讯平台,别的平台也基本上类似修改即可。

case 1:android:imeOptions有什么作用?

曾经出现一个问题:固定拨号横屏下保存输入PIN2码后完成功能失效。经检查发现编辑框的android:imeOptions="actionDone"属性没有设置。在android2.3.5上修改Phone/res/layout/get_pin2_screen.xml文件,为EditText android:id="@+id/pin添加android:imeOptions="actionDone"属性后问题解决。

默认情况下软键盘右下角的按钮为“下一个”,点击会到下一个输入框,保持软键盘;

当设置android:imeOptions="actionDone"

当设置android:imeOptions="actionSend"软键盘下方变成“发送”,点击后光标移动下一个。

case2:海外项目如何根据当地sim自动切换语言

修改文件:MccTable.java (frameworks\opt\telephony\src\java\com\android\internal\telephony)
找到sTable中对应的配置信息:
写成如下形式sTable.add(new MccEntry(460,"cn",2,"zh"));
locale.region为cn ,locale.language为zh表示所在地在中国,自动识别为中文

case3:android4.4 如何去除系统语言跟随sim卡地区变换功能?

如果想去除 系统语言跟随sim卡地区变换的功能按照如下方法修改

frameworks/opt/telephony/src/java/com/android/internal/telephony/MccTable.java文件中

updateMccMncConfiguration()函数 注释 locale = getLocaleFromMcc(context, mcc);
                                             或注释掉 if (locale != null) {中如下两句

                                                          config.setLocale(locale);

                                                          updateConfig = true;  

case4:如何在输入法中如何添加印度货币符号卢比。

1.如果是第三方输入法,需要联系第三方。

2.如果是安卓原生的latin IME,可以找到资源文件中的kbd_symbols.xml。 见如下:

<Key

android:keyLabel="$"

android:popupKeyboard="@xml/kbd_popup_template"

android:popupCharacters="¢£€¥₣₤₱₹" />

keylabel是表示这个键显示的内容,如果是短按,就上屏这个字。

如果长按,就是弹出popup,请用户选择,选择的内容是popupCharacters中显示,

原生的latin IME中可选的是欧元,法郎等货币符号,可以把卢比的符号加入到这里。

3.如果需要增加别的符号,也可以像卢比添加的方式。

case5:怎么配置输入法默认声音和vibrator


以Google拼音为例:

  Settings.java代码中存在initConfs配置函数

    private void initConfs() {
        mKeySound = mSharedPref.getBoolean(ANDPY_CONFS_KEYSOUND_KEY, true);
        mVibrate = mSharedPref.getBoolean(ANDPY_CONFS_VIBRATE_KEY, false);
        mPrediction = mSharedPref.getBoolean(ANDPY_CONFS_PREDICTION_KEY, true);
    }

 见声音配置(ANDPY_CONFS_KEYSOUND_KEY, true),设置成true代表默认打开,false代表关闭;

 Vibrator也是如此配置;


case6:输入法开启按键震动,震感太弱,如何解决


此问题如果是单体即单个手机问题,则一般为硬件vibrator有点问题,如果不是单体问题,通过软件配置一般也可以达到加强震感的要求,该平台中具体配置如下:

packages\inputmethods\pinyinime\src\com\android\inputmethod\pinyin\SoftKeyboardView.java:

搜索mVibratePattern关键字,对此进行配置即可

如 protected long[] mVibratePattern = new long[] {1, 20};

改成    protected long[] mVibratePattern = new long[] {1, 50};


case7:如何配置输入法显示和隐藏

在应用程序设计中一般会有如下对输入法显示/隐藏的要求:
1:在启动之后,当获得输入焦点的时候,即要求显示输入法
2:在Activity跳转的时候,要求隐藏前一个输入焦点绑定的输入 等这些设计要求。
如下介绍三种配置方法:
一:在AndroidMainfest.xml中配置,
一般针对需要输入焦点出现时候就弹出IME的Activity下配置
android:windowSoftInputMode="..."配置参数如下:
stateHidden:用户选择activity时,软键盘总是被隐藏
stateAlwaysHidden:当该Activity主窗口获取输入焦点时,软键盘也总是被隐藏的
stateVisible:软键盘通常是可见的
stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态
adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示
另外还有两个配置是为了动态调整输入框的位置
adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间
adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分 ---这个我们用的比较多,
一般当输入焦点比较多的Activity的时候,配置这个,系统会自动的调整Activity的界面,保证EditText不会被IME遮挡。一般会压缩Title和输入框之间的布局

二:在代码中配置
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
这里的WindowManager.LayoutParams有
SOFT_INPUT_ADJUST_PAN
SOFT_INPUT_ADJUST_RESIZE
SOFT_INPUT_STATE_ALWAYS_VISIBLE
SOFT_INPUT_STATE_ALWAYS_HIDDEN
SOFT_INPUT_STATE_HIDDEN
SOFT_INPUT_STATE_VISIBLE
SOFT_INPUT_STATE_UNSPECIFIED
SOFT_INPUT_STATE_UNCHANGED
这里的配置和上述AndroidManifest意思是一样的

如果我们在上述两个文件中都配置了,最后都是以代码中的配置为准

三:在Activity跳转的时候需要动态的显示/隐藏输入法
隐藏

public void hideInputMethod() {
         InputMethodManager imm = getInputMethodManager();
         if (imm != null) {
             imm.hideSoftInputFromWindow(getWindowToken(), 0);//这里的Token 是当前焦点view的Token
         }
     }显示
      public void showInputMethod() {
         InputMethodManager imm = getInputMethodManager();
         if (imm != null) {
             imm.showSoftInput(this, 0);
         }
     }


上述两种是常用的动态显示/隐藏输入法

case8:如何防止一个控件被过快重复点击


在android开发中,为防止控件过快点击,需要确保有效点击,即在有效时间内只记下一次点击事件  

private boolean processFlag = true; //默认可以点击   
 //b_next 那个被点击的控件   
 b_next.setOnClickListener(new OnClickListener() {  
           public void onClick(View v) {  
               if (processFlag) {  
                   setProcessFlag();//   
                   toNext();// 去执行的具体操作   
                   new TimeThread().start();  
               }  
           }  
       });  
 /** 
    * 设置按钮在短时间内被重复点击的有效标识(true表示点击有效,false表示点击无效) 
    */  
   private synchronized void setProcessFlag() {  
       processFlag = false;  
   }  
  
   /** 
    * 计时线程(防止在一定时间段内重复点击按钮) 
    */  
   private class TimeThread extends Thread {  
       public void run() {  
           try {  
               sleep(1000);  
               processFlag = true;  
           } catch (Exception e) {  
               e.printStackTrace();  
           }  
       }  
   }

case9:如何监听来电通话

监听来电的方法是创建一个类PhoneState继承PhoneStateListener,实现onCallStateChanged方法,里面的state主要有三种状态

CALL_STATE_RINGING: 来电状态 

CALL_STATE_OFFHOOK: 摘机状态,即接听状态 


CALL_STATE_IDLE:空闲状态

根据三种状态,分别做对应操作。

然后使用

mPhoneState = new PhoneState();
mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
mTelephonyManager.listen(mPhoneState, PhoneStateListener.LISTEN_CALL_STATE);
即可使监听生效。

最后还要在AndroidManifest.xml里面添加个permission.

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 


case10:如何获得Android手机内存使用情况?

1.通过代码获得:

public long memInfo {
    // 获得可用的内存
      public static long getmem_UNUSED(Context mContext) {
      long MEM_UNUSED;
      ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
      // 创建ActivityManager.MemoryInfo对象  
     ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
     am.getMemoryInfo(mi);    // 取得剩余的内存空间 
      MEM_UNUSED = mi.availMem / 1024; 
     return MEM_UNUSED;
 }

 

2.通过命令获取当前设备的内存使用情况

 “/proc/meminfo”文件记录了android手机的一些内存信息,在命令行窗口里输入”adb shell”,进入shell环境,输入”cat /proc/meminfo”即可在命令行

里显示meminfo文件的内容。cat /proc/meminfo

MemTotal:          94096 kB
MemFree:            1684 kB
Buffers:              16 kB

只需要读取这个文件就可以,获取到的MemTotal的值就是内存的总数



case11:默认输入法修改为“讯飞输入法”,清除最近应用后,默认输入法会还原

RamOptimize一键清理把ifly的进程给清除了,这样系统在寻找输入法时发现当前默认的ifly输入法被kill,就会自动切换到 默认的系统输入法。只需将ifly加入RamOptimize的白名单,保证不被kill就不会还原为默认的输入法,具体的修改如下:

--- a/res/values/arrays.xml
 +++ b/res/values/arrays.xml
 @@ -46,6 +46,7 @@
       <item>com.android.music</item>
       <item>com.thunderst.radio</item>
       <item>com.android.providers.downloads.ui</item>
 +     <item>com.iflytek.inputmethod</item>
      </string-array>
      <!-- the name of service that we wan't to kill -->
      <string-array name="recent_keep_service" translatable="false">


case12:如何修改虚拟按键高度?


frameworks/base/core/res/res/values/dimens.xml文件中

<resources>   
    ....... 
    <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_height">48dp</dimen>
     <!-- Height of the bottom navigation bar in portrait; often the same as @dimen/navigation_bar_height -->
     <dimen name="navigation_bar_height_landscape">48dp</dimen></resources>
navigation_bar_height是竖屏时高度
navigation_bar_height_landscape是横屏时高度
case13:输入框行尾,怎样才能允许输入空格自动换行?


安卓原生对文字的换行策略是:

在正式的文件中每行开头不能是标点、空格等非常规字符



修改原生策略前,需要考虑以下几点: 


1、这个需求是否合理,修改与不修改对不同的用户群不同场景下会造成什么影响,是否某些用户及场景下用户体验增加了,但另一些却降低了。


2、修改原生策略有可能会造成一些 CTS 相关 case fail。 


3、对整个系统的原有界面会有影响,之前合适的地方在修改后换行位置变了,可能变得会有显示问题。 


修改方法是:

frameworks/base/core/java/android/text/StaticLayout.java的generate方法中:

搜索:boolean isSpaceOrTab = c == CHAR_TAB || c == CHAR_ZWSP;

修改为:boolean isSpaceOrTab = c == CHAR_SPACE || c == CHAR_TAB || c == CHAR_ZWSP;

搜索:// From the Unicode Line Breaking Algorithm (at least approximately)
                        boolean isLineBreak = isSpaceOrTab ||
                                // / is class SY and - is class HY, except when followed by a digit
                                ((c == CHAR_SLASH || c == CHAR_HYPHEN) &&
                                (j + 1 >= spanEnd || !Character.isDigit(chs[j + 1 - paraStart])));

修改为:// From the Unicode Line Breaking Algorithm (at least approximately)
                        boolean isLineBreak = isSpaceOrTab ||
                                // / is class SY and - is class HY, except when followed by a digit
                                ((c == CHAR_SLASH || c == CHAR_HYPHEN) &&
                                (j + 1 >= spanEnd || !Character.isDigit(chs[j + 1 - paraStart]))) ||
                                // Ideographs are class ID: breakpoints when adjacent, except for NS
                                // (non-starters), which can be broken after but not before
                                (c >= CHAR_FIRST_CJK && isIdeographic(c, true) &&
                                j + 1 < spanEnd && isIdeographic(chs[j + 1 - paraStart], false));