Android 带有系统警报窗口的反按事件
我需要在按下Android 带有系统警报窗口的反按事件,android,back-button,android-homebutton,Android,Back Button,Android Homebutton,我需要在按下back和home按钮事件时关闭系统警报窗口。我尝试了onKeyEvent,但没有成功。由于我们无法在服务中捕获backpressed事件,如何实现这一点?使用下面的代码 public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { exitByBackKey(); //moveTaskToBack(false);
back
和home
按钮事件时关闭系统警报窗口。我尝试了onKeyEvent
,但没有成功。由于我们无法在服务中捕获back
pressed事件,如何实现这一点?使用下面的代码
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
exitByBackKey();
//moveTaskToBack(false);
return true;
}
return super.onKeyDown(keyCode, event);
}
protected void exitByBackKey() {
AlertDialog alertbox = new AlertDialog.Builder(this)
.setMessage("Do you want to exit application?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
finish();
//close();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
}
})
.show();
}
public void onBackPressed()
{
super.onBackPressed();
}
使用以下方法处理按下的后退按钮
public void onBackPressed()
{
super.onBackPressed();
}
在您的活动中声明这一点。在android中,super.OnBackPressed自动回调方法。它肯定会取消您的对话
public void onBackPressed()
{
super.onBackPressed();
}
此外,您的对话框必须如下所示
public void onBackPressed()
{
super.onBackPressed();
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder1.setMessage("TEST DIALOG.\n");
builder1.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
Toast.makeText(MainActivity.this, "This Is test Dialog", Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
或者您可以设置负按钮
public void onBackPressed()
{
super.onBackPressed();
}
希望这有帮助 定义自定义布局并覆盖dispatchKeyEvent,例如:
public void onBackPressed()
{
super.onBackPressed();
}
public class CustomSystemAlertWindow extends FrameLayout {
public static final String TAG = "CustomSystemAlertWindow";
private WeakReference<Context> mContext;
public CustomSystemAlertWindow(Context context) {
super(context);
mContext = new WeakReference<Context>(context);
// Set a background color to identify the view on the screen
this.setBackgroundColor(getResources().getColor(android.R.color.holo_red_light));
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
Log.d(TAG, "back button pressed");
if (mContext != null && mContext.get() != null) {
WindowManager wm = (WindowManager) mContext.get().getSystemService(Context.WINDOW_SERVICE);
wm.removeView(this);
}
return true;
}
return super.dispatchKeyEvent(event);
}
}
当您按下后退按钮时,视图将消失
public void onBackPressed()
{
super.onBackPressed();
}
public void onBackPressed()
{
super.onBackPressed();
}
public class alertPopup extends Activity {
Context context;
final AlertDialog alertDialog;
String TAG = "your Activity Name"
boolean homePressed = false; // to detect the Homebutton pressed
@Override
public void onCreate(Bundle savedInstanceState) {
AlertDialog.Builder builder = newAlertDialog.Builder(YourActivity.this, R.style.AppCompatAlertDialogStyle);
builder.setTitle("AlertDialog Title");
..........
....... // Build ur AlertDialog
alertDialog= builder.create();
alertDialog.show();
//to detect Alert Dialog cancel when user touches outside the Dialog prompt
alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
Log.v(TAG,"Alert Dialog cancelled when user touches outside the Dialog prompt")
}
});
}
@Override
public void onBackPressed()
{
Log.v(TAG,"Back Button Pressed");
super.onBackPressed();
alertDialog.dismiss(); //dismiss the alertDialog
alertPopup.this.finish(); // Destroy the current activity
homePressed = false;
}
@Override
public void onResume() {
super.onResume();
homePressed = true; // default: other wise onBackPressed will set it to false
}
@Override
public void onPause() {
super.onPause();
if(homePressed) {
alertDialog.dismiss(); //dismiss the alertDialog
alertPopup.this.finish(); // Destroy the current activity
Log.v(TAG, "Home Button Pressed"); }
}
public void onDestroy(){
super.onDestroy();
}
}
注:
public void onBackPressed()
{
super.onBackPressed();
}
在Android清单中添加此权限以显示警报窗口
public void onBackPressed()
{
super.onBackPressed();
}
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
快乐编码:)因为这是一个托管覆盖窗口的服务,这是一个有点棘手的解决方案,但它是可能的
public void onBackPressed()
{
super.onBackPressed();
}
您应该分别处理这两种情况(覆盖home按钮按下和back按钮按下)
public void onBackPressed()
{
super.onBackPressed();
}
1。覆盖主页按钮按下:
public void onBackPressed()
{
super.onBackPressed();
}
创建此HomeWatcher类,该类包含一个BroadcastReceiver,当按下home按钮时将发出通知。仅当窗口打开时才注册此接收器
public void onBackPressed()
{
super.onBackPressed();
}
public void onBackPressed()
{
super.onBackPressed();
}
在服务onCreate方法中,请使用以下方法:
public void onBackPressed()
{
super.onBackPressed();
}
HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
@Override
public void onHomePressed() {
yourWindow.hide() //means: windowManager.removeView(view);
}
@Override
public void onHomeLongPressed() {
}
});
mHomeWatcher.startWatch();
2。覆盖后退按钮按下:
public void onBackPressed()
{
super.onBackPressed();
}
其思想是创建一个空布局作为window类的数据成员,
并将视图附加到它(即使它是一个膨胀的XML布局)
public void onBackPressed()
{
super.onBackPressed();
}
例如,这将是您的窗口类:
public void onBackPressed()
{
super.onBackPressed();
}
public class MyWindow
{
private WindowManager windowManager;
private WindowManager.LayoutParams params;
private View view;
// Add this empty layout:
private MyLayout myLayout;
public MyWindow()
{
windowManager = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.your_original_window_layout, null);
// Add your original view to the new empty layout:
myLayout = new MyLayout(this);
myLayout.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
// And show this layout instead of your original view:
public void show()
{
windowManager.addView(myLayout, params);
}
public void hide()
{
windowManager.removeView(myLayout);
}
}
现在创建MyLayout类以覆盖按back按钮:
public void onBackPressed()
{
super.onBackPressed();
}
public class MyLayout extends LinearLayout
{
private MyWindow myWindow;
public MyLayout(MyWindow myWindow)
{
super(myWindow.context);
this.myWindow = myWindow;
}
@Override public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
{
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0)
{
getKeyDispatcherState().startTracking(event, this);
return true;
}
else if (event.getAction() == KeyEvent.ACTION_UP)
{
getKeyDispatcherState().handleUpEvent(event);
if (event.isTracking() && !event.isCanceled())
{
// dismiss your window:
myWindow.hide();
return true;
}
}
}
return super.dispatchKeyEvent(event);
}
}
我知道这有点复杂,因为它是一个由服务托管的系统警报窗口,但它正在工作。我也有同样的问题,它已经完全解决了。
祝你好运。你需要覆盖
onBackPressed
方法
public void onBackPressed()
{
super.onBackPressed();
}
@Override
public void onBackPressed() {
super.onBackPressed(); // remove this if u want to handle this event
}
我知道您正在使用
权限来显示浮动视图
public void onBackPressed()
{
super.onBackPressed();
}
使用浮动视图,您可以截获back
按钮按下,但无法截获home
按钮按下(android不会让您这样做,主要是因为安全原因)
public void onBackPressed()
{
super.onBackPressed();
}
要截取back
按钮,请在充气浮动视图时添加包装。
您的包装应该如下所示:
public void onBackPressed()
{
super.onBackPressed();
}
// Wrapper for intercepting System/Hardware key events
ViewGroup wrapper = new FrameLayout(this) {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
hideAddNotesFloatingView();
return true;
}
return super.dispatchKeyEvent(event);
}
};
private void addFloatingView() {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
0,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER | Gravity.LEFT;
params.x = 0;
params.y = 0;
// Wrapper for intercepting System/Hardware key events
FrameLayout wrapper = new FrameLayout(this) {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
// Add your code for handling the back button press
return true; // Return true means that the event was handled
}
return super.dispatchKeyEvent(event);
}
};
mAddNoteFloatingView = mInflater.inflate(R.layout.floating_view, wrapper);
mWindowManager.addView(mAddNoteFloatingView, params);
}
然后将其作为根添加到浮动视图中:
public void onBackPressed()
{
super.onBackPressed();
}
mAddNoteFloatingView = mInflater.inflate(R.layout.floating_add_note, wrapper);
我的完整代码如下所示:
public void onBackPressed()
{
super.onBackPressed();
}
// Wrapper for intercepting System/Hardware key events
ViewGroup wrapper = new FrameLayout(this) {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
hideAddNotesFloatingView();
return true;
}
return super.dispatchKeyEvent(event);
}
};
private void addFloatingView() {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
0,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER | Gravity.LEFT;
params.x = 0;
params.y = 0;
// Wrapper for intercepting System/Hardware key events
FrameLayout wrapper = new FrameLayout(this) {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
// Add your code for handling the back button press
return true; // Return true means that the event was handled
}
return super.dispatchKeyEvent(event);
}
};
mAddNoteFloatingView = mInflater.inflate(R.layout.floating_view, wrapper);
mWindowManager.addView(mAddNoteFloatingView, params);
}
很简单。遵循以下步骤:
dispatchKeyEvent
李>
addView()
方法将原始视图添加到此动态创建的视图中除了@Eliran Kuta的解决方案之外,这是对后退按钮的更简单的回答
public void onBackPressed()
{
super.onBackPressed();
}
val view = getAlertView()
val windowParam = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT, // whatever
WindowManager.LayoutParams.WRAP_CONTENT, // whatever
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, // use WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY before Oreo
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, // whatever
PixelFormat.TRANSLUCENT // whatever
)
view.isFocusableInTouchMode = true
view.setOnKeyListener { view, keyCode, event ->
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
// do your work here
true
}
else -> false
}
}
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.addView(view, windowParam)
您可以通过覆盖onBackButtonpressed方法来实现这一点。您可以添加显示对话框的代码吗?系统警报窗口是我用来绘制其他应用程序的窗口。我想处理关键事件,例如从辅助功能服务中按下BackButton和home按钮。请注意,问题是关于“系统警报窗口”这是从服务开始的(不涉及任何活动)。是的,我知道。如果要检测按下的后退按钮和主页按钮,应通过服务显示活动。还有别的办法吗?@yaemi会尽快检查的。我不知道还有没有别的办法,这就是为什么我要问。。。另外,我将尝试反编译FB messanger应用程序,看看他们是如何做到的。我给出了一个我正确知道的解决方案。不要在你不知道的情况下问问题。发布你的代码,否则很难帮助你。既然这个问题不是你的,你可以把它贴在网上或类似的服务上。类似的就不一样了。答案的代码与您的代码有什么区别?我的布局是从预定义的XML扩展而来的,它的根是“CustomsystemAlertWindow”,我刚刚尝试使用XML,它对我有效。你确定你正在使用与答案相同的标志来创建
WindowManager.LayoutParams
?谢谢,我会尽快尝试。你可以下载我的应用程序,了解其中的系统警报windows行为,如果你愿意,可以问我更多问题,我会给你一些提示和代码示例。基本上,sys alert overlay窗口需要大量的维护、管理和额外的维护,因为它们不是活动。在MyWindow类->什么是“上下文”中,声明中没有变量这不是homebutton的重写。。。但它是一个延伸。。。homebutton操作也执行以下操作:-(dispatchKeyEvent从未调用您将mAddNoteFloatingView添加到windowManager而不是wrapper,为什么?wrapper是最上面的视图,它应该添加到WM中,不是吗?@shantanu在这种情况下,mAddNoteFloatingView
和wrapper
都引用了相同的视图。LayoutInflater.inflate
返回:膨胀层次结构的根视图。如果提供了根视图,则为根视图;否则为膨胀XML文件的根视图