Android7.0 系统添加默认输入法

需求

    将我们自己的输入法加到系统中,并设置成默认输入法。


具体实现

1、将输入法编入系统,一般可以将应用放到package/app/目录下,mk文件如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyIME
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_BUILT_MODULE_STEM := package.apk
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk

include $(BUILD_PREBUILT)

2、设置为默认输入法,diff如下:

------------ base/packages/SettingsProvider/res/values/defaults.xml ------------
index 9b50dc0..d46038c 100644
     <!-- Default for Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED -->
     <integer name="def_captive_portal_detection_enabled" translatable="false">1</integer>
+
+    <string name="config_default_input_method" translatable="false">com.test.myime/.MyIMEService</string>
+    <string name="config_enable_input_methods" translatable="false">com.test.myime/.MyIMEService</string>
 </resources>
 base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java 
index 998efd9..fcd5555 100644
@@ -2457,22 +2457,28 @@ class DatabaseHelper extends SQLiteOpenHelper {
 
             String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
             if (!TextUtils.isEmpty(wifiWatchList)) {
                 loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
             }
 
             // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
             // persistent system property instead.
             //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
 
             // Allow mock locations default, based on build
+
+            loadStringSetting(stmt, Settings.Secure.DEFAULT_INPUT_METHOD,
+                    R.string.config_default_input_method );
+            loadStringSetting(stmt, Settings.Secure.ENABLED_INPUT_METHODS,
+                    R.string.config_enable_input_methods );
+
             loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
                     "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
 
             loadSecure35Settings(stmt);
 
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
                     R.bool.def_mount_play_notification_snd);
 
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
                     R.bool.def_mount_ums_autostart);
这个修改其实就是让SettingProvider读取配置并加到数据库中,然后由 InputMethodService来加载默认输入法。

bug处理

    以上的修改如果是对于6.0系统就已经OK了,但是7.0有不一样的地方。经过分析,原来是当手机已经通电开机但是用户并有解锁锁屏的时候,Android N运行于一个安全的模式,也就是Dierect Boot模式。一般情况下,应用是无法在Direct Boot模式下运行的,如果需要某个app能够在Direct Boot模式下运行,需要注册相关APP的组件。

应用组件申请在Direct Boot模式下运行:在AndroidManinfest.xml中设置 android:directBootAware="true"。

在分析7.0过程中发现在启动Launcher之前会先启动一个FallbackHome,之后才会启动Launcher,通过调查发现FallbackHome属于Settings中的一个activity,Settings的android:directBootAware为true,并且FallbackHome在category中配置:

<application android:label="@string/settings_label"
            android:icon="@mipmap/ic_launcher_settings"
            ............
            android:directBootAware="true">
 
        <!-- Triggered when user-selected home app isn't encryption aware -->
        <activity android:name=".FallbackHome"
                  android:excludeFromRecents="true"
                  android:theme="@style/FallbackHome">
            <intent-filter android:priority="-1000">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

所以在ActivityManagerService启动Home界面时,从PackageManagerService中获取到的Home界面就是FallbackHome。

这个安全模式就会导致我的输入法在系统起来的时候服务没起来,进而导致输入法弹不出来。

解决方法

    在输入法的AndroidManifest.xml中声明android:directBootAware为true。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值