Android系统重叠窗口

时间:2015-09-18 12:52:30

标签: java android android-permissions

我正在尝试创建系统叠加层。但我一直得到'#34;许可被拒绝"。我使用的是SDK版本23。

我的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test" >

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".activity.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

我用来创建叠加层的代码:

    //mView = new HUDView(this);
    mButton = new Button(this);
    mButton.setText("Overlay button");
    mButton.setOnTouchListener(this);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.RIGHT | Gravity.TOP;
    params.setTitle("Load Average");
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    wm.addView(mButton, params);

7 个答案:

答案 0 :(得分:30)

首先,没有名为SYSTEM_OVERLAY_WINDOW的权限。它是SYSTEM_ALERT_WINDOW

其次,如果您的targetSdkVersion为23或更高,并且您在Android 6.0及更高版本的设备上运行,那么您的应用一开始就无法获得此权限。请致电Settings.canDrawOverlays()查看您是否拥有该权限,如果不这样做,请使用ACTION_MANAGE_OVERLAY_PERMISSION将用户引导至“设置”。

答案 1 :(得分:22)

在AndroidManifest(版本&lt; 23)

        Dim lst As List(Of SourceInfo) = New List(Of SourceInfo)()
    lst.Add(New SourceInfo() With {.Id = 1, .Name = "First"})
    lst.Add(New SourceInfo() With {.Id = 2, .Name = "Second"})

    Dim q = From li In lst
           Select New With {li.Id, li.Name}

    Dim retLst = lst.CreateAndFillList(Of TargetInfo)()

    Dim retLst1 = q.CreateAndFillList(Of TargetInfo)()

结果:

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


public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE= 5469;
//Random value

    public void testPermission() {
        if (!Settings.canDrawOverlays(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
        }
    }

答案 2 :(得分:0)

您还可以将用户引导至特定应用的重叠页面。文档states

  

输入:可选地,Intent的数据URI可以指定应用程序包名称以直接调用特定于包名称的管理GUI。例如&#34; package:com.my.app&#34;。

类似于:

intent.setData(Uri.fromParts("package", getPackageName(), null));

答案 3 :(得分:0)

作为替代解决方案,您可以尝试使用WindowManager.LayoutParams.TYPE_TOAST而不是WindowManager.LayoutParams.TYPE_SYSTEM_ALERT。 这不需要任何许可。  我用它来显示图像,也许按钮会起作用

答案 4 :(得分:0)

对于低于android 8的用户使用

<nuxt-link></nuxt-link>

答案 5 :(得分:0)

我处理了library中每个android版本的所有覆盖权限。请在此处查看gistenter image description here

答案 6 :(得分:0)

对于显示在其他应用程序中需要在清单中添加权限

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

检查您的应用是否有权限

Settings.canDrawOverlays(context)

检查权限 checkOverlayPermission

private const val CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084

private fun checkOverlayPermission(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
        //If the draw over permission is not available open the settings screen
        //to grant the permission.
        val intent = Intent(
            Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:$packageName")
        )
        startActivityForResult(
            intent,
            CODE_DRAW_OVER_OTHER_APP_PERMISSION
        )
    }
}

在 onActivityResult 中,您可以检查是否授予权限

override fun onActivityResult(
    requestCode: Int,
    resultCode: Int,
    data: Intent?
) {
    if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {
        if (Settings.canDrawOverlays(this)) {
            // Permission Granted
        } else {
            // Permission not Granted
            // If you want then call again checkOverlayPermission until permission granted
        }
    } 
}