清除 OS Marshmallow 以上版本的缓存

Clearing the Cache on OS Versions above Marshmallow

我想制作一个 Android 应用程序来清除其他应用程序的缓存。对于 Android Marshmallow 以下的版本,我已经想出了如何做到这一点。

This 是我在 Android Honeycom 及更高版本中使用的:

    if (isExternalStorageWritable()) {
        final File externalDataDirectory = new File(Environment
                .getExternalStorageDirectory().getAbsolutePath(), "/Android/data");

        final String externalCachePath = externalDataDirectory.getAbsolutePath() +
                "/%s/cache";

        if (externalDataDirectory.isDirectory()) {
            final File[] files = externalDataDirectory.listFiles();

            for (File file : files) {
                if (!deleteDirectory(new File(String.format(externalCachePath,
                        file.getName())), true)) {
                    Log.e(TAG, "External storage suddenly becomes unavailable");

                    return false;
                }
            }
        } else {
            Log.e(TAG, "External data directory is not a directory!");
        }
    } else {
        Log.d(TAG, "External storage is unavailable");
    }

但我在弄清楚如何为 Android Marshmallow 及更高版本执行此操作时遇到了问题。

市场上存在的其他缓存清理器是否能够通过获得可访问性许可或任何其他方式来执行此操作?

如果应用程序是系统应用程序,它可以请求 android.permission.DELETE_CACHE_FILES 并且您可以使用反射来访问 PackageManager.deleteApplicationCacheFiles()

  // Lazily instantiated by reflection
  @Nullable private Method deleteApplicationCacheMethod;

  public ListenableFuture<Void> deleteApplicationCache(String packageName) throws Exception {
    SettableFuture<Void> futureDelete = SettableFuture.create();
    ClearCacheObserver observer = new ClearCacheObserver(packageName, deleteObserver);
    // Invoke deleteApplicationCacheFiles() by reflection
    Method deleteApplicationCacheMethod = deleteApplicationCacheMethod(packageManager);
    deleteApplicationCacheMethod.invoke(packageManager, packageName, observer);
    return futureDelete;
  }

  /** Returns an accessible version of the {@link PackageManager#deleteApplicationCacheFiles}. */
  private static Method deleteApplicationCacheMethod() throws InvocationTargetException {
    if (deleteApplicationCacheMethod == null) {
      deleteApplicationCacheMethod = packageManager
          .getClass()
          .getDeclaredMethod(
               "deleteApplicationCacheFiles", String.class, IPackageDataObserver.class);
     deleteApplicationCacheMethod.setAccessible(true);
   }
   return deleteApplicationCacheMethod;
 }

  /** Wraps a Guava Future in a IPackageDataObserver. */
  private static class ClearCacheObserver extends IPackageDataObserver.Stub {
    final String packageName;
    final SettableFuture<Void> futureDelete;

    ClearCacheObserver(String packageName, SettableFuture<Void> futureDelete) {
      this.packageName = packageName;
      this.futureDelete = futureDelete;
    }

    @Override
    public void onRemoveCompleted(String package, boolean succeeded) {
      if (!packageName.equals(package))) {
        return;
      }
      if (succeeded) {
        futureDelete.set(null);
      } else {
        futureDelete.setException(new Exception("Failed to delete cache for " + package));
      }
    }
  }

从 Android 6.0 (Marshmallow) 开始,任何普通应用程序都不允许清除其他应用程序的缓存。只有当您的应用程序是系统应用程序或由系统签名的同一证书签名时,您才能清除其他应用程序的缓存。但是有一个技巧可以帮助您。

您可以使用无障碍服务(您正确指出)来执行此操作。

据我所知,您可以显示缓存值,然后向用户询问可访问性权限,在授予权限后打开设置屏幕-->转到存储-->单击缓存按钮,然后按确定。

请记住,这只是一个 hack,可能会根据不同的 OEM 和 Android 版本产生错误。

关于如何实现,this 是探索如何使用无障碍服务的一个很好的例子。

此外,请记住,您需要获得 GOOGLE PLAY 的预先批准才能使用辅助功能,否则可能会从 Play 商店中删除该应用程序。在提供更新之前请务必获得许可,否则他们可能会暂停或终止您的应用程序。对此要非常小心。