osfans / trime

同文安卓輸入法平臺3.x/Android-rime/Rime Input Method Engine for Android
http://osfans.github.io/trime/
GNU General Public License v3.0
3.08k stars 372 forks source link

按键振动强度调解失效 #494

Closed xlucn closed 2 years ago

xlucn commented 3 years ago

Describe the bug 在应用中设置按键振动强度,振动强度不变。

在我的手机上,即便振动时长调至最低(1毫秒),无论如何调节振动强度,振动仍然很强,无法调节至合适(以gboard默认为参照)的振感。

To Reproduce Steps to reproduce the bug:

  1. 进入Trime设置 => 键盘
  2. 打开“按键时振动”选项
  3. 调节“按键振动强度”数值
  4. 除了0之外,调节到任何数值,振动强度都一样

Expected behavior 振动强度相应改变。

Log

Screenshots

Smartphone (please complete the following information):

Additional context 问题最初谈及于#439,这里单独提交一次。

WhiredPlanck commented 3 years ago

目前已知这几个有滑动条的设置是有 Bug 的。但是我目前还没找出问题的关键。感谢反馈,之后我仔细研究一下

walk143 commented 3 years ago

相关问题:振动强度和振动时长的最小值需要调整为1。手动调整到0会导致程序崩溃

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.osfans.trime, PID: 24072
    java.lang.IllegalArgumentException: amplitude must either be DEFAULT_AMPLITUDE, or between 1 and 255 inclusive (amplitude=0)
        at android.os.VibrationEffect$OneShot.validate(VibrationEffect.java:493)
        at android.os.VibrationEffect.createOneShot(VibrationEffect.java:180)
        at com.osfans.trime.ime.core.TrimeKeyEffects.keyPressVibrate(TrimeKeyEffects.kt:74)
        at com.osfans.trime.ime.core.Trime.keyPressVibrate(Trime.java:774)
        at com.osfans.trime.settings.fragments.KeyboardFragment.onSharedPreferenceChanged(KeyboardFragment.kt:36)
        at android.app.SharedPreferencesImpl$EditorImpl.notifyListeners(SharedPreferencesImpl.java:612)
        at android.app.SharedPreferencesImpl$EditorImpl.apply(SharedPreferencesImpl.java:494)
        at com.osfans.trime.settings.components.DialogSeekBarPreference.showSeekBarDialog$lambda-6$lambda-3(DialogSeekBarPreference.kt:101)
        at com.osfans.trime.settings.components.DialogSeekBarPreference.lambda$iIanMggiVp0RpiKhpxaVgKgeYos(Unknown Source:0)
        at com.osfans.trime.settings.components.-$$Lambda$DialogSeekBarPreference$iIanMggiVp0RpiKhpxaVgKgeYos.onClick(Unknown Source:4)
        at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
        at android.os.Handler.dispatchMessage(Handler.java:110)
        at android.os.Looper.loop(Looper.java:219)
        at android.app.ActivityThread.main(ActivityThread.java:8668)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
I/Process: Sending signal. PID: 24072 SIG: 9
Disconnected from the target VM, address: 'localhost:43981', transport: 'socket'
WhiredPlanck commented 3 years ago

根据多次研究,振动强度调节并不是真的失效了。我手头的设备很遗憾没有线性马达,所以只提供普通马达的参考。

我个人的观察结果是,振动强度的明显程度主要受振动时长影响。只要振动时长调整一些,振动的强弱就有明显的区别。但是同一时长(比如默认的 100ms)下,只有非常强(比如 255)或者非常弱(比如 10)才可能有明显的差别。这和振动强度的数值算法有关。

最近在调整对线性马达的适配,这一部分的代码可能会和之前完全不同。所以可能直接用更新代替修复,敬请期待。

xlucn commented 3 years ago

Edit: 请跳过看下一个回复

@WhiredPlanck 我突发奇想,去调了一下Gboard的选项,发现一个现象,可能有帮助。

Gboard里也有振动强度的调节,其默认值是“系统默认”,这个振动是很合适的(我是一加8,线性马达),和系统(我用的Lineage OS)的振动(如按返回键)是一样的。这个选项可调节的值只有时长,0-100毫秒,当调节为任意时长后,即便是最小的1毫秒,依然比“系统默认”的振感要强很多,很粗暴突兀。可以这么说,我上面报告的现象同样适用Gboard:

在我的手机上,即便振动时长调至最低(1毫秒),无论如何调节振动强度,振动仍然很强,无法调节至合适(以gboard默认为参照)的振感。

转子马达不清楚,线性马达肯定不只有时长一个自由度的,肯定可以调节振幅。所以我觉得,Trime和Gboard在时长调节时,可能没有调节合适的振幅,而是默认将其拉满。而“系统默认”却调节了振幅,因此可以更柔和,更合适。

下面就是我胡猜的了,我不是安卓dev,很可能没道理。Gboard不太可能对每个机型/振动马达型号进行适配,那么它是怎么设置那么恰到好处的“系统默认”振动呢?同样,我用的Lineage OS也是第三方系统,它又是怎么实现合适的振动呢?会不会是一加的系统固件里有一些预装的振动参数设定。LOS应该是会出于硬件兼容性需要,将各种OEM固件拷到LOS上面;而Gboard又通过一些通用的标准,可以获取到这些设定?Trime能否也做到呢?

Edit: 好像我想多了?:(

https://developer.android.com/reference/android/os/VibrationEffect#DEFAULT_AMPLITUDE

https://github.com/osfans/trime/blob/6ec495544f5ff11cb603ec91bc8447d9dd971eeb/app/src/main/java/com/osfans/trime/ime/core/TrimeKeyEffects.kt#L62-L66

xlucn commented 3 years ago

@WhiredPlanck 对不起,又打扰了。我发现我的关注点转移到了能否达到最合适的振感,而不是成功调节振动强度。我姑且将错就错,再提一些,毕竟,能够把默认做得很合适,也是很重要的。

我发现当前3.2.2版本的振动时长和强度并不能设置为-1(默认值为10和0),那么下面的代码是不是永远不能运行:

https://github.com/osfans/trime/blob/a97b39c8de220861baaef5a88e60e3af0b1087b4/app/src/main/java/com/osfans/trime/ime/core/TrimeKeyEffects.kt#L48-L52

我做了些不专业的调查,感觉只有在用Haptics的时候,我手机上的(线性马达)振动才是适中的。得到这个结论参考了如simple keyboard的代码:

https://github.com/rkkr/simple-keyboard/blob/61da901f94a90b6cc1f1d234177db35a60bdea0b/app/src/main/java/rkr/simplekeyboard/inputmethod/latin/AudioAndHapticFeedbackManager.java#L105-L119

以及florisboard的代码:

https://github.com/florisboard/florisboard/blob/1c8523c6dd325007df45aee3d6aef043ec7f98fa/app/src/main/java/dev/patrickgold/florisboard/ime/keyboard/InputFeedbackManager.kt#L96-L131

根据我的尝试:

WhiredPlanck commented 3 years ago

@OliverLew 厉害,你说的八九不离十。

florisboard 的 InputFeedbackManager 是最近加的,我还没搞清楚它怎么用的。但是之前它确实给振动和按键音引入了个系统默认值。不过我当时图省事就先没加。我是想直接抄 florisboard 的成果,因为我自己的设备没有线性马达,一来不好调试,二来我可能也调不出来 QwQ

xlucn commented 3 years ago

谢谢你的确认!我不太会开发,调查到这个程度已经用了洪荒之力了XD,希望能有帮助。因为现在的新手机基本都是线性马达,所以我认为照顾得全面些会更好。 我觉得把simple keyboard的设置逻辑搬过来就可以(现在已经有强度和时长,设置默认值为调用Haptics API可能就行吧)。如果不方便测试,可以在其它什么地方发布nightly版,我们可以帮忙验证。

WhiredPlanck commented 3 years ago

谢谢你的确认!我不太会开发,调查到这个程度已经用了洪荒之力了XD,希望能有帮助。因为现在的新手机基本都是线性马达,所以我认为照顾得全面些会更好。 我觉得把simple keyboard的设置逻辑搬过来就可以(现在已经有强度和时长,设置默认值为调用Haptics API可能就行吧)。如果不方便测试,可以在其它什么地方发布nightly版,我们可以帮忙验证。

确实,florisboard 的那套逻辑蛮复杂的。我这几天再调节调节 ~

xlucn commented 2 years ago

我试了3.2.3,确实在线性马达上的振感适中了。但是,初始状态并不是这样的,虽然“时长”和“强度”是“系统默认”,还需要点一下“系统默认”才对。不知道是什么问题。

如果本issue及 #439 都仅仅是因为线性马达不适合采用之前的振动方法,那现在的状态就算解决了吧。参考上面举的几个例子,对于线性马达也都只有“系统默认”一种合适的选项,无法再调节强度了。

@WhiredPlanck 再次感谢!