12

我有一个浮动图标,它位于所有活动之上,但是当设备被锁定时,它会消失,直到设备被解锁。

另一个含义,我想使用服务中的窗口管理器在锁定屏幕上显示一个视图(FloatIcon)。

到目前为止,这是我的代码。

public class FloatIcon extends Service {

    private WindowManager windowManager;
    private ImageView floatIcon;

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

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

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        floatIcon = new ImageView(this);
        floatIcon.setImageResource(R.drawable.ic_launcher);
        floatIcon.setClickable(true);
        floatIcon.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getBaseContext(), MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                getApplication().startActivity(intent);
            }
        });

        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;

        windowManager.addView(floatIcon, params);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (floatIcon != null)
            windowManager.removeView(floatIcon);
    }
}

当我用谷歌搜索时,我找不到有用的东西。

4

3 回答 3

12

使用 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR 而不是 WindowManager.LayoutParams.TYPE_PHONE 可以解决问题。这将使视图能够监听触摸事件。但是,您也可以使用 WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY 但它不会监听触摸事件

于 2015-06-05T19:41:28.483 回答
7

虽然问题得到了回答,但有一些解释:- 使用带有FLAG_SHOW_WHEN_LOCKED的TYPE_PHONE窗口只会在该窗口全屏时显示在锁定屏幕上 - 访问android 参考,而使用TYPE_SYSTEM_ERROR窗口类型没有全屏限制,从而解决了问题。

正如@milosmns 所要求的那样,解决方法可以是在您的代码中添加大约 100 毫秒的延迟,在来电屏幕上显示窗口的代码将像魅力一样工作。

于 2016-05-26T11:45:28.167 回答
0

不要在 OnCreate 本身中添加视图。而是制作一个广播接收器并将意图传递给它。这将仅在屏幕锁定时显示您的图标。当屏幕解锁时它会消失。以下是代码片段。不要忘记在清单中列出您的服务。

public class FloatingIconService extends Service {

private BroadcastReceiver mReceiver;
private boolean isShowing = false;
private WindowManager windowManager;
public ImageView icon;
private WindowManager.LayoutParams params;

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

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    Log.i("onStart", "FloatingIconService");

    return super.onStartCommand(intent,flags,startId);
}

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

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    //add icon and its properties
    icon = new ImageView(this);
    icon.setImageResource(R.drawable.ic_action_name);
    icon.setClickable(true);
    icon.setPadding(10, 10, 10, 10);
    icon.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {

            Log.i("onStart", "FloatingIconService when long press on icon");
            ((Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE)).vibrate(1000);

            Intent i = new Intent(getApplicationContext(), Dashboard.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            startActivity(i);
            return true;
        }
    });

    //set parameters for the icon
    params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.BOTTOM;
    params.x=0;
    params.y=0;

    //Register receiver for determining screen off and if user is present
    mReceiver = new FloatingIconReceiver();
    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
    filter.addAction(Intent.ACTION_USER_PRESENT);

    registerReceiver(mReceiver, filter);
}

private class FloatingIconReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            //if screen is turn off show the icon
            if (!isShowing) {
                windowManager.addView(icon, params);
                isShowing = true;
            }
        } else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
            //Handle resuming events if user is present/screen is unlocked remove the icon immediately
            if (isShowing) {
                windowManager.removeViewImmediate(icon);
                isShowing = false;
            }
        }
    }
}

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

    if (mReceiver != null) {
        unregisterReceiver(mReceiver);
    }

    //remove view if it is showing and the service is destroy
    if (isShowing) {
        windowManager.removeViewImmediate(icon);
        isShowing = false;
    }
    super.onDestroy();
}

}

只有有人可以帮助我使这个图标浮动。就像我们可以在活动中使用 FAB 一样。

于 2018-08-24T09:15:20.770 回答