您当前的位置:首页 > 计算机 > 编程开发 > 安卓(android)开发

流量统计权限

时间:02-08来源:作者:点击数:

流量统计需要申请权限。实现步骤如下:

清单文件中申请权限:

<uses-permission
    android:name="android.permission.PACKAGE_USAGE_STATS"
    xmlns:tools="http://schemas.android.com/tools"
    tools:ignore="ProtectedPermissions" />

MainActivity中有一个按钮,点击后开始申请权限,代码如下:

class MainActivity : AppCompatActivity() {

    private lateinit var launcher: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            val isOk = it.resultCode == Activity.RESULT_OK
            Log.i("ABCD", "isOk = $isOk")
            if (!hasQueryTrafficStatsPermission(this)) {
                Log.i("ABCD", "用户拒绝了权限")
                launcher.launch(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
            } else {
                Log.i("ABCD", "用户给权限了")
            }
        }

        findViewById<Button>(R.id.button).setOnClickListener {
            if (hasQueryTrafficStatsPermission(this)) {
                Log.i("ABCD", "已经有流量统计权限了")
            } else {
                Log.i("ABCD", "开始申请流量统计权限")
                launcher.launch(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
            }
        }
    }

}

/** 判断是否有流量统计权限 */
fun hasQueryTrafficStatsPermission(activity: FragmentActivity): Boolean {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return true // 小于API 23版本的则默认就有流量统计权限了
    }
    val appOps = activity.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
    val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        appOps.unsafeCheckOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), activity.packageName)
    } else {
        @Suppress("DEPRECATION")
        appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), activity.packageName)
    }
    return mode == AppOpsManager.MODE_ALLOWED
}

注:不要使用it.resultCode == Activity.RESULT_OK来判断请求权限的结果,因为它永远为false。

为了使Activity更简洁,我们把请求权限相关代码封装到工具类中,如下:

object TrafficStatsPermissionUtil {

    private lateinit var launcher: ActivityResultLauncher<Intent>
    private lateinit var resultCallback: () -> Unit

    fun registerForActivityResult(activity: FragmentActivity) {
        launcher = activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (!hasQueryTrafficStatsPermission(activity)) {
                Log.i("ABCD", "用户拒绝了权限")
                showDialog(activity, """本应用需要获取"使用情况访问权限"权限,请给予此权限,否则无法使用本应用""") {
                    launcher.launch(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
                }
            } else {
                Log.i("ABCD", "用户给权限了")
                resultCallback()
            }
        }
    }

    fun requestTrafficStatsPermission(activity: FragmentActivity, resultCallback: () -> Unit) {
        this.resultCallback = resultCallback
        if (hasQueryTrafficStatsPermission(activity)) {
            Log.i("ABCD", "已经有流量统计权限了")
            resultCallback()
        } else {
            Log.i("ABCD", "开始申请流量统计权限")
            launcher.launch(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
        }
    }

    private fun showDialog(activity: FragmentActivity, message: String, okClick: () -> Unit) {
        AlertDialog.Builder(activity)
                .setTitle("提示")
                .setMessage(message)
                .setPositiveButton("确定") { _, _ -> okClick() }
                .setCancelable(false)
                .show()
    }

    /** 判断是否有流量统计权限 */
    private fun hasQueryTrafficStatsPermission(activity: FragmentActivity): Boolean {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true // 小于API 23版本的则默认就有流量统计权限了
        }
        val appOps = activity.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            appOps.unsafeCheckOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), activity.packageName)
        } else {
            @Suppress("DEPRECATION")
            appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), activity.packageName)
        }
        return mode == AppOpsManager.MODE_ALLOWED
    }
}
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        TrafficStatsPermissionUtil.registerForActivityResult(this)

        findViewById<Button>(R.id.button).setOnClickListener {
            TrafficStatsPermissionUtil.requestTrafficStatsPermission(this) {
                Log.i("ABCD", "哈哈哈,拿到流量统计权限了^_^")
            }
        }
    }

}
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门