Creating a system overlay window (always on top)

前端 未结 16 953
南方客
南方客 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:38

    Try this. Works fine in ICS. If You want to stop service simply click the notification generated in statusbar.

     public class HUD extends Service
     {
        protected boolean foreground = false;
        protected boolean cancelNotification = false;
        private Notification notification;
        private View myView;
        protected int id = 0;
        private WindowManager wm;
        private WindowManager.LayoutParams params;
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
        @Override
        public void onCreate() {
            super.onCreate();
           // System.exit(0);
            Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_SHORT).show();
            params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
            params.gravity=Gravity.TOP|Gravity.LEFT;
        wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        inflateview();
        foregroundNotification(1);
        //moveToForeground(1,n,true);
        }     
       @Override
        public void onDestroy() {
            super.onDestroy();
            ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(0);
            Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_SHORT).show();
            if(myView != null)
            {
                ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(myView);
                myView = null;
            }
        }
        protected Notification foregroundNotification(int notificationId) 
       {    
        notification = new Notification(R.drawable.ic_launcher, "my Notification", System.currentTimeMillis());    
            notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_ONLY_ALERT_ONCE;   
            notification.setLatestEventInfo(this, "my Notification", "my Notification", notificationIntent());          
            ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(id, notification);            
            return notification;
        }
        private PendingIntent notificationIntent() {
            Intent intent = new Intent(this, stopservice.class);    
            PendingIntent pending = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);    
            return pending;
        }
        public void inflateview()
        {
             LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
                myView = inflater.inflate(R.layout.activity_button, null);
                myView.setOnTouchListener(new OnTouchListener() {
                   @Override
                   public boolean onTouch(View v, MotionEvent event) {
                       Toast.makeText(getBaseContext(),"onToasttt", Toast.LENGTH_SHORT).show();
                       return false;
                   }
                 });
                // Add layout to window manager
                wm.addView(myView, params); 
        }
    }
    

    UPDATE

    Sample here

    To create an overlay view, when setting up the LayoutParams DON'T set the type to TYPE_SYSTEM_OVERLAY.

    Instead set it to TYPE_PHONE.
    
    Use the following flags:
    
    FLAG_NOT_TOUCH_MODAL
    
    FLAG_WATCH_OUTSIDE_TOUCH
    

提交回复
热议问题