Search code examples
androidincoming-call

Floating window on incoming call screen


I want show some info when somebody call me. I have service. This service has registred broadcastreceiver. This receiver listen for android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED. I'm able to show toast when my phone is unlocked, but when I have phone locked and someone is calling to me,a toast is not showing. What is the best way to show some info when someone is call to me?

Update: I created floating window which I open when phone is ringing. This work very well, but window is not showing when phone is locked and someone is calling to me. When I picked up the call, floating window is there. Is here some way to show this foating window on lockscreen incoming call screen? This is the way how I opening floating window:

new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    startService(new Intent(context, FloatingWindow.class));
                }
            }, 2000);

and this is my floatin window

public class FloatingWindow extends Service{

private WindowManager wm;
private LinearLayout ll;
private Button btnStop;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

    wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    ll = new LinearLayout(this);
    btnStop = new Button(this);

    ViewGroup.LayoutParams btnParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    btnStop.setText("Stop");
    btnStop.setLayoutParams(btnParameters);

    LinearLayout.LayoutParams llParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
    ll.setBackgroundColor(Color.argb(66, 255, 0, 0));
    ll.setLayoutParams(llParameters);

    final WindowManager.LayoutParams parameters = new WindowManager.LayoutParams(400, 150, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
    parameters.x = 0;
    parameters.y = 0;
    parameters.gravity = Gravity.CENTER | Gravity.CENTER;

    ll.addView(btnStop);
    wm.addView(ll, parameters);

    ll.setOnTouchListener(new View.OnTouchListener() {

        private WindowManager.LayoutParams updatedParameters = parameters;
        int x, y;
        float touchedX, touchedY;
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    x = updatedParameters.x;
                    y = updatedParameters.y;

                    touchedX = event.getRawX();
                    touchedY = event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    updatedParameters.x = (int) (x + (event.getRawX() - touchedX));
                    updatedParameters.y = (int) (y + (event.getRawY() - touchedY));

                    wm.updateViewLayout(ll, updatedParameters);
                    break;
                default:
                    break;
            }
            return false;
        }
    });

    btnStop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            wm.removeView(ll);
            stopSelf();
        }
    });
}

}


Solution

  • ok, so I solved it a year ago, but no one has yet written this question, so I will give my solution.

    Here is how I open floating window:

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            context.startService(new Intent(context, FloatingWindow.class));
        }
    }, 1000);
    

    And here, onCreate from my FloatingWindow Service

    @Override
    public void onCreate() {
        super.onCreate();
    
        wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        ll = new LinearLayout(this);
        btnStop = new Button(this);
    
        gestureDetector = new GestureDetector(this, new GestureListener());
    
        ViewGroup.LayoutParams btnParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        btnStop.setText("X");
        btnStop.setLayoutParams(btnParameters);
    
        ViewGroup.LayoutParams tvParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
    
        LinearLayout.LayoutParams llParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        ll.setBackgroundColor(Color.argb(255, 255, 0, 0));
        ll.setLayoutParams(llParameters);
    
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
    
        params.gravity = Gravity.CENTER;
    
        View popup_view = ((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.popup_window, ll, false);
        tvInfo = (TextView) popup_view.findViewById(R.id.message);
        tvInfo.setText(this.getMessage());
    
        ll.addView(popup_view);
        wm.addView(ll, params);
    
    
    
        ll.setOnTouchListener(new View.OnTouchListener() {
    
            private WindowManager.LayoutParams updatedParameters = params;
            int x, y;
            float touchedX, touchedY;
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                gestureDetector.onTouchEvent(event);
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        x = updatedParameters.x;
                        y = updatedParameters.y;
    
                        touchedX = event.getRawX();
                        touchedY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        updatedParameters.x = (int) (x + (event.getRawX() - touchedX));
                        updatedParameters.y = (int) (y + (event.getRawY() - touchedY));
    
                        wm.updateViewLayout(ll, updatedParameters);
                        break;
                    default:
                        break;
                }
                return false;
            }
        });
    
        gestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                return true;
            }
    
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                stopSelf();
                return false;
            }
    
            @Override
            public boolean onDoubleTapEvent(MotionEvent e) {
                return true;
            }
        });       
    }
    

    It work perfectly even on lock screen.