Android AOSP定制默认输入法为讯飞输入法

news2024/11/10 16:16:23

Android AOSP定制默认输入法为讯飞输入法

前言:

​ 最近在公司的项目中发现默认的输入法非常不好用,而且默认输入法中英文切换非常麻烦,被用户吐槽定制的AOSP镜像体验不好,于是查找资料,研究了一番,尝试了搜狗、百度和讯飞三大著名的输入法,最后选择了适合我们的讯飞输入法.本文就讲解一下在AOSP中如何定制默认的输入法.

1.下载讯飞输入法apk:

建议去官网下载,如果官网下载的有问题去apkmirror这个网站下载,基本上都是正版可以使用的apk,我的gms服务三件套都是在此网站下载的,都是可以正常使用》

https://www.apkmirror.com/

2.把apk放到系统目录下:

具体目录如下:

vendor/common/android/gms/iFlyInPut/iFlyInPut.apk:system/priv-app/iFlyInPut/iFlyInPut.apk

在这里插入图片描述

3.这里有2种配置方式:

3.1 第1种方式以mk文件方式:

3.2 新建一个文件目录和mk文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := GoogleLoginService
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := APPS
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_PRIVILEGED_MODULE := true
LOCAL_DEX_PREOPT := false

include $(BUILD_PREBUILT)

在这里插入图片描述

3.3 把apk放到此文件同名的目录下:

在这里插入图片描述

4.第2种方式

4.1 新建一个放讯飞输入法的目录:

把下载好的讯飞输入法apk放到此文件目录下.

在这里插入图片描述

4.2 添加apk配置到系统目录:

在product_extra文件中添加如下配置:一般AOSP源码都有此目录,做过AOSP定制的小伙伴应该都明白,这里就不过多讲解了,后面讲解GMS定制的时候在具体讲解每个目录和文件的含义.

vendor/common/android/gms/iFlyInPut/iFlyInPut.apk:system/priv-app/iFlyInPut/iFlyInPut.apk

4.3 完整的文件配置如下:

这里有几个比较重要的应用:

  • Google服务框架: GoogleServicesFramework;
  • Google核心服务:PrebuiltGmsCore
  • GooglePlay:Phonesky;(google商店)
#
# Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
# Description: product extra config
#
IS_GMS_LUNCH = true

PRODUCT_PACKAGES += \
    GoogleServicesFramework \  
    PrebuiltGmsCore \     
    GoogleLoginService \  
    Phonesky \           

PRODUCT_COPY_FILES += \
      vendor/common/android/gms/system/etc/permissions/extend.xml:system/etc/permissions/extend.xml \
      vendor/common/android/gms/system/etc/sysconfig/google.xml:system/etc/sysconfig/google.xml \
      $(call find-copy-subdir-files,*,vendor/common/android/gms/Phonesky/split,system/priv-app/Phonesky) \
      $(call find-copy-subdir-files,*,vendor/common/android/gms/PrebuiltGmsCore/split,system/priv-app/PrebuiltGmsCore) \
      vendor/common/android/gms/GoogleChrome/GoogleChrome.apk:system/priv-app/GoogleChrome/GoogleChrome.apk \
      vendor/common/android/gms/iFlyInPut/iFlyInPut.apk:system/priv-app/iFlyInPut/iFlyInPut.apk

5.添加讯飞输入法:

在系统源码路径:/framefork/base/packages/SettingsProvider/res/values/defaults文件添加如下配置:

每个输入法的包名和服务不一样,可根据自己的业务进行对应的配置,本文只是以讯飞为例子,大家需要自行修改.

<!-- 设置默认输入法 -->
<string name="enabled_input_methods" translatable="false">com.iflytek.inputmethod/.FlyIME</string>

<string name="default_input_method" translatable="false">com.iflytek.inputmethod/.FlyIME</string>

在这里插入图片描述

6.设置讯飞输入法为默认输入法:

找到源码路径:/framefork/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper

在文件DatabaseHelper添加如下设置讯飞输入法为默认输入法,代码如下:

  //add start
    loadStringSetting(stmt, Settings.Secure.DEFAULT_INPUT_METHOD,R.string.enabled_input_methods);
    loadStringSetting(stmt, Settings.Secure.ENABLED_INPUT_METHODS,R.string.default_input_method);
    //add end

完整修改代码如下:
private void loadSecureSettings(SQLiteDatabase db) {
        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                    + " VALUES(?,?);");

            // 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
            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);

            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
                    R.bool.def_mount_ums_prompt);

            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
                    R.bool.def_mount_ums_notify_enabled);

            loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
                    R.integer.def_long_press_timeout_millis);

            loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
                    R.bool.def_touch_exploration_enabled);

            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
                    R.bool.def_accessibility_speak_password);

            if (SystemProperties.getBoolean("ro.lockscreen.disable.default", false) == true) {
                loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1");
            } else {
                loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
                        R.bool.def_lockscreen_disabled);
            }

            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED,
                    com.android.internal.R.bool.config_dreamsEnabledByDefault);
            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
                    com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
            loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
                    com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
            loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS,
                    com.android.internal.R.string.config_dreamsDefaultComponent);
            loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
                    com.android.internal.R.string.config_dreamsDefaultComponent);

            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
                    R.bool.def_accessibility_display_magnification_enabled);

            loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
                    R.fraction.def_accessibility_display_magnification_scale, 1);

            loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
                    R.bool.def_user_setup_complete);

            loadStringSetting(stmt, Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
                        R.string.def_immersive_mode_confirmations);

            loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
                    R.bool.def_install_non_market_apps);

            loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
                    R.bool.def_wake_gesture_enabled);

            loadIntegerSetting(stmt, Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
                    R.integer.def_lock_screen_show_notifications);

            loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
                    R.bool.def_lock_screen_allow_private_notifications);

            loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
                    R.integer.def_sleep_timeout);

            //add start
            loadStringSetting(stmt, Settings.Secure.DEFAULT_INPUT_METHOD,R.string.enabled_input_methods);
            loadStringSetting(stmt, Settings.Secure.ENABLED_INPUT_METHODS,R.string.default_input_method);
            //add end

            /*
             * IMPORTANT: Do not add any more upgrade steps here as the global,
             * secure, and system settings are no longer stored in a database
             * but are kept in memory and persisted to XML.
             *
             * See: SettingsProvider.UpgradeController#onUpgradeLocked
             */
        } finally {
            if (stmt != null) stmt.close();
        }
    }

    private void loadSecure35Settings(SQLiteStatement stmt) {
        loadBooleanSetting(stmt, Settings.Secure.BACKUP_ENABLED,
                R.bool.def_backup_enabled);

        loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
                R.string.def_backup_transport);
    }

在这里插入图片描述

7.设置讯飞输入法默认权限:

7.1 找到源码路径/framefork/base/data/etc/

7.2 在privapp-permissions-platform文件中添加如下配置:

主要是解决用户打开输入法还需要授权的问题,这种每个手机和用户都要去授权很麻烦,也不符合现代化的用户体验,于是在定制的时候就要考虑好用户权限授权问题.

<privapp-permissions package="com.iflytek.inputmethod.miui">
    <permission name="android.permission.REBOOT"/>
    <permission name="android.permission.RECOVERY"/>
    <permission name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <permission name="android.permission.READ_EXTERNAL_STORAGE"/>
    <permission name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
    <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <permission name="android.permission.RECEIVE_BOOT_COMPLETED"/>
</privapp-permissions>

在这里插入图片描述

8.实现的效果如下:

可以看到开机后打开浏览器或者app的输入法,默认就是调用的讯飞输入法,基本上就完成了本次的把讯飞输入法定制为默认输入法的定制需求.

在这里插入图片描述

9.总结:

当然这里还有一个小问题,就是用户首次打开输入法的时候会有一个隐私协议的授权弹框,既然是定制系统,这块其实也可以考虑,我们是采用首次打开app的时候调起输入法利用无障碍服务自动点击同意或者拒绝隐私协议的方式解决这个体验问题,方式有很多,这里就不详细讲解了,大家可以自己尝试解决.基本上是一个很完整的定制过程,感兴趣的小伙伴可以自行尝试,实战才是检验一切的最好老师.

今天的AOSP定制实现还是遇到很多问题的:

  • 比如apk定制好之后能不能正常使用?
  • 如何把讯飞输入法定制为默认输入法?而不是需要用户主动去切换选择?
  • 怎么默认授权文件读写、录音等权限?
  • 怎么在用户首次打开输入法时自动点击同意或者拒绝隐私政策?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2095615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】日期类函数(时间计数器)从无到有实现

欢迎来到HarperLee的学习笔记&#xff01; 博主主页传送门&#xff1a;HarperLee的博客主页 个人语录&#xff1a;他强任他强&#xff0c;清风拂山岗&#xff01; 一、前期准备 1.1 检查构造的日期是否合法 bool Date::CheckDate() {if (_month < 1 || _month > 12|| _d…

vercel免费在线部署TodoList网页应用

参考&#xff1a; TodoList网页应用&#xff1a;https://blog.csdn.net/weixin_42357472/article/details/140909096 1、项目首先上传github 直接vscode自带的上传项目&#xff0c;commit后在创建项目上传即可 2、vercel部署项目 1&#xff09;先注册 2&#xff09;impor…

基于PHP评论区的存储型XSS漏洞

评论区的XSS漏洞是指攻击者在评论区输入恶意脚本&#xff0c;当其他用户浏览该页面时&#xff0c;这些恶意脚本会被执行&#xff0c;从而造成安全威胁。这种漏洞通常出现在网站没有对用户输入进行充分过滤和转义的情况下&#xff0c;为存储型XSS。存储型XSS攻击是指攻击者在目标…

【MCAL】TC397+EB-tresos之SPI配置实战 - (同步/异步)

本篇文章首先从理论讲起&#xff0c;从AUTOSAR规范以及MCAL手册两个不同角度&#xff08;前者偏理论&#xff0c;后者偏实践&#xff09;介绍了SPI模块的背景概念与理论&#xff0c;帮助读者在实际配置之前能有个理论的框架。然后详细的介绍了在TC397平台使用EB tresos对SPI驱动…

数智化粮仓综合监控管理系统设计方案WORD-2023

关注智慧方案文库&#xff0c;学习9000多份智慧城市智慧医院&#xff0c;智慧水利&#xff0c;智能制造&#xff0c;数字化转型&#xff0c;智慧工厂&#xff0c;智慧矿山&#xff0c;智慧交通&#xff0c;智慧粮仓&#xff0c;工业互联网&#xff0c;数字孪生......持续更新热…

SpringCloud Alibaba】(十三)学习 RocketMQ 消息队列

目录 1、MQ 使用场景与选型对比1.1、MQ 的使用场景1.2、引入 MQ 后的注意事项1.3、MQ 选型对比 2、下载、安装 RocketMQ 及 RocketMQ 控制台2.1、下载安装 RocketMQ2.2、测试 RocketMQ 环境2.3、RocketMQ 控制台【图形化管理控制台】2.3.1、下载、安装2.3.2、验证 RocketMQ 控制…

【困难】 猿人学web第一届 第14题 备而后动-勿使有变

调试干扰 进入题目 打开开发者工具会进入一个无限 debugger; 向上查看堆栈&#xff0c;可以找到生成 debugger 的代码段 手动解混淆后可以知道 debugger 生成的方式 (function () {// 函数内的代码是不需要的&#xff0c;因为里面的代码不会执行 }[constructor](debugger)[call…

Java并发编程面试必备:如何创建线程池、线程池拒绝策略

一、线程池 1. 线程池使用 1.1 如何配置线程池大小 如何配置线程池大小要看业务系统执行的任务更多的是计算密集型任务&#xff0c;还是I/O密集型任务。大家可以从这两个方面来回答面试官。 &#xff08;1&#xff09;如果是计算密集型任务&#xff0c;通常情况下&#xff…

模型 ACT心理灵活六边形

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。接纳现实&#xff0c;灵活行动&#xff0c;追求价值。 1 ACT心理灵活六边形的应用 1.1 应对工作压力 背景&#xff1a; 在高压的工作环境中&#xff0c;员工经常面临巨大的工作压力&#xff0c;这可…

在VScode中使用Git将本地已有文件夹提交到Github仓库以便于使用版本控制进行项目开发

前置软件 VScode、Git。 Linux系统中安装Git工具请自行百度。可以通过git --version查看对应Git版本号。 Github创建空白仓库 一定要注意创建空白仓库&#xff0c;不要包含任何文件&#xff0c;包括Readme.md文件也不能有。 上面的仓库名&#xff08;Repository name&#xff…

Kaggle克隆github项目+文件操作+Kaggle常见操作问题解决方案——一文搞定,以openpose姿态估计项目为例

文章目录 前言一、Kaggle克隆仓库1、克隆项目2、查看目录 二、安装依赖三、文件的上传、复制、转移操作1.上传.pth文件到input目录2、将权重文件从input目录转移到工作目录 三、修改工作目录里的文件内容1、修改demo_camera.py内容 四、运行&#xff01; 前言 想跑一些深度学习…

【网络安全】条件竞争绕过电子邮件验证

未经许可,不得转载。 文章目录 正文正文 目标:xxx.com 使用电子邮件注册该网站并登录。接着,进入帐户设置,进入更改电子邮件功能: 请求包如下: 接着,发送两个相同的请求包到repeater,第一个中添加攻击者邮件: 第二个中添加正常的邮件: 创建组,以便能够同时发送两个…

手把手教你如果安装激活CleanMyMac X 4.15.6中文破解版

CleanMyMac X 4.15.6中文破解版可以为Mac腾出空间&#xff0c;软件已经更新到CleanMyMac X 4.15.6中文版支持最新版Macos 10.14系统。CleanMyMac X 4.15.6中文破解版具有一系列巧妙的新功能&#xff0c;可让您安全&#xff0c;智能地扫描和清理整个系统&#xff0c;删除大量未使…

NeRF: Representing Scenes asNeural Radiance Fields for View Synthesis 论文解读

目录 一、导言 二、NeRF 1、渲染和反渲染 2、NeRF的基本原理 3、采样点 4、位置编码 5、NeRF网络结构 6、体渲染 三、分层采样 1、均匀采样 2、基于σ的采样 四、损失函数 一、导言 该论文来自于ECCV2020&#xff0c;主要提到一种NeRF的方法来合成复杂场景下的新视…

创建 AD9361 的 vivado 工程,纯FPGA配置,不使用ARM程序

前言 AD9361 的配置程序&#xff0c;如果使用官方的&#xff0c;就必须用ps进行配置&#xff0c;复杂不好使&#xff0c;如果直接使用FPGA配置&#xff0c;将会特别的简单。 配置软件 创建一份完整的寄存器配置表 //*******************************************************…

续:docker 仓库数据传输加密

上一个实验&#xff1a;非加密的形式在企业中是不被允许的。 示例&#xff1a;【为Registry 提供加密传输】 因为传输也是https&#xff0c;所以与ssh一样的加密。 ## 这种方式就不用写这个了。 [rootdocker ~]# cat /etc/docker/daemon.json #{ # "insecure-registrie…

GoodSync Business - 企业级服务器同步与备份工具

现在越来越多公司会搭建服务器&#xff0c;或自建文件共享中心。那么如何才能实现对这些终端的高效管理、安全备份&#xff0c;以保障企业数据的安全呢&#xff1f; GoodSync Business 就是一款企业服务器同步与备份工具&#xff0c;适用于 Win / Mac 工作站&#xff0c;以及 …

C语言程序设计

日落有个小商店&#xff0c;贩卖着橘黄色的温柔。 7.关系操作符 > > < < ! (用于测试“不相等”) &#xff08;用于测试“相等”&#xff0c;但是不是所有的对象都可以用该符号来比较相不相等&#xff09; eg. int main ( ) { if ("abc"&q…

【AI大模型】基于docker部署向量数据库Milvus和可视化工具Attu详解步骤

&#x1f680; 作者 &#xff1a;“大数据小禅” &#x1f680; 文章简介 &#xff1a;本专栏后续将持续更新大模型相关文章&#xff0c;从开发到微调到应用&#xff0c;需要下载好的模型包可私。 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 目…

【王树森】Few-Shot Learning (2/3): Siamese Network 孪生网络(个人向笔记)

Learning Pairwise Similarity Scores Training Data 训练集有很多个类别的图片&#xff0c;每个类别的图片都有标注 Positive Sample&#xff1a;我们需要正样本来告诉神经网路什么东西是同一类 Negative Sample&#xff1a;负样本可以告诉神经网路事物之间的区别 我们用…