Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to close ACTION_USAGE_ACCESS_SETTINGS intent when user click correct target application?

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.

like image 398
user3051460 Avatar asked Sep 23 '16 02:09

user3051460


People also ask

What is an access intent in Salesforce?

The Access Intent column includes one of the following values: Indicates that the object uses the predefined database access intent. Sets the object to use the primary database, allowing the user to modify data. Sets the object to use the database replica, which means that the user can only view data, not change data.

How to get current foreground application using usagestatsmanager API?

I'm using the new UsageStatsManager API to get current foreground application in Android 5.0 Lollipop. In order to use this API, the user must enable the application in the Settings->Security->Apps with usage access screen. I send the user directly to this screen with this Intent: Now, I want to validate the user enabled my application.

How do implicit intents work with multiple apps?

If there's more than one app that can handle the intent, the system presents the user with a dialog to pick which app to use. This page describes several implicit intents that you can use to perform common actions, organized by the type of app that handles the intent.

How do I use the database access intent list?

Choose the icon, enter Database Access Intent List, and then choose the related link. The page lists all reports, pages, and queries. The Access Intent column includes one of the following values: Indicates that the object uses the predefined database access intent. Sets the object to use the primary database, allowing the user to modify data.


1 Answers

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.

like image 153
R. Zagórski Avatar answered Oct 02 '22 04:10

R. Zagórski