【问题标题】:How to detect backbutton/home press from a service like messenger chat head service?如何从信使聊天头服务等服务中检测后退按钮/主页按下?
【发布时间】:2017-03-15 22:02:44
【问题描述】:

我一直在查看几个 stackoverflow 问题,以了解如何使用 Windows 管理器收听服务上的 backpress 按钮。大多数答案都认为这是不可能的,但是我可以看到信使处理得很好。

Messenger如何处理其头部聊天服务上的backpress按钮? (或者我完全错了,它们不是使用 Windows 管理器的服务?)

【问题讨论】:

    标签: service android-windowmanager onbackpressed


    【解决方案1】:

    要实现您的需要,您需要扩展一些 ViewGroup,您将用作视图的根容器。让我们从这个开始:

    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);
        }
    }
    

    基本上,重写 dispatchKeyEvent 对我们来说是一个窍门。 然后在一些xml中使用它(我称之为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>
    

    接下来,创建一个将我们的视图添加到 WindowManager 的服务(虽然我想你知道怎么做,但为了完整起见,我还是会发布它):

    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);
        }
    }
    

    长话短说,BackButtonAwareLinearLayout 公开了一个侦听器接口,我们的服务需要实现并订阅布局。

    还要记住,这解决了处理后退按钮的问题。要处理主页按钮,您可能需要查看 https://stackoverflow.com/a/31340960https://stackoverflow.com/a/33580971 - 基本上我的答案是这两个链接 + https://stackoverflow.com/a/15980900 的一些总结,但包含一些调整(例如,您可以'不在 WindowManager.LayoutParams 中设置 FLAG_NOT_FOCUSABLE)。

    当然你需要通过调用 startService 在某个地方启动你的服务,在 AndroidManifest.xml 中声明这个服务并添加一个 SYSTEM_ALERT_WINDOW 权限。

    【讨论】:

    • 设置WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL如果要允许输入继续到后台窗口
    猜你喜欢
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    相关资源
    最近更新 更多