Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.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 - Fatal编程技术网

Android 在主页按钮仍然有效的地方创建系统覆盖?

Android 在主页按钮仍然有效的地方创建系统覆盖?,android,Android,我正在尝试创建一个始终在屏幕上的按钮 按钮应该是可点击的,并且 按钮正下方有什么东西吗 不应在压力机上激活 正在运行的活动或主屏幕 按钮后面应该还能用, 这意味着用户仍然应该 能够与家庭互动 屏幕或应用程序 软键 按钮应该仍然有效:主页, 背面、菜单等 以下代码执行#1和#2,但软键按钮不再工作: WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutPara

我正在尝试创建一个始终在屏幕上的按钮

  • 按钮应该是可点击的,并且 按钮正下方有什么东西吗 不应在压力机上激活
  • 正在运行的活动或主屏幕 按钮后面应该还能用, 这意味着用户仍然应该 能够与家庭互动 屏幕或应用程序
  • 软键 按钮应该仍然有效:主页, 背面、菜单等
  • 以下代码执行#1和#2,但软键按钮不再工作:

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);
    
    将其更改为该选项将禁用单击覆盖,但#2和#3起作用:

    最后,在本例中,单击覆盖层及其后面的内容:

    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
    WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
    
    我怎样才能改变这一点,使覆盖是可点击的,它正下方的什么是不可点击的,覆盖以外的一切工作,包括主页按钮

    执行所有这些操作的示例应用程序是Super Manager

    更新:我发现以下允许使用home按钮,但仍然不允许使用其他按钮:

            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | 
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
    
    ,

  • 您不能将两个或多个窗口类型放在一起。您将创建一些随机的其他类型。老实说,你正在使用的窗口类型实际上并不是应用程序想要使用的(这就是为什么它们里面有“系统”这个词)


  • “软键按钮不再工作”是什么意思?如果这是一个大问题(我想知道做这件事的代码),那么就不可能在家里停止工作。其他按键被传递到当前按键焦点;如果您不想被聚焦,请使用
    标志\u NOT\u FOCUSABLE

  • 这些标志中的每一个的文档都应该非常清楚它是做什么的,所以选择做你想做的标志<代码>标记不可聚焦,因为您不想获取关键事件<代码>标记非触摸模式,因为您不想阻止窗口外的触摸事件。您不会说您想了解窗口外的按键信息,因此没有理由使用
    FLAG\u WATCH\u outside\u TOUCH


  • 我知道pcm2a没有发布有效的解决方案,所以我还是替他做吧。

    注意:尽管我提出了一个可行的解决方案,但对于Android架构设计来说,使用这些方法并不是100%正确的。我建议向安卓开发团队询问更多信息(请在这里发布他们的答案,让我们大家都能看到)

    权限 主布局
    
    
    快乐编码!

    阿米尔

    哇,谢谢!使用带有“不可聚焦”标志的“不可触摸”模式的“系统警报”类型已经达到了目的。按钮或选择器不会显示其单击的动画,但我已经通过使用OnClick和OnTouch来改变action\u down和action\u up的背景来解决这个问题。“应该不可能停止工作。”实际上@pcm2a是正确的。我已经在Motorola Droid 3股票上测试了这一点,带有上述标志的TYPE_SYSTEM_ERROR或TYPE_SYSTEM_ALERT窗口可以使用包括HOME key在内的关键事件(事实上,即使没有使用这些事件,默认行为也不会发生)。这很奇怪,因为我觉得这是一个任何应用程序都无法截获的键。@Tom我想当Dianne说不可能使软键按钮不工作时,她的意思是不可能阻止用户单击软键按钮。当然,您可以让窗口覆盖按钮的默认行为,但您不能“禁用”主页按钮(即使其不可单击),例如。这是因为这些按钮作为系统拥有的单独窗口的一部分存在。顺便说一句:@pcm2a是正确的。HW home按钮不适用于在Android 4.0.4上不可聚焦的标志,在模拟器和真实设备上测试;-)@你的评论把我从混乱中解救了出来。谢谢大家的贡献。你能发布最终答案或更新你的问题吗?另外,您用于构建它的权限是什么?
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | 
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
    
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    
    package com.vidmind.test.service.video;
    import android.app.Service;
    import android.content.Intent;
    import android.graphics.PixelFormat;
    import android.media.MediaPlayer;
    import android.media.MediaPlayer.OnPreparedListener;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.os.Messenger;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.WindowManager;
    import android.widget.LinearLayout;
    import android.widget.VideoView;
    
    public class TestVideoService extends Service {
    
        /** Command to the service to display a message */
        public static final int MSG_PLAY_VIDEO = 1;
        public static final int MSG_VIDEO_LOOP_MODE = 2;
    
    
        /** Bundle Strings */
        public static final String KEY_VIDEO_URL = "KEY_VIDEO_URL";
        public static final String KEY_VIDEO_LOOP_MODE = "KEY_VIDEO_LOOP_MODE";
    
    
        // Binder given to clients
        private static final String TAG = "TestVideoService";
        final Messenger mMessenger = new Messenger(new IncomingHandler());
        private LinearLayout mOverlay;
        private VideoView mVideoView;
        private boolean mVideoLoop = true;
    
    
        /** ****************** Handler implementation class ****************** **/
    
        /**
         * Handler of incoming messages from clients.
         */
        class IncomingHandler extends Handler {
            @Override
            public void handleMessage(Message msg) {
                Bundle bundle;
                switch (msg.what) {
                    case MSG_PLAY_VIDEO:
                        bundle = msg.getData();
                        String url = bundle.getString(KEY_VIDEO_URL);
                        play(url);
                        break;
    
                    case MSG_VIDEO_LOOP_MODE:
                        bundle = msg.getData();
                        boolean looping = bundle.getBoolean(KEY_VIDEO_LOOP_MODE);
                        setVideoLoop(looping);
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
        }
    
        /** ****************************************************************** **/
    
        @Override
        public IBinder onBind(Intent intent) {
            return mMessenger.getBinder();
        }
    
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.d(TAG, "Service has started");
    
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.d(TAG, "Serice destroyed");
    
            // Remove view from WindowManager
            WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
            wm.removeView(mOverlay);
    
            mOverlay = null;
            mVideoView = null;
        }
    
    
        /** ****************** Private Functions ****************** **/
    
        /**
         * Set video loop mode
         * @param value
         */
        private void setVideoLoop(boolean value) {
            mVideoLoop = value;
        }
    
        /**
         * Start playing the movie
         * @param url
         * @returns success/failure
         */
        private boolean play(String url) {
            boolean isSuccess = false;
    
            if (mOverlay != null && mVideoView.isPlaying()) {
                Log.w(TAG, "Cannot recreate video overlay");
                return isSuccess;
            }
    
            // Create overlay video
            createOverlay(mOverlay != null);
            if (!mVideoView.isPlaying()) {
                mVideoView.setOnPreparedListener(new OnPreparedListener() {
    
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mp.setLooping(mVideoLoop);
                    } 
                });
    
                mVideoView.setVideoURI(Uri.parse(url));
                mVideoView.requestFocus();
                mVideoView.start();
                isSuccess = true;
            }
            return isSuccess;
        }
    
        /**
         * Create video overlay
         * 
         * @param isCreated
         */
        private void createOverlay(boolean isCreated) {
            if (isCreated) return;
    
            // Create System overlay video
            WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.FILL_PARENT, 150,
                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                    PixelFormat.TRANSLUCENT);
            params.gravity = Gravity.BOTTOM;
    
            LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            mOverlay = (LinearLayout) inflater.inflate(R.layout.main, null);
            mVideoView = (VideoView) mOverlay.findViewById(R.id.video_player);
    
            WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
            wm.addView(mOverlay, params);
    
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    
        <VideoView
            android:id="@+id/video_player"
            android:layout_width="120dp"
            android:layout_height="120dp"/>
    
    </LinearLayout>