如何在运行时在Android Marshmallow中获取CLEAR_APP_CACHE权限?

时间:2016-10-26 11:29:43

标签: android android-6.0-marshmallow android-permissions

代码

void clearCache() {

    if (mClearCacheObserver == null) {
        mClearCacheObserver = new CachePackageDataObserver();
    }

    PackageManager mPM = getPackageManager();

    @SuppressWarnings("rawtypes")
    final Class[] classes = {Long.TYPE, IPackageDataObserver.class};

    Long localLong = Long.valueOf(CACHE_APP);


    try {
        Method localMethod =
                mPM.getClass().getMethod("freeStorageAndNotify", classes);

        localMethod.setAccessible(true);
        // Start of inner try-catch block

        try {
            localMethod.invoke(mPM, localLong, mClearCacheObserver);

        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.getCause().printStackTrace();
        }

        // End of inner try-catch block

    } catch (NoSuchMethodException e1) {

        e1.printStackTrace();
    }

}

logcat的

java.lang.SecurityException: Neither user 10206 nor current process has android.permission.CLEAR_APP_CACHE.
     at android.os.Parcel.readException(Parcel.java:1620)
     at android.os.Parcel.readException(Parcel.java:1573)
     at android.content.pm.IPackageManager$Stub$Proxy.freeStorageAndNotify(IPackageManager.java:5081)
     at android.app.ApplicationPackageManager.freeStorageAndNotify(ApplicationPackageManager.java:2500)
     at android.content.pm.PackageManager.freeStorageAndNotify(PackageManager.java:4710)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.onexsoftech.clearcacheapp.MainActivity.clearCache(MainActivity.java:278)
     at com.onexsoftech.clearcacheapp.MainActivity.insertDummyContactWrapper1(MainActivity.java:495)
     at com.onexsoftech.clearcacheapp.MainActivity.insertDummyContact(MainActivity.java:472)

3 个答案:

答案 0 :(得分:6)

在Android 6.0 CLEAR_APP_CACHE had a protectionLevel of dangerous之前,普通的SDK应用可以在清单中请求它。

自Android 6.0起,CLEAR_APP_CACHE has a protectionLevel of signature|privileged。普通的Android应用无法拥有此权限。如果您的应用程序使用固件的签名密钥签名,或者您已安装在特权系统分区上,则只能保留此权限。

答案 1 :(得分:4)

来自Android M - > CLEAR_APP_CACHE,保护级别:系统|签名

  

Android 6.0不会改变正常权限的行为(全部   非危险权限,包括普通,系统和签名   权限)。

因此无法在运行时请求该权限。更准确地说

  

签名系统权限,意味着它只能被保留   使用固件的签名密钥签名或已安装的应用程序   在系统分区上(例如,由有根设备的用户)。来自this stackoverflow Q / A.

文档: https://source.android.com/devices/tech/config/runtime_perms.html#affected-permissions

答案 2 :(得分:-3)

在AndroidManifest.xml中添加权限

<permission android:name="android.permission.CLEAR_APP_CACHE"/>
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>

为请求代码创建一个常量。

<强> Constants.java

public static final int REQUEST_CODE_FOR_PERMISSION = 501;

申请许可: -

public static void requestPermissionForClearCache(Activity activity) {
    if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CLEAR_APP_CACHE) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CLEAR_APP_CACHE)) {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CLEAR_APP_CACHE}, Constatnts.REQUEST_CODE_FOR_PERMISSION);
        } else {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CLEAR_APP_CACHE}, Constatnts.REQUEST_CODE_FOR_PERMISSION);
        }
    }
}

在片段中覆盖下面的方法。

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    if (requestCode == Constatnts.REQUEST_CODE_FOR_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        // permission was granted successfully
    } else {
        // permission was NOT granted successfully
    }
}