Cómo eliminar la caché de aplicaciones para todas las aplicaciones en Android M?

¿Existe una opción para eliminar la caché de todas las aplicaciones o ciertas aplicaciones en Android M?

Parece que la mayoría de las formas no funcionan más en Android M.

Como referencia he utilizado este Código de esta discusión: 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; } } 

Combinado con este permiso

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

Este código funciona bien en dispositivos inferiores a Android 6.0. Pero en los dispositivos con Android 6.0 resulta en esta excepción

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

Hay un limpiador de código abierto en GitHub, que detuvo el desarrollo por esta razón:

Incompatibilidad parcial con Android 6.0 y versiones posteriores

A partir de Android 6.0, el permiso CLEAR_APP_CACHE parece que ya no está disponible para las aplicaciones normales y dado que este permiso es necesario para limpiar la memoria caché interna, Cache Cleaner no puede limpiar caché interno en Android 6.0 y versiones posteriores. Sin embargo, la limpieza de la caché externa sigue siendo compatible.

¿Realmente no hay forma de eliminar la caché de aplicaciones en dispositivos con Android M?

¿Cómo se maneja la aplicación de configuración de Google? No puede ser el nuevo método:

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

Porque creo que no elimina el caché de ciertas aplicaciones, pero de suficientes aplicaciones para borrar el tamaño de RAM esperado … Pero la aplicación Configuración puede borrar el caché de ciertas aplicaciones

ACTUALIZACIÓN Al igual que la respuesta exceptuada explica, parece que no hay manera de eliminar la caché de aplicación sin root en los dispositivos con Android M y superiores. Pero lo publicaré aquí si encuentro una manera …

    ¿Existe una opción para eliminar la caché de todas las aplicaciones o ciertas aplicaciones en Android M?

    Una aplicación de terceros no puede eliminar la caché de otra aplicación en Android 6.0+. El nivel de protección de Manifest.permission.CLEAR_APP_CACHE cambiado de "peligroso" a "signature | privileged" o "system | signature" en Android 6.0+. Ahora, sólo las aplicaciones firmadas con la clave del firmware pueden contener este permiso.

    ¿Realmente no hay manera de eliminar caché de aplicaciones en dispositivos con Android M?

    A menos que la aplicación esté instalada como una aplicación del sistema o tenga acceso de root, no hay forma de eliminar la caché de la aplicación en Android 6.0+.

    ¿Cómo se maneja la aplicación Configuración?

    Android es, por supuesto, de código abierto. Veamos el código. En AppStorageSettings.java líneas 172-183 encontramos:

     if (v == mClearCacheButton) { // Lazy initialization of observer if (mClearCacheObserver == null) { mClearCacheObserver = new ClearCacheObserver(); } mPm.deleteApplicationCacheFiles(mPackageName, mClearCacheObserver); } 

    Por lo tanto, la aplicación Configuración utiliza el método oculto PackageManager#deleteApplicationCacheFiles(String, IPackageDataObserver) . Puede hacerlo porque contiene el permiso de nivel de sistema "android.permission.CLEAR_APP_USER_DATA" ( un permiso que una aplicación de terceros no puede contener ).


    Caché externo

    Sin embargo, la limpieza de la caché externa sigue siendo compatible.

    Esto todavía es posible en Android 6.0 o superior. No he mirado el código fuente de la aplicación que mencionaste, pero supongo que todo lo que necesitas hacer es solicitar el permiso WRITE_EXTERNAL_STORAGE , obtener todos los paquetes instalados mediante PackageManager , obtener el directorio de la caché externa de la aplicación y eliminar el directorio.


    Acceso raíz

    Por supuesto, si tiene acceso root, puede eliminar la caché de otra aplicación. A continuación se muestra un ejemplo rápido de cómo usar el acceso root para eliminar toda la caché de aplicaciones. Puede utilizar el libsuperuser de Chainfire para ejecutar comandos en un shell raíz:

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

    Para obtener más información, consulte mi respuesta a Clear Cache of All Apps en Marshmallow?

    En Android 6 (Marshmallow) hay un método freeStorage() adicional que toma un parámetro volumeUuid :

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

    Obviamente, el nuevo método aparece primero en la lista devuelta de métodos declarados.

    Puedes cambiar el código original para que se vea como esta obra de arriba en Android 6:

     PackageManager pm = getPackageManager(); // Get all methods on the PackageManager Method[] methods = pm.getClass().getDeclaredMethods(); for (Method m : methods) { if (m.getName().equals("freeStorage")) { Class[] params = m.getParameterTypes(); if (params.length == 2) { // 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; } } } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.