简体   繁体   English

Android:如何通过锁定屏幕显示对话框或活动[未解锁屏幕]

[英]Android : How to show dialog or activity over lock screen[ not unlock the screen]

我有一个应用程序,它将从服务器接收消息并向用户发出一个对话框。所以当手机在锁定屏幕上时我希望对话框显示在锁定屏幕的顶部但不解锁它。是否有人给我建议?

I solved something similar in the following way. 我用以下方式解决了类似问题。 Create services, to broadcast the action " ACTION_SCREEN_ON & ACTION_USER_PRESENT & ACTION_SCREEN_OFF ", create function to show the windows with WINDOW_SERVICE . 创建服务,广播动作“ ACTION_SCREEN_ONACTION_USER_PRESENTACTION_SCREEN_OFF ”,创建用WINDOW_SERVICE显示窗口的功能。 I use a service for my requirements, but it can adapt. 我根据我的要求使用服务,但它可以适应。

public class OverlayService extends Service {

    private static final String TAG = OverlayService.class.getSimpleName();
    WindowManager mWindowManager;
    View mView;
    Animation mAnimation;

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        registerOverlayReceiver();
        return super.onStartCommand(intent, flags, startId);
    }

    private void showDialog(String aTitle){
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        mView = View.inflate(getApplicationContext(), R.layout.fragment_overlay, null);
        mView.setTag(TAG);

        int top = getApplicationContext().getResources().getDisplayMetrics().heightPixels / 2;

        RelativeLayout dialog = (RelativeLayout) mView.findViewById(R.id.dialog);
        LayoutParams lp = (LayoutParams) dialog.getLayoutParams();
        lp.topMargin = top;
        lp.bottomMargin = top;
        mView.setLayoutParams(lp);

        ImageButton imageButton = (ImageButton) mView.findViewById(R.id.close);
        lp = (LayoutParams) imageButton.getLayoutParams();
        lp.topMargin = top - 58;
        imageButton.setLayoutParams(lp);
        imageButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mView.setVisibility(View.INVISIBLE);
            }
        });

        TextView title = (TextView) mView.findViewById(R.id.Title);
        title.setText(aTitle);

        final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
        WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ,
        PixelFormat.RGBA_8888);

        mView.setVisibility(View.VISIBLE);
        mAnimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.in);
        mView.startAnimation(mAnimation);
        mWindowManager.addView(mView, mLayoutParams);

    }

    private void hideDialog(){
        if(mView != null && mWindowManager != null){
            mWindowManager.removeView(mView);
            mView = null;
        }
    }

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

    private void registerOverlayReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        registerReceiver(overlayReceiver, filter);
    }

    private void unregisterOverlayReceiver() {
        hideDialog();
        unregisterReceiver(overlayReceiver);
    }


    private BroadcastReceiver overlayReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "[onReceive]" + action);
            if (action.equals(Intent.ACTION_SCREEN_ON)) {
                showDialog("Esto es una prueba y se levanto desde");
            }
            else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                hideDialog();
            }
            else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                hideDialog();
            }
        }
    };
}

I hope it useful! 我希望它有用!

public void onAttachedToWindow() {
      Window window = getWindow();
      window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
           | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
           | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
           | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}

Finally I achieved the same. 最后我实现了同样的目标。 Don't go for activity, because android will not show lock screen behind your activity for security reason, so use service instead of Activity. 不要去活动,因为安全原因,android不会在你的活动后面显示锁屏,所以使用服务代替Activity。

Below is my code in onStartCommand of my service 下面是我服务的onStartCommand中的代码

WindowManager mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

View mView = mInflater.inflate(R.layout.score, null);

WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
/* | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON */,
PixelFormat.RGBA_8888);

mWindowManager.addView(mView, mLayoutParams);

And add <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> to manifest 并将<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />到清单

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM