How to detect backbutton/home press from a service like messenger chat head service?

本秂侑毒 提交于 2019-12-09 11:41:41

问题


I have been looking through several stackoverflow question to find out how can I listen to backpress button on a service using windows manager. Most of the answers proposes that it's not possible, however I can see that messenger handle it very well.

How does messenger handle the backpress button on it's head chat service? (Or I am completely wrong and they are not a service using windows manager?)


回答1:


To achieve what you need, you need to extend some ViewGroup that you are going to use as a root container for your views. Let's start with this:

public class BackButtonAwareLinearLayout extends LinearLayout {

    public interface BackButtonListener {
        void onBackButtonPressed();
    }

    @Nullable
    private BackButtonListener mListener;

    public BackButtonAwareLinearLayout(Context context) {
        super(context);
    }

    public BackButtonAwareLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BackButtonAwareLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setBackButtonListener(@Nullable BackButtonListener listener) {
        mListener = listener;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK
                && mListener != null) {
            mListener.onBackButtonPressed();
            return true;
        }
        return super.dispatchKeyEvent(event);
    }
}

Basically, overriding dispatchKeyEvent is what does a trick for us here. Then make a use of it in some xml (I have called it chat_head_container.xml):

<?xml version="1.0" encoding="utf-8"?>
<com.pablo432.myapplication.BackButtonAwareLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="48sp"
        android:text="Hello, world!"
        android:textColor="#000"
        android:background="#f5f5f5"
        android:gravity="center"/>

</com.pablo432.myapplication.BackButtonAwareLinearLayout>

Next, create a Service that adds our view to the WindowManager (though I suppose you know how to do it, I'll post it anyway for the sake of completeness):

public class ChatHeadService extends Service
        implements BackButtonAwareLinearLayout.BackButtonListener {

    private WindowManager mWindowManager;
    private BackButtonAwareLinearLayout mRootContainer;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mRootContainer = (BackButtonAwareLinearLayout) inflater.inflate(
                R.layout.chat_head_container, null, false);
        mRootContainer.setBackButtonListener(this);

        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                PixelFormat.TRANSPARENT);

        mWindowManager.addView(mRootContainer, layoutParams);
    }

    @Override
    public void onBackButtonPressed() {
        mRootContainer.setBackButtonListener(null);
        mWindowManager.removeView(mRootContainer);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mRootContainer != null) mWindowManager.removeView(mRootContainer);
    }
}

So long story short, BackButtonAwareLinearLayout exposes a listener interface, that our service needs to implement and subscribe itself to the Layout.

Also have in mind that this addresses handling back button. To handle home button, you may want to take a look at https://stackoverflow.com/a/31340960 and https://stackoverflow.com/a/33580971 - basically my answer is a bit of a summary from those two links + https://stackoverflow.com/a/15980900 but contains few tweaks (like, for example, you can't set FLAG_NOT_FOCUSABLE in WindowManager.LayoutParams).

Of course you need to start your service somewhere by calling startService, declare this service in AndroidManifest.xml and add a SYSTEM_ALERT_WINDOW permission.



来源:https://stackoverflow.com/questions/42821520/how-to-detect-backbutton-home-press-from-a-service-like-messenger-chat-head-serv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!