【问题标题】:How to delete other applications cache from our android app?如何从我们的 android 应用程序中删除其他应用程序缓存?
【发布时间】:2013-06-23 05:13:05
【问题描述】:

我正在尝试开发一个可以删除其他应用程序缓存数据的 android 应用程序,我尝试浏览所有博客,但没有一个对我有用,我可以通过以下代码清除我的应用程序缓存

File cache = getCacheDir();
            File appDir = new File(cache.getParent());
            if (appDir.exists()) 
            {
                String[] children = appDir.list();
                for (String s : children) 
                {
                    if (!s.equals("lib"))
                    {
                        deleteDir(new File(appDir, s));
                        Toast.makeText(DroidCleaner.this, "Cache Cleaned", Toast.LENGTH_LONG).show();
                        Log.i("TAG", "**************** File /data/data/APP_PACKAGE/" + s + " DELETED *******************");
                    }
                }
            }

public static boolean deleteDir(File dir) 
{
    if (dir != null && dir.isDirectory()) 
    {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++) 
        {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) 
            {
                return false;
            }
        }
    }
    return dir.delete();
}

我的清单代码

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

我在 2.2、2.3 和 4.0 上测试了代码

在看到以下链接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;
   }
}

我想清除其他应用程序的缓存,请任何人帮助我,如果我错了,请纠正我,提前谢谢。

【问题讨论】:

  • 你认为你会被允许处理其他应用程序的数据吗?
  • 不是没有root,但如果你看到Play商店中可用的Clean Master,History Eraser等应用程序,他们正在完成任务。
  • 这对我不起作用@David Wasser
  • 请解释“不工作”。您是否在 logcat 中查找任何错误或其他消息(不要过滤 logcat,否则您可能会错过重要的东西)?您是否提供了正确的权限?发布您的清单。你在什么设备上测试过这个?

标签: android caching


【解决方案1】:

API 23 不再支持此 API,即 Marshmallow。 Marshmallow 中已弃用权限。

但还有另一种方法,即请求 Accessories 的运行时权限。从 Play 商店尝试应用程序 All-in-one Toolbox。即使在棉花糖中,这个应用程序也能够清除其他应用程序的缓存。那么我们应该可以这样做。

我正在研究这个。找到解决方案后,我将更新答案。谢谢。


旧答案如下


我使用了以下代码,现在我能够在不生根的情况下清除所有应用程序的缓存,它对我来说非常有效,

private static final long CACHE_APP = Long.MAX_VALUE;
private CachePackageDataObserver mClearCacheObserver;

btnCache.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            clearCache();
        }
    });//End of btnCache Anonymous class

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);

      /*
       * 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.printStackTrace();
      }
      /*
       * End of inner try-catch block
       */
    }
    catch (NoSuchMethodException e1)
    {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }
}//End of clearCache() method

private class CachePackageDataObserver extends IPackageDataObserver.Stub 
{
    public void onRemoveCompleted(String packageName, boolean succeeded) 
    {

    }//End of onRemoveCompleted() method
}//End of CachePackageDataObserver instance inner class

并且还在您的src 文件夹中创建一个名为android.content.pm 的包,在该包中创建一个名为IPackageDataObserver.aidl 的文件并将以下代码粘贴到其中

package android.content.pm;

/**
 * API for package data change related callbacks from the Package Manager.
 * Some usage scenarios include deletion of cache directory, generate
 * statistics related to code, data, cache usage(TODO)
 * {@hide}
 */
oneway interface IPackageDataObserver {
    void onRemoveCompleted(in String packageName, boolean succeeded);
}

并确保在您的清单中使用以下代码

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

如果大家有什么问题可以联系我,谢谢。

【讨论】:

  • 您不需要所有IPackageDataObserver 的东西。只需像这样调用方法:localMethod.invoke(mPM, localLong, null).
  • @Chethan Shetty 如果我想清除特定应用程序的数据,我该怎么做?如何检查包裹
  • 我正在使用 Eclipse 编辑器,我在 src 文件夹中创建了 IPackageDataObserver.aidl 文件并粘贴代码,正如你在回答中所说的那样,现在问题是 IPackageDataObserver.Stub 在我定义一个类并扩展 IPackageDataObserver.Stub 的地方没有解决...该怎么办?
  • 伙计们,正如你所说,我在 src 中创建了一个 android.content.pm 包,并在其中创建了一个 IPackageDataObserver.aidl。但我有两个问题:第一个是 Intreface 中的单向语法总是出错,并且 IPackageDataObserver 在 clearcache 函数中无法识别。你能帮帮我吗?
  • IPackageDataObserver.Stub 在我定义一个类并扩展 IPackageDataObserver.Stub 的地方没有解决。请帮忙。正如你所说,我已经创建了包。
【解决方案2】:

缓存不仅仅是一回事。对于每个应用程序,系统数据文件夹中都有一个缓存文件夹,每个可用存储分区都有一个缓存文件夹(一个在设备的内部 sd 卡中,如果有外部 sd 卡,那么那里也有一个)

所以要清除系统数据文件夹中的缓存,请执行此操作

Method method = pmClass.getDeclaredMethod("freeStorageAndNotify", new Class[] { Long.TYPE, Class.forName("android.content.pm.IPackageDataObserver") });
method.setAccessible(true);
method.invoke(con.getPackageManager(), Long.MAX_MALUE, null);
//null is for the IPackageDataObserver object that let's you know when the process is done and it is not necessary to provide.

因为您无权访问系统文件夹以在非 root 设备中自行删除它们,所以您礼貌地要求 Android 为您执行此操作。

要清除非系统数据文件夹中的缓存,请执行此操作

for(String storageVolumePath:storageVolumePaths) {
    File androidDataFolder = new File((String) storageVolumePath + "/Android/data/");
    if (androidDataFolder.exists()) {
        File[] filesList = androidDataFolder.listFiles();
        if (filesList != null) {
            for (File file : filesList) {
                if (file.isDirectory()) {
                    file = new File(file.getAbsolutePath() + "/cache/");
                    if(file.exists()) {
                        try {
                            deleteFile(file);
                        }catch (Exception e ){}
                    }
                }
            }
        }
    }
}

多合一工具箱不会从 marshmellow 中的系统数据文件夹中清除缓存,因为没有 root 访问权限是不可能的。它只使用第二种技术并清除总缓存的一部分。要在没有 root 访问权限的 API 23 及更高版本中实现这一点,您需要成为系统应用程序,因为无法使用 Permission API 请求 android.permission.CLEAR_APP_CACHE 权限

【讨论】:

  • 如何获取storageVolumePaths
【解决方案3】:

另一种方法是将位于 \sdk\platforms\android-19\data 目录中的 layoutlib.jar 文件添加到项目的库中。您将能够解析该类和其他类,而无需手动将其添加到源代码中。

我必须补充一点,这将不会将这些类添加到您的二进制文件中。它只会让你解决分类问题。

【讨论】:

  • 考虑提供代码 sn-p 以帮助了解更多关于您的方法。
猜你喜欢
  • 2019-02-03
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 2019-01-15
  • 2011-09-28
  • 2020-03-10
  • 1970-01-01
相关资源
最近更新 更多