草庐IT

android - 升级到 AppCompat v22.1.0 现在按下菜单键时不会触发 onKeyDown 和 onKeyUp

coder 2023-06-09 原文

我刚刚升级了我的应用程序以使用新发布的 v22.1.0 AppCompat,现在按下菜单键时不会触发 onKeyDownonKeyUp。其他键正确触发 onKeyDownonKeyUp,但是当我按下菜单键时没有任何反应。如果我降级到 v22.0.0,一切都会恢复正常。

我该如何解决?

最佳答案

8 月 23 日更新

这个 has been fixed再次在 appcompat-v7 支持库的 v23.0.0 中。更新到最新版本来解决这个问题。


7 月 19 日更新

不幸的是,AppCompat v22.2.1 破坏了 onKeyDownonKeyUp 事件 again .我刚刚更新了 AppCompatActivityMenuKeyInterceptor 以支持 v22.1.x 和 v22.2.1


5 月 29 日更新

这个 has been fixed在 appcompat-v7 支持库的 v22.2.0 中。更新到最新版本来解决这个问题。


不幸的是,AppCompat v22.1.0 拦截了 onKeyDownonKeyUp 事件,并且在按下菜单键时不会传播它们。唯一可能的解决方案是使用反射在 AppCompat 之前拦截 onKeyDownonKeyUp 事件。

将此类添加到您的项目中:

public class AppCompatActivityMenuKeyInterceptor {

    private static final String FIELD_NAME_DELEGATE = "mDelegate";
    private static final String FIELD_NAME_WINDOW = "mWindow";

    public static void intercept(AppCompatActivity appCompatActivity) {
        new AppCompatActivityMenuKeyInterceptor(appCompatActivity);
    }

    private AppCompatActivityMenuKeyInterceptor(AppCompatActivity activity) {
        try {
            Field mDelegateField = AppCompatActivity.class.getDeclaredField(FIELD_NAME_DELEGATE);
            mDelegateField.setAccessible(true);
            Object mDelegate = mDelegateField.get(activity);

            Class mDelegateClass = mDelegate.getClass().getSuperclass();
            Field mWindowField = null;

            while (mDelegateClass != null) {
                try {
                    mWindowField = mDelegateClass.getDeclaredField(FIELD_NAME_WINDOW);
                    break;
                } catch (NoSuchFieldException ignored) {
                }

                mDelegateClass = mDelegateClass.getSuperclass();
            }

            if (mWindowField == null)
                throw new NoSuchFieldException(FIELD_NAME_WINDOW);

            mWindowField.setAccessible(true);
            Window mWindow = (Window) mWindowField.get(mDelegate);

            Window.Callback mOriginalWindowCallback = mWindow.getCallback();
            mWindow.setCallback(new AppCompatWindowCallbackCustom(mOriginalWindowCallback, activity));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private class AppCompatWindowCallbackCustom extends WindowCallbackWrapper {

        private WeakReference<AppCompatActivity> mActivityWeak;

        public AppCompatWindowCallbackCustom(Window.Callback wrapped, AppCompatActivity appCompatActivity) {
            super(wrapped);

            mActivityWeak = new WeakReference<AppCompatActivity>(appCompatActivity);
        }

        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            final int keyCode = event.getKeyCode();

            AppCompatActivity appCompatActivity = mActivityWeak.get();

            if (appCompatActivity != null && keyCode == KeyEvent.KEYCODE_MENU) {
                if (appCompatActivity.dispatchKeyEvent(event))
                    return true;
            }

            return super.dispatchKeyEvent(event);
        }
    }
}

在你的activity的onCreate中调用AppCompatActivityMenuKeyInterceptor.intercept(this):

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Initialize the interceptor
        AppCompatActivityMenuKeyInterceptor.intercept(this);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // Now onKeyDown is called also for KEYCODE_MENU
        if (keyCode == KeyEvent.KEYCODE_MENU) {
            //do your stuff

            //return false if you want to propagate the
            //KeyEvent to AppCompat, return true otherwise
            return false;
        }

        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        // Now onKeyUp is called also for KEYCODE_MENU
        if (keyCode == KeyEvent.KEYCODE_MENU) {
            //do your stuff

            //return false if you want to propagate the
            //KeyEvent to AppCompat, return true otherwise
            return false;
        }

        return super.onKeyUp(keyCode, event);
    }
}

如果您使用 ProGuard 或 DexGuard,请将这些规则添加到您的配置中:

-keepclassmembers class android.support.v7.app.AppCompatActivity {
    private android.support.v7.app.AppCompatDelegate mDelegate;
}

-keepclassmembers class android.support.v7.app.AppCompatDelegateImplBase {
    final android.view.Window mWindow;
}

现在您的 Activity 也可以接收菜单键的 onKeyDownonKeyUp 事件。

关于android - 升级到 AppCompat v22.1.0 现在按下菜单键时不会触发 onKeyDown 和 onKeyUp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29852303/

有关android - 升级到 AppCompat v22.1.0 现在按下菜单键时不会触发 onKeyDown 和 onKeyUp的更多相关文章

  1. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  4. ruby - 在不使用 RVM 的情况下在 Mac 上卸载和升级 Ruby - 2

    我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案

  5. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  6. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  7. ruby-on-rails - 从 Rails 2.3 升级到 Rails 4.0 - 2

    我们有一个目前在Rails2.3.12版和Ruby1.8.7版上运行的应用程序。我们想将我们的应用程序更新到Rails4.0和Ruby2.1.0。我们有大约200个模型和150个Controller。我想知道升级过程需要多大的努力。您还可以提供升级可以遵循的步骤。我们应该先升级Ruby然后再升级Rails还是相反? 最佳答案 您想要实现的目标将是史诗般的努力。我无法为您提供分步说明,因为不可能在一个答案中涵盖所有情况。我建议不要同时升级Ruby和Rails,而是分步升级。升级本身的复杂性是巨大的,但只要您的应用程序具有合理的测试覆盖

  8. ruby-on-rails - Rails 4.1.0.beta1 升级失败 - 2

    我最近尝试安装rails4.1.0.beta1,但是railss导致以下错误。[RVM]/gems/ruby-2.0.0-p247/gems/activesupport-4.1.0.beta1/lib/active_support/core_ext/module/aliasing.rb:32:in`alias_method':undefinedmethod`graft'forclass`ActiveRecord::Associations::JoinDependency'(NameError)[RVM]/gems/ruby-2.0.0-p247/gems/activesupport-4

  9. ruby-on-rails - ActionCable 无需升级到 Rails 5 beta - 2

    我目前有一个运行在4.2.5上的Rails应用程序,我想使用ActionCable而不必将整个应用程序升级到Rails5.0.0.beta3版本并冒破坏所有其他gem的风险。按照我在互联网上看到的指南,我已经尝试过gem'actioncable',github:'rails/actioncable'这不起作用,因为ActionCable存储库已合并到Rails存储库中。我什至试过gem'actioncable',github:'rails/rails'但这似乎不适用于ActionCable合并到Rails时发生的版本重新编号。(唯一低于5.0.0.beta*的版本是0.0.0,这似乎是

  10. ruby-on-rails - Rails 5 升级 :/actionpack-5. 0.0/lib/action_controller/test_case.rb:49:in `initialize':参数数量错误(0 代表 2)(ArgumentError) - 2

    我最近正在进行Rails5升级,当我尝试启动Rails控制台时遇到了这个错误:/actionpack-5.0.0/lib/action_controller/test_case.rb:49:ininitialize':wrongnumberofarguments(0for2)(ArgumentError)当前bundleupdaterails已经完成了gem依赖项的解决,足以更新到5.0.0,rspec正在运行(尽管我正在修复很多中断)。我也可以运行railss没有错误。这里是代码中断行:https://github.com/rails/rails/blob/master/action

随机推荐