How to delete other applications cache from our android app?

Solution 1:

This API is no more supported in API 23, that is Marshmallow. Permission is deprecated in Marshmallow.

But there is another way by asking run time permission for Accessories. Try app All-in-one Toolbox from play store. This app is able to clear other apps cache even in Marshmallow. Then it should be possible for us to do so.

I am researching on this. Once I found the solution, I will update the answer. Thanks.


OLD ANSWER IS AS FOLLOWS


I used the following code and now I'm able to clear all application's cache without rooting, it's working perfectly for me,

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

And also create a pacakge in your src folder with the name android.content.pm inside that package create a file in the name IPackageDataObserver.aidl and paste the following code to it

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

and in your manifest make sure you used the following code

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

If you guys find any problem feel free to contact me, Thanks.

Solution 2:

Cache is not just one thing. For each app there is a cache folder in the system data folders and one cache folder for every storage partition available (one in device's internal sd card and if there is an external sd card then there is one there too)

So to clear the cache in the system data folders you do this

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.

Because you don't have access to the system folders to delete them by your self in a non rooted device so you politely ask Android to do it for you.

To clear the cache in the non-system data folders you do this

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

All in one toolbox DOES NOT clear cache from the system data folders in marshmellow because it is not possible without root access. It only uses the second technique and clears part of the total cache. To achieve that in API 23 and above without root access you need to be a system app because there is no way to request the android.permission.CLEAR_APP_CACHE permission using the Permission API