我一直在查看几个stackoverflow问题,以了解如何使用Windows管理器监听服务上的backpress按钮。大多数答案提出这是不可能的,但我可以看到信使处理得很好。
messenger如何处理其聊天服务的背压按钮? (或者我完全错了,他们不是使用Windows管理器的服务?)
答案 0 :(得分:3)
要实现所需,您需要扩展一些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/31340960和https://stackoverflow.com/a/33580971 - 基本上我的回答是来自这两个链接+ https://stackoverflow.com/a/15980900的一些摘要,但包含一些调整(如例如,您无法在WindowManager.LayoutParams中设置FLAG_NOT_FOCUSABLE。
当然,您需要通过调用startService在某处启动服务,在AndroidManifest.xml中声明此服务并添加SYSTEM_ALERT_WINDOW权限。