找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 98|回复: 1

[教程] 一个Renpy打包安卓游戏的不调用安全输入法的解决方法

[复制链接]
发表于 昨天 13:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 blurred 于 2025-10-4 13:16 编辑

前言:
1.此方法由"我"单独提出,实现,测试
2.本方案在Ren'py-8.3.7能够实现效果,如果使用,请注意引擎版本

3.涉及到修改引擎的代码,所以请在事前把引擎目录下的rapt相关文件备份
3.学习操作门槛:需要一定的java小基础以及了解Android应用的相关特性
(包括但不限于一些基础的apk知识,apk的文件结构以及其rapt各个文件作用和内容)

4.你使用了这个方案来屏蔽安全键盘,可以在游戏名单标上“浅唱”,不标也没关系
5.此方案还是有风险,具体看文尾
(其实是只要是修改了源码的都存在风险)

本帖参考:
一个Renpy游戏打包apk资源加密方案 - 经验教程 -
RenPy中文空间一个Renpy安卓打包游戏通过安卓平台审核方案 - 经验教程 - RenPy中文空间
包索引  |  API 参考  |  Android 开发者 --- Package Index  |  API reference  |  Android Developers
压缩包:(懒得看帖子可以一键解压即可食用)(内置食用教程和餐具)
https://www.renpy.cn/forum.php?mod=attachment&aid=MTY2OHxhOGRjYjUzYnwxNzU5NjEzNDUxfDB8
效果预览:
Screenshot_2025-10-04-11-56-34-206_asasdas.safji.jpg
(注意我没有自己关闭安全键盘)
Screenshot_2025-10-04-11-56-47-938_com.android.se.jpg
方法思路、代码讲解和配置教程:
配置教程在压缩包里面有
在renpy中,我们打包安卓游戏的时候时常会出现:
“欸,为什么我在游戏里面的输入框在手机上一直调用安全键盘?”
“啊啊啊我想要输入中文”
当我们需要输入中文只能让玩家自己去设置关闭安全键盘,这十分的不方便,所以我们需要修改renpy中关于安卓构建部分的源码
通过对安卓的认识,我们可以快速了解到安卓构建的对于安卓系统接口在ranpyandroid中,当我们观察renpy关于安卓的5355个文件,可以简单地注意到:
位于renpyandroid\src\main\java\org\libsdl\app的SDLActivity.java处理了安卓
  • 应用生命周期管理(创建、暂停、恢复、销毁)
  • 输入事件处理(触摸、键盘、传感器)
  • 窗口管理、全屏控制
  • 剪贴板、消息框、URL打开等系统功能


那么,我们阅读到以下代码,可以发现这里处理了虚拟文本编辑器视图专门处理软键盘输入和硬件键盘事件。
[RenPy] 纯文本查看 复制代码
class DummyEdit extends View implements View.OnKeyListener {
    InputConnection ic;

    public DummyEdit(Context context) {
        super(context);
        setFocusableInTouchMode(true);
        setFocusable(true);
        setOnKeyListener(this);
    }

    @Override
    public boolean onCheckIsTextEditor() {
        return true;
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        /*
         * This handles the hardware keyboard input
         */
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (SDLActivity.isTextInputEvent(event)) {
                ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
                return true;
            }
            SDLActivity.onNativeKeyDown(keyCode);
            return true;
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            SDLActivity.onNativeKeyUp(keyCode);
            return true;
        }
        return false;
    }

    //
    @Override
    public boolean onKeyPreIme (int keyCode, KeyEvent event) {
        // As seen on StackOverflow: [url=http://stackoverflow.com/questions/7634346/keyboard-hide-event]http://stackoverflow.com/questions/7634346/keyboard-hide-event[/url]
        // FIXME: Discussion at [url=http://bugzilla.libsdl.org/show_bug.cgi?id=1639]http://bugzilla.libsdl.org/show_bug.cgi?id=1639[/url]
        // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
        // FIXME: A more effective solution would be to assume our Layout to be RelativeLayout or LinearLayout
        // FIXME: And determine the keyboard presence doing this: [url=http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android]http://stackoverflow.com/questio ... keyboard-in-android[/url]
        // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
        if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
            if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) {
                SDLActivity.onNativeKeyboardFocusLost();
            }
        }
        return super.onKeyPreIme(keyCode, event);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        ic = new SDLInputConnection(this, true);

        outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
        outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
                | EditorInfo.IME_FLAG_NO_FULLSCREEN /* API 11 */;

        return ic;
    }
}

其中的InputConnection:用于与输入法编辑器(IME)通信的接口,源码中的TYPE_TEXT_VARIATION_VISIBLE_PASSWORD字样就是向系统说明输入类型为密码,从而触发安全输入法导致无法输入中文
[RenPy] 纯文本查看 复制代码
 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
        outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
                | EditorInfo.IME_FLAG_NO_FULLSCREEN /* API 11 */;

那么,我们将它改为
[RenPy] 纯文本查看 复制代码
        outAttrs.inputType = InputType.TYPE_CLASS_TEXT | 
                            InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS |
                            InputType.TYPE_TEXT_VARIATION_NORMAL;

        outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI |
                            EditorInfo.IME_FLAG_NO_FULLSCREEN |
                            EditorInfo.IME_ACTION_DONE;


就可以实现将密码类型改为正常文本类型,从而使得系统不调用安全输入法,而食用正常的默认输入法
完整修改代码:(这里只贴出DummyEdit ,因为整个文件全部有2.4k行
[RenPy] 纯文本查看 复制代码
class DummyEdit extends View implements View.OnKeyListener {
    InputConnection ic;

    public DummyEdit(Context context) {
        super(context);
        setFocusableInTouchMode(true);
        setFocusable(true);
        setOnKeyListener(this);
    }

    @Override
    public boolean onCheckIsTextEditor() {
        return true;
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        /*
         * This handles the hardware keyboard input
         */
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (SDLActivity.isTextInputEvent(event)) {
                ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
                return true;
            }
            SDLActivity.onNativeKeyDown(keyCode);
            return true;
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            SDLActivity.onNativeKeyUp(keyCode);
            return true;
        }
        return false;
    }

    //
    @Override
    public boolean onKeyPreIme (int keyCode, KeyEvent event) {
        // As seen on StackOverflow: [url=http://stackoverflow.com/questions/7634346/keyboard-hide-event]http://stackoverflow.com/questions/7634346/keyboard-hide-event[/url]
        // FIXME: Discussion at [url=http://bugzilla.libsdl.org/show_bug.cgi?id=1639]http://bugzilla.libsdl.org/show_bug.cgi?id=1639[/url]
        // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
        // FIXME: A more effective solution would be to assume our Layout to be RelativeLayout or LinearLayout
        // FIXME: And determine the keyboard presence doing this: [url=http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android]http://stackoverflow.com/questio ... keyboard-in-android[/url]
        // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
        if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
            if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) {
                SDLActivity.onNativeKeyboardFocusLost();
            }
        }
        return super.onKeyPreIme(keyCode, event);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        ic = new SDLInputConnection(this, true);

        outAttrs.inputType = InputType.TYPE_CLASS_TEXT | 
                            InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS |
                            InputType.TYPE_TEXT_VARIATION_NORMAL;
        

        outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI |
                            EditorInfo.IME_FLAG_NO_FULLSCREEN |
                            EditorInfo.IME_ACTION_DONE;


        
        
        return ic;
    }
}

闲言:
1.在github中,pytom对于安全输入法的回复是
屏幕截图 2025-10-04 125658.png
不可置否,确实可能存在这样的问题,所以对于我这个方案,仍然存在对于非ASCLL字符处理导致出错的问题,但是至少我目前没遇到
2.在花费了快一周的时间解决这个问题的探索过程中,我发现关于安卓部分,文档仍然有不少东西是没说的,例如系统广播,更多的传感器调用等,也有可能是这一部分并不是tom直接负责,总体上安卓部分的内容对于安卓系统的兼容做的还是挺不错,但其内容冗杂实在...我甚至能在这里面看到2010年的开源项目...
3.关于SDL和rapt,tom也在图中表示会在SDL3更新中解决这个问题,希望有更好的处理方案。



安全键盘屏蔽--by 浅唱.zip

16.4 KB, 下载次数: 1, 下载积分: 活力 100

第一版

发表于 昨天 20:55 | 显示全部楼层
刚遇到了这个问题就见到了大佬的解决方案,感谢
回复 支持 抱歉

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号|苏公网安备 32092302000068号 )

GMT+8, 2025-10-5 05:30 , Processed in 0.049058 second(s), 29 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表