我需要在back
按下home
按钮事件时关闭系统警报窗口。我已尝试使用onKeyEvent
,但徒劳无功。由于我们无法捕获服务中的back
按下事件,如何实现此目标?
答案 0 :(得分:5)
由于它是托管覆盖窗口的服务,因此它有点棘手,但有可能。
您应该分别处理这两种情况(按住主页按钮,按下后退按钮)。
<强> 1。覆盖主页按钮:
创建此HomeWatcher类,其中包含将在按下主页按钮时通知的BroadcastReceiver。只有在窗口出现时才注册此接收器。
Android: associate a method to home button of smartphone
在您的服务onCreate方法中使用此:
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。按下后退按钮:
这个想法是创建一个空布局作为窗口类的数据成员, 并将您的视图附加到它(即使它是一个膨胀的XML布局)。
例如,这将是你的窗口类:
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类以覆盖后退按钮:
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);
}
}
我知道它有点复杂,因为它是由服务托管的系统警报窗口,但它正在工作。我也有同样的问题,它已经完全解决了。 祝你好运。
答案 1 :(得分:1)
使用以下方法处理按下后退按钮。
and
答案 2 :(得分:1)
您需要覆盖onBackPressed
方法。
@Override
public void onBackPressed() {
super.onBackPressed(); // remove this if u want to handle this event
}
答案 3 :(得分:0)
使用以下代码
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();
}
答案 4 :(得分:0)
@Override
public void onBackPressed()
{
super.onBackPressed();
}
在您的活动中声明此信息。 super.OnBackPressed在android中自动回调方法。它肯定会取消你的对话。
此外,您的对话框必须如下所示。
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();
或者您可以设置“否定”按钮..
希望这有帮助!
答案 5 :(得分:0)
定义自定义布局并覆盖dispatchKeyEvent
,例如:
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);
}
}
然后使用以下代码添加视图:
CustomSystemAlertWindow customSystemAlertWindow = new CustomSystemAlertWindow(context);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
wm.addView(customSystemAlertWindow, params);
当您按后退按钮时,视图将被解除。
答案 6 :(得分:0)
实施代码以轻松检测后退按钮或主页按钮。
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();
}
}
注意:
在Android Manifest中添加此权限以显示警告窗口。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
快乐编码:)
答案 7 :(得分:0)
我了解您使用<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
权限来显示浮动视图。
使用浮动视图,您可以截取back
按钮,但无法截取home
按钮(由于安全原因,Android不会主要让您使用)。
要拦截back
按钮,您需要在浮动视图时添加包装器。
您的包装器应如下所示:
// 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);
}
};
然后将其作为根添加到浮动视图中:
mAddNoteFloatingView = mInflater.inflate(R.layout.floating_add_note, wrapper);
我的完整代码如下所示:
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);
}
答案 8 :(得分:0)
dispatchKeyEvent
。 addView()
方法将原始视图添加到此动态创建的视图中。答案 9 :(得分:0)
除了@Eliran Kuta的解决方案之外,这是“返回”按钮的更简单答案。
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)