Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android系统覆盖未显示在我的应用程序外_Android_Android Layout_Layoutparams - Fatal编程技术网

Android系统覆盖未显示在我的应用程序外

Android系统覆盖未显示在我的应用程序外,android,android-layout,layoutparams,Android,Android Layout,Layoutparams,我需要在任何正在运行的应用程序上显示一个系统覆盖窗口。它工作正常,但只有当我的应用程序的活动处于前台时。以下是我使用的代码: params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, Wind

我需要在任何正在运行的应用程序上显示一个系统覆盖窗口。它工作正常,但只有当我的应用程序的活动处于前台时。以下是我使用的代码:

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已定义
系统警报\u窗口
权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

当我的活动在前台运行时,一切都非常出色。只要我切换到任何其他应用程序或主屏幕,就不会显示覆盖图。我调试了代码,它确实在运行wm.addView(),并且没有抛出任何异常。我还玩了LayoutParams标志(删除了KEEP_SCREEN_和相关的等等),但没有任何区别


Android 4.4.2 fwiw

您需要创建一个
服务
,以保持系统覆盖(警报)即使在应用程序关闭时也能显示

创建一个简单的服务,我将调用
FloatingService
,当调用
onStartCommand
时,它将显示覆盖(警报)。返回
START\u 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" />

问题是我在主视图的post()方法中运行addView()调用:

相反,如果我只是在主线程中运行它,它工作得很好。我使用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;
    }
}

我记得当我尝试做这些事情时,就我所记得的,
上下文必须是应用程序上下文。我不能参加这个活动。“ctx”包含主活动getApplicationContext()调用(即应用程序上下文)返回的内容。祝你好运。键入系统警报而不是键入系统覆盖?我不需要警报。我需要一个半透明的覆盖窗口总是在上面。类型\u系统\u覆盖正是我需要的,它工作良好。。。只要我的活动在前台,服务的问题在于它不一定在UI线程中运行,因此我不能直接使用addView调用。不管怎样,我都不明白为什么它必须是服务?我已经运行了一个后台服务,可以通过eventbus与我的“系统覆盖”管理器通信,这还不够吗?我想出来了。我会发布我自己的答案,但由于它的清晰性和广泛的说明,我对你的答案投了赞成票
mainView.post(new Runnable() {
 public void run() {
  wm.add(mainView);
 }
);
public void onEventMainThread(UIRunnableEvent event) {
    event.r.run();
}

public static class UIRunnableEvent {
    protected Runnable r;

    protected UIRunnableEvent(Runnable r) {
        this.r = r;
    }
}