我需要在任何正在运行的应用程序之上显示系统覆盖窗口。它工作正常,但只有当我的应用程序的活动在前台时。这是我使用的代码:
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
WindowManager.LayoutParams.FLAG_DIM_BEHIND |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER | Gravity.TOP;
params.dimAmount = 0.3f;
wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
mainAlertView = View.inflate(ctx, R.layout.system_alert_view, null);
wm.addView(mainAlertView, params);
添加到WindowManager的视图包含我在运行时添加子视图的空LinearLayout:
mainAlertLayout.addView(childView);
清单xml已定义SYSTEM_ALERT_WINDOW
权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
当我的活动在前景中运行时,这一切都很有效。只要我切换到任何其他应用程序或主屏幕,就不会显示叠加层。我调试了代码,它确实在运行wm.addView(),它没有抛出任何异常。我还玩过LayoutParams标志(删除了KEEP_SCREEN_ON和相关的等),但没有任何区别。
Android 4.4.2 fwiw
答案 0 :(得分:6)
即使应用程序关闭,您也需要创建service
以保持系统覆盖(警报)显示。
创建一个简单的服务,我将调用FloatingService
,它将在调用onStartCommand
时显示覆盖(警报)。返回START_STICKY
以使服务在后台运行。
public class FloatingService extends Service {
private WindowManager windowManager;
private View floatingView;
WindowManager.LayoutParams params;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flag, int startId){
// show the alert her
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
// use your custom view here
floatingView = View.inflate(getBaseContext(),R.layout.floating_layout,null); //floatingView.setOnTouchListener(mOnTouchListener);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER | Gravity.CENTER;
// add the view to window manger
windowManager.addView(floatingView, params);
return START_STICKY;
}
}
向视图添加侦听器,以便您可以在需要时关闭叠加层(警报)
floatingView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
windowManager.removeView(floatingView);
floatingView = null;
}
});
最后,在清单
中注册服务 <service android:name="com.example.app.services.FloatingService" />
System Alert
权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
答案 1 :(得分:0)
问题是我在主视图的post()方法中运行了addView()调用:
mainView.post(new Runnable() {
public void run() {
wm.add(mainView);
}
);
相反,如果我只是在主线程中运行它,它工作正常。我使用de.greenrobot.eventbus,将Runnable发布到事件总线非常简单,并确保它在主线程中执行:
public void onEventMainThread(UIRunnableEvent event) {
event.r.run();
}
public static class UIRunnableEvent {
protected Runnable r;
protected UIRunnableEvent(Runnable r) {
this.r = r;
}
}