2011-12-12 28 views
5

Piszę aplikację, która może programowo wyczyścić pamięć podręczną aplikacji wszystkich aplikacji firm trzecich zainstalowanych na urządzeniu. Poniżej znajduje się fragment kodu dla Androida 2.2Jak mogę wyczyścić pamięć podręczną aplikacji dla systemu Android?

public static void trimCache(Context myAppctx) { 

    Context context = myAppctx.createPackageContext("com.thirdparty.game", 
      Context.CONTEXT_INCLUDE_CO|Context.CONTEXT_IGNORE_SECURITY); 

    File cachDir = context.getCacheDir();   
    Log.v("Trim", "dir " + cachDir.getPath()); 

    if (cachDir!= null && cachDir.isDirectory()) { 

     Log.v("Trim", "can read " + cachDir.canRead()); 
     String[] fileNames = cachDir.list(); 
     //Iterate for the fileName and delete 
    } 
} 

Mój manifest ma następujące uprawnienia:

android.permission.CLEAR_APP_CACHE
android.permission.DELETE_CACHE_FILES

Teraz problem jest, że nazwa katalogu pamięci podręcznej jest drukowana, ale lista plików cachDir.list() zawsze zwraca wartość null. Nie mogę usunąć katalogu pamięci podręcznej, ponieważ lista plików jest zawsze pusta.

Czy istnieje inny sposób wyczyszczenia pamięci podręcznej aplikacji?

+0

Nie potrzebujesz do tego urządzenia zrootowanego? –

Odpowiedz

6

"android.permission.CLEAR_APP_CACHE" android.permission.DELETE_CACHE_FILES”

Zwykłe aplikacje SDK nie może posiadać pozwolenie DELETE_CACHE_FILES. O ile można trzymać CLEAR_APP_CACHE, nie ma nic w Android SDK, który pozwala aby wyczyścić pamięć podręczną aplikacji.

Czy jest jakiś inny sposób, aby wyczyścić pamięć podręczną aplikacji?

Możesz wyczyścić własną pamięć podręczną, usuwając pliki z tej pamięci podręcznej.

+0

biorąc pod uwagę poprawne uprawnienia, można usunąć foldery pamięci podręcznej innych aplikacji w pamięci zewnętrznej (tylko). to nie to samo, ale wiele aplikacji używa tych folderów jako głównego miejsca do umieszczania plików tymczasowych. –

+0

Chcę wiedzieć, kiedy kiedykolwiek użytkownik może kliknąć wyczyść pamięć podręczną, aby uzyskać powiadomienie lub coś innego, jak uzyskać? –

+0

@KOUSIKdaniel: * Myślę * że twój proces zostanie zakończony przed wyczyszczeniem pamięci podręcznej, ale nie jestem tego pewien. Nie znam żadnego innego powiadomienia, które otrzymasz. – CommonsWare

2

poate iti scalić Asta

static int clearCacheFolder(final File dir, final int numDays) { 

     int deletedFiles = 0; 
     if (dir!= null && dir.isDirectory()) { 
      try { 
       for (File child:dir.listFiles()) { 

        //first delete subdirectories recursively 
        if (child.isDirectory()) { 
         deletedFiles += clearCacheFolder(child, numDays); 
        } 

        //then delete the files and subdirectories in this dir 
        //only empty directories can be deleted, so subdirs have been done first 
        if (child.lastModified() < new Date().getTime() - numDays * DateUtils.DAY_IN_MILLIS) { 
         if (child.delete()) { 
          deletedFiles++; 
         } 
        } 
       } 
      } 
      catch(Exception e) { 
       Log.e("ATTENTION!", String.format("Failed to clean the cache, error %s", e.getMessage())); 
      } 
     } 
     return deletedFiles; 
    } 

    public static void clearCache(final Context context, final int numDays) { 
     Log.i("ADVL", String.format("Starting cache prune, deleting files older than %d days", numDays)); 
     int numDeletedFiles = clearCacheFolder(context.getCacheDir(), numDays); 
     Log.i("ADVL", String.format("Cache pruning completed, %d files deleted", numDeletedFiles)); 
    } 
+1

To zadziałało. Wolę: 'long now = new Date(). GetTime();' przed pętlą zamiast deklarowania nowej instancji 'now' dla każdego pliku. –

0

Nie jestem pewien, jak to jest odpowiednie pod względem konwencji, ale działa to tak daleko dla mnie w globalnej klasy Application:

File[] files = cacheDir.listFiles(); 
    for (File file : files){ 
     file.delete(); 
    } 

oczywiście, to nie rozwiązuje zagnieżdżone katalogi, które może być wykonane przy użyciu funkcji rekurencyjnej tak (nie przetestowane z podkatalogów):

deleteFiles(cacheDir); 

private void deleteFiles(File dir){ 
    if (dir != null){ 
     if (dir.listFiles() != null && dir.listFiles().length > 0){ 
      // RECURSIVELY DELETE FILES IN DIRECTORY 
      for (File file : dir.listFiles()){ 
       deleteFiles(file); 
      } 
     } else { 
      // JUST DELETE FILE 
      dir.delete(); 
     } 
    } 
} 

nie używałem File.isDirectory bo to było niewiarygodne w moich testów.

Powiązane problemy