10

I'm trying to develop an android app that could erase others application cache data, I tried to browse through all blogs but none of them worked for me, I can able to clear my application's cache by the following code

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

My manifest code

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

I tested the code on 2.2, 2.3 and 4.0

and after seeing the post in the following link Android: Clear Cache of All Apps?

I changed my code to

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

I want to clear other application's cache, can any body please help me, please correct me if I'm wrong, Thanks in advance.

Community
  • 1
  • 1
Chethan Shetty
  • 1,972
  • 4
  • 25
  • 45
  • Do you think you will be allowed to handle other application's data? – Naresh Jun 26 '13 at 07:34
  • Not with out root, but if you see Clean Master, History Eraser etc applications which are available in play store, they are achieving the task. – Chethan Shetty Jun 26 '13 at 07:37
  • See my answer to http://stackoverflow.com/questions/14507092/android-clear-cache-of-all-apps – David Wasser Jun 26 '13 at 09:00
  • It's not working for me @David Wasser – Chethan Shetty Jun 26 '13 at 09:20
  • Please explain "not working". Did you look in logcat for any errors or other messages (don't filter logcat or you might miss something important)? Have you provided the correct permissions? Post your manifest. What devices have you tested this on? – David Wasser Jun 26 '13 at 09:29
  • @DavidWasser the I used the code you posted, other app's cache are not clearing as the way they are meant to be. App's cache still remains same. Also I provided the permission. – Chethan Shetty Jun 26 '13 at 09:31
  • Post your code and your manifest. Also please indicate what device(s) you have tested this on? – David Wasser Jun 26 '13 at 09:52
  • Did you use the code in my answer to http://stackoverflow.com/questions/14507092/android-clear-cache-of-all-apps ? That code calls the `freeStorage()` method on the `PackageManager` using reflection. If you did use that code, please paste your implementation in the question. Perhaps you just implemented it incorrectly. – David Wasser Jun 26 '13 at 10:13
  • Please add a log entry in the `catch` clause (like `Log.e("MyApp", "Caught: ", e)`) and also a log entry directly after the call to `m.invoke()` (like `Log.v("MyApp", "called invoke()")` – David Wasser Jun 26 '13 at 11:24
  • @DavidWasser I was able to find solution to the approach using `freeStorageAndNotify()`method, Thanks for your support and time. – Chethan Shetty Jun 27 '13 at 05:31
  • I'm glad you were able to solve the problem. However, I'd really like to know why my method did not work. Can you add the logs as I've requested and tell me if you are getting any exceptions, or if it cannot find the `freeStorage()` method? What device(s) are you testing on? – David Wasser Jun 27 '13 at 14:31

3 Answers3

15

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.

Chethan Shetty
  • 1,972
  • 4
  • 25
  • 45
  • You don't need all the `IPackageDataObserver` stuff. Just call the method like this: `localMethod.invoke(mPM, localLong, null)`. – David Wasser Jun 27 '13 at 14:30
  • @Chethan Shetty if I want to clear data of specific app how can i do this?how can i check for package – yuva ツ Mar 12 '14 at 18:22
  • i am using eclipse editor and i created IPackageDataObserver.aidl file in src folder and paste code as you say in answer now problem is that IPackageDataObserver.Stub not resolved where i define a class and extend IPackageDataObserver.Stub... what to do? – Hardik Mar 31 '14 at 10:16
  • @Hardik, Please create the `IPackageDataObserver.aidl`, inside your `src` folder create the package named `android.content.pm` – Chethan Shetty Apr 04 '14 at 19:47
  • @Hardik Thanks, Have a great coding. – Chethan Shetty Apr 05 '14 at 05:10
  • please tell me what is "IPackageDataObserver" my code always get error due to this...how to resolve this. – neeraj kirola Jun 13 '14 at 13:04
  • @Neeraj, Please create the IPackageDataObserver.aidl, inside your src folder create the package named android.content.pm `IPackageDataObserver.aidl` is a `Android Interface Definition Language` – Chethan Shetty Jun 14 '14 at 19:55
  • @Chethan Shetty ..thanks it worked...and thanks for your quick reply – neeraj kirola Jun 16 '14 at 05:08
  • @Chethan Shetty ,one more thing..is it possible to clear cache data of particular application. – neeraj kirola Jun 16 '14 at 05:09
  • @neerajkirola yes it is possible, and use the same source code and put some conditions using for loop and if conditions, I don't think its complicated to post as answer. Thanks. – Chethan Shetty Jun 17 '14 at 07:52
  • @ChethanShetty can u pls help me how can i delete cache of particular package ?? – Erum Nov 27 '14 at 05:32
  • @neerajkirola have u successfully removed cache of particular package ? can u pls tell how have done ? – Erum Nov 27 '14 at 05:32
  • @ChethanShetty from where i will find class CachePackageDataObserver.java – Erum Feb 12 '15 at 11:21
  • This code is not working for me. Can you tell some other solution for me.? – Arunraj Jeyaraj Jun 03 '15 at 10:36
  • This code is working perfectly in Kitkat and lollipop versions. But in my jellybean tablet its not clearing all applications cache. Can you give me some solution for this jellybean version? – Arunraj Jeyaraj Jun 24 '15 at 05:46
  • @All Cache clearing is possible with the above code on Marshmallow and up devices because of permission is deprecated. – Chethan Shetty Apr 22 '16 at 09:25
  • This code successfully cleared up to Lollipop but when this code execute in Marshamallow, then it is not clear all data. Why it is do?????????????? @ChethanShetty –  Apr 26 '16 at 11:19
  • @Omr this API is no more supported in API 23, that is Marshmallow. Permission is deprecated in Marshmallow. – Chethan Shetty May 05 '16 at 11:21
  • Getting java.lang.reflect.InvocationTargetException. – Vishal Chaudhari Jan 09 '17 at 13:32
  • Have you used AIDL class as described above? – Chethan Shetty Jan 29 '17 at 05:16
  • 1
    Guys as you said I create a android.content.pm package in src and also a IPackageDataObserver.aidl in it. But i have 2 problems: the first one is that oneway syntax in Intreface always get error and the IPackageDataObserver did not recognize in clearcache function. can you help me? – Reza Tanzifi Mar 17 '17 at 09:05
  • @ChethanShetty I am using Android Studio 2.1.1 and trying to use your code but getting problem Cannot resolve symbol 'IPackageDataObserver'. Please help me....... – Mandeep Yadav Apr 12 '17 at 10:37
  • See my answer below regarding Android tool box app. – Anonymous Aug 17 '17 at 10:47
  • How should I get total Cache consumed in each app.? – Ajay Jayendran Oct 24 '17 at 18:09
  • 1
    IPackageDataObserver.Stub not resolved where i define a class and extend IPackageDataObserver.Stub. Please help. I've created the package as you told. – Kaushal28 Dec 30 '17 at 10:43
  • I am getting java.lang.NoSuchMethodException – Jyoti JK Mar 05 '18 at 12:00
  • @Rahulrr2602 I am currently not working on this. I hope the Android community can help us with the problem. This problem is very tricky. If you find solution, please share. – Chethan Shetty Apr 25 '18 at 04:11
  • @here, any one find a solution for Android Oreo? Its not working for me. I am using freeStorageAndNotify in which I get the call back to onRemoveCompleted(String packageName, boolean succeeded) but the succeeded is false. Any leads? Thanks in advance. – Vinayak Bevinakatti Sep 04 '18 at 18:18
  • Hi, I followed the above code. It's not working It gives a security exception. Did anyone get any perfect solution? – Bhaven Shah Dec 15 '21 at 07:40
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

Anonymous
  • 4,470
  • 3
  • 36
  • 67
0

Another alternative is to add the layoutlib.jar file located in the \sdk\platforms\android-19\data directory, to the library of your project. You'll be able to resolve that and other classes without having to manually add it to the source code.

I must add that this will those classes will not be added to your binary. It will only let you resolve the clases.

Storo
  • 988
  • 1
  • 7
  • 31