欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Activity实现系统Dialog(系统级的悬浮窗)

程序员文章站 2022-04-24 20:57:40
...

1 创建一个style

 <style name="customDialog" parent="Theme.AppCompat.Light.Dialog">
        <item name="windowNoTitle">true</item>
        <!--背景透明-->
        <item name="android:windowIsTranslucent">true</item>
        <!--是否有覆盖-->
        <item name="android:windowContentOverlay">@null</item>
        <!--是否浮动-->
        <item name="android:windowIsFloating">false</item>
        <!--边框-->
        <item name="android:windowFrame">@null</item>
        <!--背景:透明-->
        <item name="android:windowBackground">@null</item>
        <!-- 背景透明 -->
        <item name="android:backgroundDimEnabled">false</item>
    </style>

2 manifest里面声明:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

<activity android:name=".DialogActivityDemo" android:theme="@style/customDialog"></activity>

3 代码里弹出:

 public void showDialog(){
        if (Build.VERSION.SDK_INT >= 23) {
            // 判断悬浮窗权限是否开启
            if (Settings.canDrawOverlays(this)) {
                // 悬浮窗权限已开启,可以直接使用
                LogUtil.d(TAG,"111");
                showOverlayWindow();
            } else {
                // 没有悬浮窗权限,去设置开启悬浮窗权限
                try {
                    LogUtil.d(TAG,"222");
                    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                    // 在Activity::onActivityResult里启动悬浮窗
                    startActivityForResult(intent, 9999);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } else {
            // Android6.0以下,声明默认有悬浮窗权限,但是 华为, 小米,oppo等手机会有自己的一套Android6.0以下的悬浮窗权限管理,也需要考虑做适配!!!
            showOverlayWindow();
        }

    }

    private void showOverlayWindow() {
        Intent intent = new Intent(MyApplication.getInstance(),DialogActivityDemo.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
    }

5.编写真正的对话框 DialogActivityDemo


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class DialogActivityDemo extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        initDialog();
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog_demo);
    }


    public void initDialog() {
        getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);/*WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY TYPE_SYSTEM_DIALOG*/
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.width = (int) getResources().getDimension(R.dimen.length_444);
        lp.height = (int) getResources().getDimension(R.dimen.length_636);
        lp.x = 14;
        lp.y = 10;
        lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                WindowManager.LayoutParams.FLAG_FULLSCREEN |
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION |
                WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
        getWindow().setAttributes(lp);
    }
}

重点

因为我要做的是系统级对话框,是不能依赖activity的,最重要的是,我不想要背后的activity弹出来。此处要做的就是启动对话框的时候把应用的activity清空给finish掉即可。

但是这种对话框真正的应用场景应该是开机启动的某一个服务或者广播或者某个action,原本就没有其他activity。

相关标签: android tip(1)