流量统计需要申请权限。实现步骤如下:
清单文件中申请权限:
- <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", "哈哈哈,拿到流量统计权限了^_^")
- }
- }
- }
-
- }
-