来电界面上的悬浮窗口

3
我希望在有人打电话给我时显示一些信息。 我有一个服务。这个服务已经注册了广播接收器。该接收器监听android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED。 当我的手机解锁时,我能够显示toast,但是当我锁定手机并有人给我打电话时,toast就不会显示。 最好的方法是什么,可以在有人给我打电话时显示一些信息?
更新: 我创建了一个浮动窗口,在电话响起时打开它。 这个方法非常有效,但是当我锁定手机并有人给我打电话时,窗口就不会显示。当我接听电话时,浮动窗口才出现。有没有办法在锁屏界面上显示这个浮动窗口? 以下是我打开浮动窗口的方式:
new Handler().postDelayed(new Runnable() {

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

这是我的浮动窗口。
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();
        }
    });
}

}

1个回答

2

好的,我一年前就解决了这个问题,但是还没有人写过这个问题,所以我会提供我的解决方案。

这是我打开浮动窗口的方法:

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

在这里,是我浮动窗口服务的onCreate方法。
@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;
        }
    });       
}

它甚至在锁屏状态下也能完美运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接