Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
448 views
in Technique[技术] by (71.8m points)

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

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 used this Code out of this discussion : Android: Clear Cache of All Apps?

PackageManager  pm = getPackageManager();
// Get all methods on the PackageManager
Method[] methods = pm.getClass().getDeclaredMethods();
for (Method m : methods) {
    if (m.getName().equals("freeStorage")) {
        // 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;
    }
} 

Combined with this permission

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

This Code works fine on devices lower than Android 6.0. But on devices with Android 6.0 it results in this exception

java.lang.IllegalArgumentException: Wrong number of arguments; expected 3, got 2 

There is an open source cleaner on GitHub, which stopped development with this reason:

Partial incompatibility with Android 6.0 and newer

Starting with Android 6.0, CLEAR_APP_CACHE permission seems to be no longer available to regular applications and since this permission is required for cleaning of internal cache, Cache Cleaner is not able to clean internal cache on Android 6.0 and newer. However, cleaning of external cache is still supported.

Is there really no way, to delete App Cache on devices with Android M ?

How does the Google Setting App handle it ? It can't be the new method:

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

because I think it does not delete the Cache of certain apps, but of enough apps to clear the expected ram size... But the Settings app can clear the Cache of certain apps

UPDATE Like the excepted answer explains, there seems to be no way to delete tha App Cache without root on Devices with Android M and above. But I will post it here if I find a way....

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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) {
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...