6

I need to check if another app has the permission to External Storage Manager. With

Environment.isExternalStorageManager()

I check if the current app is granted. How can I do this for another app? I already tried to check the permission status with

getPackageManager().checkPermission(Manifest.permission.MANAGE_EXTERNAL_STORAGE, "dk.tacit.android.foldersync.lite")

but it return always -1, which means PERMISSION_DENIED, even if the permission is granted.

TiJo
  • 63
  • 4

2 Answers2

4

You can try using AppOpsManager class like this :

try {
        PackageManager packageManager = this.getPackageManager();
        ApplicationInfo info = packageManager.getApplicationInfo("package name",0);
        Log.d("TAG", "onCreate: "+hasPermission(this,info)); 
        
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }

Now the hasPermission function :

@RequiresApi(api = Build.VERSION_CODES.R)
public static boolean hasPermission(Context context,ApplicationInfo info) {
    boolean granted = false;
    AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
    int mode = appOps.unsafeCheckOpNoThrow(AppOpsManager.permissionToOp("android.permission.MANAGE_EXTERNAL_STORAGE"), info.uid, info.packageName);
    if (mode == AppOpsManager.MODE_DEFAULT)
        granted = (context.checkCallingOrSelfPermission(Manifest.permission.MANAGE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
    else
        granted = (mode == AppOpsManager.MODE_ALLOWED);
    return granted;
}

You also have to declare QUERY_ALL_PACKAGES permission in the manifest :

<uses-permission
    android:name="android.permission.QUERY_ALL_PACKAGES"
    tools:ignore="QueryAllPackagesPermission" />
DrHowdyDoo
  • 2,327
  • 2
  • 7
  • 21
0

Here are more generalized version of DrHowdyDoo's solution

fun isExternalStorageManager(
    packageName: String,
    context: Context,
    packageManger: PackageManager
): Boolean {
    return hasPermission(packageName, MANAGE_EXTERNAL_STORAGE, context, packageManger)
}


fun hasPermission(
    packageName: String,
    permission: String,
    context: Context,
    packageManger: PackageManager
): Boolean {
    val granted: Boolean
    val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager

    val info = packageManger.getApplicationInfo(packageName, 0)
    val mode = appOps.unsafeCheckOpNoThrow(
        AppOpsManager.permissionToOp(permission)!!,
        info.uid,
        packageName
    )
    granted = if (mode == AppOpsManager.MODE_DEFAULT) {
        context.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED
    } else {
        (mode == AppOpsManager.MODE_ALLOWED)
    }

    return granted
}

Example:

isExternalStorageManager("dk.tacit.android.foldersync.lite", this, getPackageManager())

You can also add the queried package like this in AndroidManifest.xml:

<queries>
    <package android:name="dk.tacit.android.foldersync.lite" />
</queries>
TiJo
  • 63
  • 4