在android服务中检测’home button pressed’事件,显示一个UI(类似于facebook chatheads)

在facebook chatheads中,这是facebook messenger应用程序的一部分,我注意到以下行为:据我所知,聊天头本身和打开的聊天屏幕都是服务的一部分。 不涉及任何活动。

我怎么能确定? 在我打开的聊天屏幕上按回家后,它被最小化回聊天头,我可以立即重新打开聊天屏幕。 如果聊天屏幕是活动,则在按下主页按钮后通过startActivity(intent)重新打开活动将延迟活动的开始,如此处所指定: 在没有5秒的情况下按下HOME按钮后从服务启动活动延迟

在这里: 按下主页按钮显示活动5秒延迟的原因?

在我的服务onCreate方法中,我使用以下代码显示来自服务的UI:

 public class ServiceTest extends Service { ... @Override public void onCreate() { super.onCreate(); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); windowManager.addView(someView, params); } .... } 

有没有人知道如何直接从显示UI的服务接收“主页按钮按下”事件? 当用户按下主页按钮时,我想最小化我的视图(类似于Facebook聊天头)。

  • Android - 图像按钮比例
  • Android:ViewPager卡在视图之间
  • 自定义标题栏没有填充(Android)
  • 试图了解ScrollView中LinearLayout的边距
  • 像素和缩放像素之间的关系是什么
  • 如何在Android屏幕中禁用选项卡?
  • 关于Android用户界面设计的书籍
  • 使用对象数组列表作为微调器适配器
  • 在对这个问题进行自己的研究之后,我得出了以下结论:

    Facebook通过提供标志TYPE_SYSTEM_OVERLAY属性“拦截”导航按钮。 看看这个由@jawsware提供的post答案

    做他建议不做的事 – 将导致控制导航按钮的“影响”

    使用此标志可以将焦点放在叠加层上,并从后面的活动中获得焦点。

    使用onFocusChangedListener视图回调或OnKey侦听器,它们会关闭叠加层的全屏模式。

    这也解释了他们如何通过3个导航按钮 – 主页/后退/最近的任务对它做出反应

    您可以通过重写View.onCloseSystemDialogs()来实现它。 您可能需要检查View.java,因为此方法在API doc中不可见。

    显然,我们一般都无法检测到“按下主页按钮”。 在大多数情况下,窗口由startActivity()创建。 并且由’Home button pressed’引起的CloseSystemDialogs例程由android框架的内部类,PhoneWindow.DecorView作为ViewRootImpl的视图祖先处理。 但是当我们直接向窗口管理器添加视图时,查看ViewRootImpl的祖先是我们的自定义视图,而不是PhoneWindow.DecorView。 检查ViewRootImpl.java的源代码可能更容易理解。

    KeyEvent.KEYCODE_APP_SWITCH也导致closeSystemDialogs例程。 这解释了facebook chatheads的工作原理。

    好的,完整编辑我的答案,

    在您的活动中覆盖以下方法。

      @Override public void onAttachedToWindow() { super.onAttachedToWindow(); this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD); } 

    覆盖上述方法后,现在您可以使用onKeyDown()方法轻松收听活动中的HOME键。

      @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_HOME) { //The Code Want to Perform. } }); 

    试试这个希望它有所帮助

    您可以监控(例如每200毫秒检查一次)最常运行的活动,看看它是您的活动还是其他活动,并知道它何时发生变化。 这也可以让您处理来电等情况。

     ActivityManager am = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE); am.getRunningTasks(1).get(0).topActivity... 

    这是我的方式。 它工作正常。 把它放在onReceive()函数中。

     if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { String reason = intent.getStringExtra(SYSTEM_REASON); //Toast.makeText(context,"ACTION_CLOSE_SYSTEM_DIALOGS : Reason : " + reason ,Toast.LENGTH_LONG).show(); // Detect home screen key press or "recent app" key pressed when screen is in unlocked state if (reason != null) { if (reason.equals(SYSTEM_HOME_KEY)) { // For Home press } else if (reason.equals(SYSTEM_RECENT_APPS)) { // For long press } } } 

    我很确定facebook不会听主页按键,因为他们的逻辑要求聊天头出现,无论应用程序是什么,只要它不是facebook。

    执行此操作的一种简单粗暴的方法是在应用程序单例中维护一个静态标志,并从您拥有的每个Activity中修改它。 在onPause()中,将其设置为false ,并在onResume()和onCreate()中将其设置为true

    然后只需检查此标志的状态,并采取相应措施。 如果是真的,则表示您的应用是可见的。

    您可能希望在对其执行操作之前添加一个小暂停,以防止每次更改活动时注入的视图都会闪烁。

    这是工作示例代码。

     mLinear = new LinearLayout(getApplicationContext()) { //home or recent button public void onCloseSystemDialogs(String reason) { //The Code Want to Perform. } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_CAMERA ) { //The Code Want to Perform. } return super.dispatchKeyEvent(event); } }; mLinear.setFocusable(true); View mView = inflate.inflate(R.layout.floating_panel_layout, mLinear); WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); //params WindowManager.LayoutParams params = new WindowManager.LayoutParams( width, height, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, PixelFormat.TRANSLUCENT); params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL; wm.addView(mView, params); 

    您可以将类别HOME添加到清单文件中。