当用户单击正确的目标应用程序时,如何关闭ACTION_USAGE_ACCESS_SETTINGS意图? [英] How to close ACTION_USAGE_ACCESS_SETTINGS intent when user click correct target application?

查看:395
本文介绍了当用户单击正确的目标应用程序时,如何关闭ACTION_USAGE_ACCESS_SETTINGS意图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在设置(Settings->Security->Apps with usage access)中使用Intent ACTION_USAGE_ACCESS_SETTINGS以在Lollipop版本中使用UsageStatsManager.

 public static final int MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS = 1;

 if(!hasPermission()){
                startActivityForResult(
                        new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS),
                        MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS);
            }

首先,onCreate()将检查该应用程序的权限.并在应用没有权限(不检查)的情况下打开Intent

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private boolean hasPermission() {
    try {
        PackageManager packageManager = getApplicationContext().getPackageManager();
        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(getApplicationContext().getPackageName(), 0);
        AppOpsManager appOpsManager = (AppOpsManager) getApplicationContext().getSystemService(Context.APP_OPS_SERVICE);
        int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
        return (mode == AppOpsManager.MODE_ALLOWED);

    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

我的问题是我想关闭设置窗口,如果用户在目标应用程序中选择(选中),否则,它将显示有关应用程序名称的消息以指导用户的选择.我该怎么做?谢谢你.我认为它将在onActivityResult函数中起作用

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS){
        ...
    }
}

我引用了链接检查我的应用程序是否启用了使用权限,但是它只是检查应用程序的启用情况.

解决方案

还有另一种有趣的方法:

private boolean hasPermissionToReadNetworkHistory() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return true;
    }
    final AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
    int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
            android.os.Process.myUid(), getPackageName());
    if (mode == AppOpsManager.MODE_ALLOWED) {
        return true;
    }
    appOps.startWatchingMode(AppOpsManager.OPSTR_GET_USAGE_STATS,
            getApplicationContext().getPackageName(),
            new AppOpsManager.OnOpChangedListener() {
                @Override
                @TargetApi(Build.VERSION_CODES.KITKAT)
                public void onOpChanged(String op, String packageName) {
                    int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
                            android.os.Process.myUid(), getPackageName());
                    if (mode != AppOpsManager.MODE_ALLOWED) {
                        return;
                    }
                    appOps.stopWatchingMode(this);
                    Intent intent = new Intent(MainActivity.this, MainActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplicationContext().startActivity(intent);
                }
            });
    requestReadNetworkHistoryAccess();
    return false;
}

private void requestReadNetworkHistoryAccess() {
    Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
    startActivity(intent);
}

请小心并删除调用该方法的侦听器:

void stopWatchingMode (AppOpsManager.OnOpChangedListener callback)

上面的示例只是打开主应用程序活动.但是,您可以添加任何行为:

  • 传递额外的intent参数以通知刚刚打开的活动以向用户显示对话框
  • 启动后台服务以显示吐司,该用户必须授予该权限.
  • 等...

查看此存储库,因为它演示了这种情况和NetworkStats的整体用法./p>

I am using Intent ACTION_USAGE_ACCESS_SETTINGS in setting (Settings->Security->Apps with usage access) to use UsageStatsManager in the Lollipop version.

 public static final int MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS = 1;

 if(!hasPermission()){
                startActivityForResult(
                        new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS),
                        MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS);
            }

First, onCreate() will check the permission for the app. and turn on the Intent if the app has no permission (does not check)

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private boolean hasPermission() {
    try {
        PackageManager packageManager = getApplicationContext().getPackageManager();
        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(getApplicationContext().getPackageName(), 0);
        AppOpsManager appOpsManager = (AppOpsManager) getApplicationContext().getSystemService(Context.APP_OPS_SERVICE);
        int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
        return (mode == AppOpsManager.MODE_ALLOWED);

    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

My question is that I want to close the setting window, if the user chooses (check) in target app, otherwise, it will show a message about application name to guide the chosen of the user. How can I do it? Thank you. I think it will do in onActivityResult function

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS){
        ...
    }
}

I refer the link Check if my application has usage access enabled, but it just checks enable of the app.

解决方案

AppOpsManager has another interesting method:

void startWatchingMode (String op, String packageName, AppOpsManager.OnOpChangedListener callback)

from documentation:

Monitor for changes to the operating mode for the given op in the given app package.

Basically this is what you expect -> react on permission to read package usage stats switch change.

What you need to do is check the allowance state and if it is not granted, open the Settings and create a listener:

private boolean hasPermissionToReadNetworkHistory() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return true;
    }
    final AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
    int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
            android.os.Process.myUid(), getPackageName());
    if (mode == AppOpsManager.MODE_ALLOWED) {
        return true;
    }
    appOps.startWatchingMode(AppOpsManager.OPSTR_GET_USAGE_STATS,
            getApplicationContext().getPackageName(),
            new AppOpsManager.OnOpChangedListener() {
                @Override
                @TargetApi(Build.VERSION_CODES.KITKAT)
                public void onOpChanged(String op, String packageName) {
                    int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
                            android.os.Process.myUid(), getPackageName());
                    if (mode != AppOpsManager.MODE_ALLOWED) {
                        return;
                    }
                    appOps.stopWatchingMode(this);
                    Intent intent = new Intent(MainActivity.this, MainActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplicationContext().startActivity(intent);
                }
            });
    requestReadNetworkHistoryAccess();
    return false;
}

private void requestReadNetworkHistoryAccess() {
    Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
    startActivity(intent);
}

Be careful and remove the listener calling the method:

void stopWatchingMode (AppOpsManager.OnOpChangedListener callback)

The example above is just opening main application activity. However you might add any behaviour:

  • pass extra intent parameter to inform just opened activity to show dialog to user
  • Start background service to show toast, that user must grant the permission.
  • etc...

Check out this repository, as it demonstrates this case and the overall usage of NetworkStats.

这篇关于当用户单击正确的目标应用程序时,如何关闭ACTION_USAGE_ACCESS_SETTINGS意图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆