当前位置:  开发笔记 > Android > 正文

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

如何解决《创建主页按钮仍然有效的系统覆盖?》经验,为你挑选了2个好方法。

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

    按钮应该是可点击的,按下按钮下面的任何内容都不应该被激活.

    在按钮后面运行的活动或主屏幕应该仍然有效,这意味着用户仍然可以与主屏幕或应用程序进行交互.

    软键按钮仍然可以工作:家庭,后面,菜单等

以下代码执行#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_NOT_TOUCH_MODAL,

最后在这个例子中,点击了叠加层和它后面的内容:

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,

如何更改此设置以使叠加层可以点击,直接在其下面是不可点击的,并且叠加层之外的所有内容都可以使用,包括主页按钮?

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

更新:我发现以下内容允许使用主页按钮,但仍然不是其他按钮:

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

,



1> hackbod..:

    你不能将OR窗口类型放在一起.您将创建一些随机的其他类型.说实话,你使用的窗口类型实际上不是供应用程序使用的(这就是为什么它们中包含"system"一词).

    "软键按钮不再起作用"是什么意思?如果这是一个大问题(我想知道执行此操作的代码),就不应该停止工作.其他键被传递到当前的关键焦点; 如果你不想专注,请使用FLAG_NOT_FOCUSABLE.

    每个标志的文档应该非常清楚它的作用,所以选择做你想做的标志. FLAG_NOT_FOCUSABLE因为你不想参加关键事件. FLAG_NOT_TOUCH_MODAL因为您不想阻止窗口外的触摸事件.你没有说你想知道你窗外的印刷机,所以没有理由使用FLAG_WATCH_OUTSIDE_TOUCH.


哇谢谢!使用带有标志not_focusable |的type_system_alert not_touch_modal已经完成了这个伎俩.按钮或选择器不会显示他们点击的动画,但我通过使用OnClick点击和OnTouch来改变action_down和action_up的背景.
"不应该停止回家工作." 实际上@ pcm2a是正确的.我已经在摩托罗拉Droid 3和TYPE_SYSTEM_ERROR或TYPE_SYSTEM_ALERT窗口上测试了这个,前面提到的标志可以使用包括HOME键的关键事件(实际上即使事件没有被消耗,也不会发生默认行为).这很奇怪,因为我认为这是一个永远不会被任何应用程序截获的密钥.

2> amirlazarovi..:

我看到pcm2a没有发布一个有效的解决方案,所以我不妨为他做.

注意:虽然我提出了一种可行的解决方案,但就Android架构设计而言,使用这些方法并非100%正确.我建议向Android开发团队的某些人询问更多信息(请在此发布他们的答案供我们所有人查看).

权限

服务
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);

    }
}
layout.main



    


快乐的编码!
阿米尔


推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有