How to delete app cache for all apps in Android M?

前端 未结 2 1010
有刺的猬
有刺的猬 2020-12-09 19:24

Is there an option to delete the cache of all Apps or certain Apps in Android M ?

Seems like most ways don\'t work anymore in Android M.

As a reference I u

相关标签:
2条回答
  • 2020-12-09 19:36

    Is there an option to delete the cache of all apps or certain apps in Android M?

    A third-party app cannot delete the cache of another app in Android 6.0+. The protection level of Manifest.permission.CLEAR_APP_CACHE changed from "dangerous" to "signature|privileged" or "system|signature" in Android 6.0+. Now, only apps signed with the firmware's key can hold this permission.

    Is there really no way to delete app cache on devices with Android M?

    Unless the app is installed as a system app or you have root access, there is no way to delete app cache on Android 6.0+.

    How does the Settings app handle it?

    Android is, of course, open source. Lets look at the code. In AppStorageSettings.java lines 172 - 178 we find:

    if (v == mClearCacheButton) {
        // Lazy initialization of observer
        if (mClearCacheObserver == null) {
            mClearCacheObserver = new ClearCacheObserver();
        }
        mPm.deleteApplicationCacheFiles(mPackageName, mClearCacheObserver);
    }
    

    So, the Settings app is using the hidden method PackageManager#deleteApplicationCacheFiles(String, IPackageDataObserver). It can do this because it holds the system level permission "android.permission.CLEAR_APP_USER_DATA" (a permission a third-party app cannot hold).


    External Cache

    However, cleaning of external cache is still supported.

    This is still possible on Android 6.0+. I haven't looked at the source code for the app you mentioned but I would assume all you need to do is request the WRITE_EXTERNAL_STORAGE permission, get all installed packages using PackageManager, get the app's external cache directory, and delete the directory.


    Root Access

    Of course, if you have root access you can delete another app's cache. Here is a quick example of using root access to delete all app cache. You can use Chainfire's libsuperuser to run commands in a root shell:

    PackageManager pm = getPackageManager();
    List<ApplicationInfo> installedApplications = pm.getInstalledApplications(0);
    for (ApplicationInfo applicationInfo : installedApplications) {
      try {
        Context packageContext = createPackageContext(applicationInfo.packageName, 0);
        List<File> directories = new ArrayList<>();
        directories.add(packageContext.getCacheDir());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
          Collections.addAll(directories, packageContext.getExternalCacheDirs());
        } else {
          directories.add(packageContext.getExternalCacheDir());
        }
    
        StringBuilder command = new StringBuilder("rm -rf");
        for (File directory : directories) {
          command.append(" \"" + directory.getAbsolutePath() + "\"");
        }
    
        Shell.SU.run(command.toString());
      } catch (PackageManager.NameNotFoundException wtf) {
      }
    }
    
    0 讨论(0)
  • 2020-12-09 19:38

    For more information, please see my answer to Clear Cache of All Apps in Marshmallow?

    In Android 6 (Marshmallow) there is an additional freeStorage() method that takes a volumeUuid parameter:

    public void freeStorage(long freeStorageSize, IntentSender pi)
    
    public abstract void freeStorage(String volumeUuid, long freeStorageSize,
            IntentSender pi)
    

    Obviously, the new method is showing up first in the returned list of declared methods.

    You can change the orginal code so that it looks like this top work in Android 6:

    PackageManager  pm = getPackageManager();
    // Get all methods on the PackageManager
    Method[] methods = pm.getClass().getDeclaredMethods();
    for (Method m : methods) {
        if (m.getName().equals("freeStorage")) {
            Class[] params = m.getParameterTypes();
            if (params.length == 2) {
                // Found the method I want to use
                try {
                    long desiredFreeStorage = 8 * 1024 * 1024 * 1024; // Request for 8GB of free space
                    m.invoke(pm, desiredFreeStorage , null);
                } catch (Exception e) {
                    // Method invocation failed. Could be a permission problem
                }
                break;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题