Wyczyść dane aplikacji programowo

121

Chcę programowo wyczyścić dane mojej aplikacji.

Dane aplikacji mogą zawierać wszystko, na przykład bazy danych, wspólne preferencje, pliki wewnętrzne-zewnętrzne lub inne pliki utworzone w aplikacji.

Wiem, że możemy wyczyścić dane z urządzenia mobilnego poprzez:

Ustawienia-> Aplikacje-> Zarządzaj aplikacjami-> Moja_aplikacja-> Wyczyść dane

Ale muszę zrobić powyższe rzeczy za pomocą programu na Androida?

uday
źródło

Odpowiedzi:

111

W API 19 (KitKat) wprowadzono nowy interfejs API: ActivityManager.clearApplicationUserData () .

Gorąco polecam używanie go w nowych aplikacjach:

import android.os.Build.*;
if (VERSION_CODES.KITKAT <= VERSION.SDK_INT) {
    ((ActivityManager)context.getSystemService(ACTIVITY_SERVICE))
            .clearApplicationUserData(); // note: it has a return value!
} else {
    // use old hacky way, which can be removed
    // once minSdkVersion goes above 19 in a few years.
}

Jeśli nie chcesz tego hakerskiego sposobu, możesz także ukryć przycisk w interfejsie użytkownika, aby funkcja nie była dostępna na starych telefonach.

Znajomość tej metody jest obowiązkowa dla wszystkich użytkowników android:manageSpaceActivity.


Za każdym razem, gdy tego używam, robię to z pliku manageSpaceActivityktóry ma android:process=":manager". Tam ręcznie kończę wszystkie inne procesy mojej aplikacji. To pozwala mi pozostawić uruchomiony interfejs użytkownika i pozwolić użytkownikowi zdecydować, gdzie ma iść dalej.

private static void killProcessesAround(Activity activity) throws NameNotFoundException {
    ActivityManager am = (ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE);
    String myProcessPrefix = activity.getApplicationInfo().processName;
    String myProcessName = activity.getPackageManager().getActivityInfo(activity.getComponentName(), 0).processName;
    for (ActivityManager.RunningAppProcessInfo proc : am.getRunningAppProcesses()) {
        if (proc.processName.startsWith(myProcessPrefix) && !proc.processName.equals(myProcessName)) {
            android.os.Process.killProcess(proc.pid);
        }
    }
}
TWiStErRob
źródło
9
dla mnie .clearApplicationUserData (); wymusza również zamknięcie aplikacji.
gaurav414u
9
Musi zabić aplikację, w przeciwnym razie może mieć dane, które przechowuje, które zostaną z powrotem zapisane. Jedynym bezpiecznym sposobem na to jest (1) zabicie aplikacji, (2) wyczyszczenie wszystkich jej danych, (3) przy następnym uruchomieniu aplikacja rozpocznie się od nowa bez żadnych danych.
hackbod
4
Cześć @TWiStErRob Chcę zaimplementować tę metodę po kliknięciu przycisku LOGOUT w mojej aplikacji. Ale wymusza zamknięcie aplikacji. Zamiast tego chcę rozpocząć główną czynność, w której obecny jest formularz rejestracji / logowania. Jak to będzie możliwe?
pblead26
1
W przypadku wersji sprzed KitKat zobacz tę odpowiedź: stackoverflow.com/a/23470355/3256989
ultraon
2
czy po zastosowaniu tego kodu można rozpocząć jakąkolwiek inną aktywność
Amandeep Rohila
107

Po prostu umieszczam samouczek z linku ihrupin zamieszczonego tutaj w tym poście.

package com.hrupin.cleaner;

import java.io.File;

import android.app.Application;
import android.util.Log;

public class MyApplication extends Application {

    private static MyApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }

    public static MyApplication getInstance() {
        return instance;
    }

    public void clearApplicationData() {
        File cacheDirectory = getCacheDir();
        File applicationDirectory = new File(cacheDirectory.getParent());
        if (applicationDirectory.exists()) {
            String[] fileNames = applicationDirectory.list();
            for (String fileName : fileNames) {
                if (!fileName.equals("lib")) {
                    deleteFile(new File(applicationDirectory, fileName));
                }
            }
        }
    }

    public static boolean deleteFile(File file) {
        boolean deletedAll = true;
        if (file != null) {
            if (file.isDirectory()) {
                String[] children = file.list();
                for (int i = 0; i < children.length; i++) {
                    deletedAll = deleteFile(new File(file, children[i])) && deletedAll;
                }
            } else {
                deletedAll = file.delete();
            }
        }

        return deletedAll;
    }
}

Więc jeśli chcesz, aby przycisk to zrobił, musisz wywołać MyApplication.getInstance (). clearApplicationData () z poziomu onClickListener

Aktualizacja: Twoja SharedPreferencesinstancja może przechowywać Twoje dane i ponownie utworzyć plik preferencji po jego usunięciu. Więc będziesz chciał dostać swój SharedPreferencesprzedmiot i

prefs.edit().clear().commit();

Aktualizacja:

Musisz dodać android:name="your.package.MyApplication"do application tagwewnętrznego pliku AndroidManifest.xml, jeśli tego nie zrobiłeś. W przeciwnym razie MyApplication.getInstance()zwraca null, w wyniku czego NullPointerException .

MinceMan
źródło
5
Dbać ! Usuwasz wszystko w folderze aplikacji, w tym preferencje udostępniania ... nie tylko sam katalog pamięci podręcznej i jego zawartość.
Snicolas
2
Wdrożyłem to rozwiązanie. Ale moje dane aplikacji nie są czyszczone, tylko pamięć podręczna jest czyszczona. Pozostało 5 MB .. inne rozwiązanie? Proszę, pomóż mi :(
SweetWisher ツ
1
@MinceMan Proszę wspomnieć, że to musi być napisane w klasie, która rozszerza Application for lepszy efekt
creepy_driver
Bardzo sprytnie zachować lib reż.
mroźno cudowny
1
tak, usunął wszystkie pliki, ale aplikacja nie zdała sobie z tego sprawy, więc nadal mogę być plikami w katalogu aplikacji. Aplikacja przeprowadziła czyszczenie po usunięciu aplikacji z ostatniej aplikacji, następnie ją uruchom. Próbowałem odtworzyć aktywność, ale to nie zadziałało
gturedi
15

połącz kod z 2 odpowiedzi:

Oto wynikowa połączona odpowiedź oparta na źródłach

private void clearAppData() {
    try {
        // clearing app data
        if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
            ((ActivityManager)getSystemService(ACTIVITY_SERVICE)).clearApplicationUserData(); // note: it has a return value!
        } else {
            String packageName = getApplicationContext().getPackageName();
            Runtime runtime = Runtime.getRuntime();
            runtime.exec("pm clear "+packageName);
        }

    } catch (Exception e) {
        e.printStackTrace();
    } 
}
CrandellWS
źródło
Czy to zadziała na wszystkich urządzeniach z Androidem, niezależnie od wersji Androida? Dla mnie działa na wszystkich 3 posiadanych przeze mnie urządzeniach z Androidem (z Lollipop, Marshmallow i Pie)
Kathir
tak, jeśli else jest równe lub mniejsze niż kit kat ... użyj clearApplicationUserData, a powyżej używa runtime.exce ... w zasadzie polecenie powłoki ... całkiem niezawodny inny niż uprawnienia ... powinien po prostu działać ...
CrandellWS
13

Najprostszym sposobem na to jest

private void deleteAppData() {
     try {
    // clearing app data
    String packageName = getApplicationContext().getPackageName();
    Runtime runtime = Runtime.getRuntime();
    runtime.exec("pm clear "+packageName);

} catch (Exception e) {
    e.printStackTrace();
} }

Spowoduje to wyczyszczenie danych i usunięcie aplikacji z pamięci. Jest to równoważne z opcją wyczyszczenia danych w Ustawieniach -> Menedżer aplikacji -> Twoja aplikacja -> Wyczyść dane

Summved Jain
źródło
3
Nie polecałbym tego podejścia. Używanie programów wiersza poleceń (np. pm), Które mogą nie istnieć, jest ryzykowne. Nie są one częścią „umowy” Android SDK, więc to, czy istnieją na danym urządzeniu, czy też zachowują się tak samo, jak na innych urządzeniach, zależy od producentów i niestandardowych programistów ROM.
CommonsWare
2
Jako alternatywa mam jeszcze jedną opcję, tj. ((ActivityManager) context.getSystemService (ACTIVITY_SERVICE)) .clearApplicationUserData (); Ma jednak ograniczenie, że działa tylko na poziomie API> = 19 Czy możesz podać tutaj alternatywę, czy może to być inna opcja.
Summved Jain
2

Czego używam wszędzie:

 Runtime.getRuntime().exec("pm clear me.myapp");

Wykonanie powyższego fragmentu kodu zamyka aplikację i usuwa wszystkie bazy danych oraz wspólne preferencje

Pehlaj - programista aplikacji mobilnych
źródło
-1

Jeśli chcesz mniej rozwlekłych hacków:

void deleteDirectory(String path) {
  Runtime.getRuntime().exec(String.format("rm -rf %s", path));
}
Christopher Perry
źródło
1
Możesz zacytować tę ścieżkę, jeśli ma spacje i takie tam.
TWiStErRob