覆盖服务 - 按下按钮按下

时间:2015-07-16 18:43:50

标签: android service overlay back

我该怎么做?

当前解决方案

我发起了一个透明的活动,它抓住了背压,然后将它转发给我的服务并随后关闭。但是这项活动将在当前的运行活动中显现,因此它不是一个非常漂亮的解决方案。

看到的解决方案

我已经看到一个应用程序能够在服务中抓住背压 - 没有一个活动可以抓住背压。如果我显示当前正在运行的活动,则此应用程序中没有任何内容。

问题

如何做到这一点?我读了这么多线程说,这是不可能的,但我可以看到,有些应用程序以某种方式实现了......

4 个答案:

答案 0 :(得分:12)

我想我发现它是如何工作的......请勿在叠加层视图中使用WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE +覆盖视图的dispatchKeyEvent

 @Override
public boolean dispatchKeyEvent(KeyEvent event)
{
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
    {
        // handle back press
        // if (event.getAction() == KeyEvent.ACTION_DOWN)
        return true;
    }
    return super.dispatchKeyEvent(event);
}

答案 1 :(得分:2)

我找到了解决这个问题的方法,它运作良好。

public class MyFooterService extends Service{
View myview;
WindowManager wm;
FrameLayout wrapper;
public MyFooterService() {

}
 @Override
public void onCreate() {
    Log.d(TAG, "onCreate called");
    LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            90,  //height of ur layout
            WindowManager.LayoutParams.TYPE_PHONE,
            0,
            PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.BOTTOM ;
    params.x = 0;
    params.y = 0;
   wrapper = new FrameLayout(this) {
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
              // handle the back button code;
             return true;
            }
          return super.dispatchKeyEvent(event);
        }
       //if pressed home key,
      public void onCloseSystemDialogs(String reason) {
            //The Code Want to Perform.
            System.out.println("System dialog " + reason);
            if (reason.equals("homekey")) {
                // handle home button 
            }
        }

     };
   myview = li.inflate(R.layout.my_footer, wrapper);   // here set into your own layout
   wm.addView(myview, params);

}
}

答案 2 :(得分:2)

如果在服务的WindowManager中附加了覆盖窗口,则将视图设置为setFocusableInTouchMode(true)属性,然后放置一个键侦听器。您将收到关键事件,例如以下示例:

view.setFocusableInTouchMode(true);
view.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK) {
            stopSelf();
            return true;
        }
        return false;
    }
});

编辑,我没有使用好的stackoverflow帐户

答案 3 :(得分:0)

您可以捕捉后退按钮点击事件。为此,您需要创建OverlayView的容器类。例如:create class Overlay将扩展一些ViewGroup类。然后,在类中,膨胀您的xml布局并将其添加到Overlay.class ViewGroup。比Overlay.class覆盖方法dispatchKeyEvent(KeyEvent事件)。这就是全部!

class Overlay extends FrameLayout{
  
  public Overlay(@NonNull Context context) {
        super(new ContextThemeWrapper(context, R.style.AppTheme));

        initView();
    }
    
    private void initView() {
      //inflate your xml here
      //than do: this.addView(<inflated view>);
      //And in the end add your Overlay to WindowManager (in Service class of course).
    }
    
     @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            //do staff here
            // and return True!
            return true;
        }
        return super.dispatchKeyEvent(event);
    }
}