1、判断悬浮窗是否打开
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val canDrawOverlays = Settings.canDrawOverlays(this)
Log.d(TAG, "onCreate:canDrawOverlays=$canDrawOverlays ")
findViewById<TextView>(R.id.status).text = "是否可悬浮在其他app上:${canDrawOverlays.toString()}"
}
2.Settings.canDrawOverlays(this)
/**
* Checks if the specified context can draw on top of other apps. As of API
* level 23, an app cannot draw on top of other apps unless it declares the
* {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission in its
* manifest, <em>and</em> the user specifically grants the app this
* capability. To prompt the user to grant this approval, the app must send an
* intent with the action
* {@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}, which
* causes the system to display a permission management screen.
*
* @param context App context.
* @return true if the specified context can draw on top of other apps, false otherwise
*/
public static boolean canDrawOverlays(Context context) {
return Settings.isCallingPackageAllowedToDrawOverlays(context, Process.myUid(),
context.getOpPackageName(), false) || context.checkSelfPermission(
Manifest.permission.SYSTEM_APPLICATION_OVERLAY)
== PackageManager.PERMISSION_GRANTED;
}
检查指定的context是否可以绘制到其他app之上,从23开始,要出现悬浮框,必须注册权限SYSTEM_ALERT_WINDOW,并且用户要明确授权此意图。要提示用户授予此批准,应用程序必须发送带有操作的意图。
Settings#ACTION_MANAGE_OVERLAY_PERMISSION 跳转到系统显示管理权限的界面
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
如果不注册SYSTEM_ALERT_WINDOW权限,在系统中悬浮窗配置列表中,会找不到自己的应用。
3.code
class MainActivity : AppCompatActivity() {
private val PermissionRequestCode = 11111
private var activityResultLauncher: ActivityResultLauncher<Intent>? = null
private val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
activityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult(), object :
ActivityResultCallback<ActivityResult> {
override fun onActivityResult(result: ActivityResult?) {
//接收回调,更新状态
updateStatus()
}
})
findViewById<Button>(R.id.click).setOnClickListener {
val intent = Intent()
intent.action = Settings.ACTION_MANAGE_OVERLAY_PERMISSION
intent.data = Uri.parse("package:$packageName");
activityResultLauncher?.launch(intent)
}
}
private fun updateStatus() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val canDrawOverlays = Settings.canDrawOverlays(this)
Log.d(TAG, "onCreate:canDrawOverlays=$canDrawOverlays ")
findViewById<TextView>(R.id.status).text = "是否可悬浮在其他app上:${canDrawOverlays.toString()}"
}
}
}
4. java.lang.IllegalStateException: LifecycleOwner com.xx.MainActivity@28b4e79 is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
registerForActivityResult 要提前初始化,准备来说要在activity的start()结束之前初始化
java.lang.IllegalStateException: LifecycleOwner com.example.testoverlaypermission.MainActivity@28b4e79 is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
at androidx.activity.result.ActivityResultRegistry.register(ActivityResultRegistry.java:123)
at androidx.activity.ComponentActivity.registerForActivityResult(ComponentActivity.java:682)
at androidx.activity.ComponentActivity.registerForActivityResult(ComponentActivity.java:691)
at com.example.testoverlaypermission.MainActivity.onCreate$lambda-1(MainActivity.kt:28)