Creating a system overlay window (always on top)

前端 未结 16 948
南方客
南方客 2020-11-21 07:07

I\'m trying to create an always-op-top button/clickable-image which stays on top of all the windows all the time.

The proof of concept is

  • here - Smar
相关标签:
16条回答
  • 2020-11-21 07:19

    It uses permission "android.permission.SYSTEM_ALERT_WINDOW" full tutorial on this link : http://androidsrc.net/facebook-chat-like-floating-chat-heads/

    0 讨论(0)
  • 2020-11-21 07:20

    This might be a stupid solution. But it works. If you can improve it, please let me know.

    OnCreate of your Service: I have used WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH flag. This is the only change in service.

    @Override
        public void onCreate() {
            super.onCreate();
            Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
            mView = new HUDView(this);
            WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                    WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                    PixelFormat.TRANSLUCENT);
            params.gravity = Gravity.RIGHT | Gravity.TOP;
            params.setTitle("Load Average");
            WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
            wm.addView(mView, params);
        }
    

    Now, you will start getting each and every click event. So, you need to rectify in your event handler.

    In your ViewGroup touch event

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    
        // ATTENTION: GET THE X,Y OF EVENT FROM THE PARAMETER
        // THEN CHECK IF THAT IS INSIDE YOUR DESIRED AREA
    
    
        Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
        return true;
    }
    

    Also you may need to add this permission to your manifest:

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    
    0 讨论(0)
  • 2020-11-21 07:23

    Well try my code, atleast it gives you a string as overlay, you can very well replace it with a button or an image. You wont believe this is my first ever android app LOL. Anyways if you are more experienced with android apps than me, please try

    • changing parameters 2 and 3 in "new WindowManager.LayoutParams"
    • try some different event approach
    0 讨论(0)
  • 2020-11-21 07:24

    @Sarwar Erfan's answer does not work any longer as Android does not allow adding view with WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY to window to be touchable anymore not with even WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH.

    I found solution to this problem. You can check it out in following question

    When adding view to window with WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, it is not getting touch event

    0 讨论(0)
  • 2020-11-21 07:27

    Starting with Android 4.x, Android team fixed a potential security problem by adding a new function adjustWindowParamsLw() in which it will add FLAG_NOT_FOCUSABLE, FLAG_NOT_TOUCHABLE and remove FLAG_WATCH_OUTSIDE_TOUCH flags for TYPE_SYSTEM_OVERLAY windows.

    That is, a TYPE_SYSTEM_OVERLAY window won't receive any touch event on ICS platform and, of course, to use TYPE_SYSTEM_OVERLAY is not a workable solution for ICS and future devices.

    0 讨论(0)
  • 2020-11-21 07:30

    Here is some simple solution, All you need is to inflate XML layout just like you do on list adapters, just make XML layout to inflate it. Here is code that all you need.

     public class HUD extends Service {
        View mView;
    
        LayoutInflater inflate;
        TextView t;
        Button b;
    
        @Override
        public void onCreate() {
            super.onCreate();   
    
            Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
    
    
            WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    
            Display display = wm.getDefaultDisplay();  get phone display size
            int width = display.getWidth();  // deprecated - get phone display width
            int height = display.getHeight(); // deprecated - get phone display height 
    
    
            WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    width, 
                    height,
                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                     PixelFormat.TRANSLUCENT);
    
    
            params.gravity = Gravity.LEFT | Gravity.CENTER;
            params.setTitle("Load Average");
    
            inflate = (LayoutInflater) getBaseContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
            mView = inflate.inflate(R.layout.canvas, null);
    
            b =  (Button) mView.findViewById(R.id.button1);
            t = (TextView) mView.findViewById(R.id.textView1);
            b.setOnClickListener(new OnClickListener() {
    
            public void onClick(View v) {
                // TODO Auto-generated method stub
                t.setText("yes you click me ");
            }
           });
    
            wm.addView(mView, params);
    
            }
    
    
    
        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题