Jak programowo wyczyścić dane aplikacji

152

Zajmuję się tworzeniem testów automatycznych dla aplikacji na Androida (z wykorzystaniem Robotium). W celu zapewnienia spójności i rzetelności testów każdy test chciałbym rozpoczynać od stanu czystego (testowanej aplikacji). Aby to zrobić, muszę wyczyścić dane aplikacji. Można to zrobić ręcznie w Ustawienia / Aplikacje / Zarządzaj aplikacjami / [Moja aplikacja] / Wyczyść dane

Jaki jest zalecany sposób wykonania tego programowo?

user597603
źródło
Czy możliwe jest użycie narzędzia adb do czyszczenia danych między uruchomieniami aplikacji? adb -w
smith324
Niestety ta opcja nie jest dostępna (pomoc adb jest nieaktualna).
user597603
Byłoby wspaniale. Podczas debugowania problemów z bazą danych muszę tak bardzo nawigować do opcji Wyczyść dane, a to naprawdę przerywa mój przepływ.
Jason Prado
Jak to zrobić za pomocą Android Studio jest omówione tutaj: stackoverflow.com/q/31713579/905686 .
user905686
W szczególności zrób to: stackoverflow.com/a/57461180/94557
Matt Wolfe,

Odpowiedzi:

171

Możesz użyć narzędzia menedżera pakietów, aby wyczyścić dane z zainstalowanych aplikacji (podobnie jak naciśnięcie przycisku „wyczyść dane” w ustawieniach aplikacji na urządzeniu). Więc używając adb możesz zrobić:

adb shell pm clear my.wonderful.app.package
edovino
źródło
1
Na Androidzie 2.1-update1 niestety daje Error: unknown command 'clear'.
Paul Lammertsma
@Palani: działa dla mnie dla każdej wersji powyżej 2.1-r1 (andoid-7). jakieś komunikaty o błędach?
edovino
1
Powyższe polecenie łączy się z powłoką Androida i wykonuje „pm clear my.wonderful.app.package” w systemie Android. W moim urządzeniu polecenie „pm” nie ma opcji „wyczyść”. Nie ma nic związanego z sdk. To zależy od oprogramowania układowego urządzenia.
Palani
Szukam jasnych danych przeglądarki (domyślnie) i aplikacji Chrome na urządzeniu z Androidem programowo z mojej aplikacji na Androida. Proszę o pomoc ..
Brijesh Patel
Nie działa na każdym urządzeniu, ale jest cudowny dla urządzeń, na których działa
Cory Trese
34

Zgodnie z odpowiedzią @ edovino, sposobem na programowe wyczyszczenie wszystkich preferencji aplikacji byłby

private void clearPreferences() {
    try {
        // clearing app data
        Runtime runtime = Runtime.getRuntime();
        runtime.exec("pm clear YOUR_APP_PACKAGE_GOES HERE");

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

Ostrzeżenie : aplikacja wymusi zamknięcie.

Sebastiano
źródło
5
Jeśli po tym działa jakikolwiek kod testowy, nie powiedzie się.
rajath
Czy wykonanie tego wymaga zadeklarowania uprawnień w manifeście?
reubenjohn
1
Nie, nie wymaga specjalnego pozwolenia.
Sebastiano,
Dzięki, uratowałeś mi życie!
Sidd,
1
jeśli nie chcę wymuszać zamknięcia aplikacji?
NJ
22

możesz wyczyścić dane aplikacji SharedPreferences

Editor editor = 
context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();

a jeśli chodzi o czyszczenie bazy danych aplikacji, ta odpowiedź jest poprawna -> Baza danych Clearing Application

guleryuz
źródło
14

Od wersji API 19 można wywołać ActivityManager.clearApplicationUserData ().

((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();
Joakim
źródło
13
Po prostu do Twojej wiadomości, wywołanie tego spowoduje zamknięcie Twojej aplikacji.
Zach Rattner
8

Sprawdź ten kod, aby:

@Override
protected void onDestroy() {
// closing Entire Application
    android.os.Process.killProcess(android.os.Process.myPid());
    Editor editor = getSharedPreferences("clear_cache", Context.MODE_PRIVATE).edit();
    editor.clear();
    editor.commit();
    trimCache(this);
    super.onDestroy();
}


public static void trimCache(Context context) {
    try {
        File dir = context.getCacheDir();
        if (dir != null && dir.isDirectory()) {
            deleteDir(dir);

        }
    } catch (Exception e) {
        // TODO: handle exception
    }
}


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

    // <uses-permission
    // android:name="android.permission.CLEAR_APP_CACHE"></uses-permission>
    // The directory is now empty so delete it

    return dir.delete();
}
Hare-Kryszna
źródło
6

Jeśli masz tylko kilka wspólnych preferencji do wyczyszczenia, to rozwiązanie jest znacznie przyjemniejsze .

@Override
protected void setUp() throws Exception {
    super.setUp();
    Instrumentation instrumentation = getInstrumentation();
    SharedPreferences preferences = instrumentation.getTargetContext().getSharedPreferences(...), Context.MODE_PRIVATE);
    preferences.edit().clear().commit();
    solo = new Solo(instrumentation, getActivity());
}
Thomas Keller
źródło
Czy to nie wymaga włączenia „trybu oprzyrządowania” ? Czym właściwie jest ten tryb?
ADTC,
Tak, wymaga to „oprzyrządowanej” aplikacji, tj. Test jest uruchamiany razem z kodem aplikacji na rzeczywistym urządzeniu w trakcie , co oznacza, że ​​można uzyskać dostęp do całego stanu aplikacji i zmieniać go w czasie wykonywania w celach testowych.
Thomas Keller
co powinno być w (...)?
NickUnuchek
@NickUnuchek Nazwa pliku preferencji.
Thomas Keller
3

Korzystając z kontekstu , możemy wyczyścić pliki specyficzne dla aplikacji, takie jak preferencje, plik bazy danych. Użyłem poniższego kodu do testowania interfejsu użytkownika za pomocą Espresso.

    @Rule
    public ActivityTestRule<HomeActivity> mActivityRule = new ActivityTestRule<>(
            HomeActivity.class);

    public static void clearAppInfo() {
        Activity mActivity = testRule.getActivity();
        SharedPreferences prefs =
                PreferenceManager.getDefaultSharedPreferences(mActivity);
        prefs.edit().clear().commit();
        mActivity.deleteDatabase("app_db_name.db");
    }
Ronak Poriya
źródło
3

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.

Spowoduje to całkowite usunięcie danych, a także wymusi zamknięcie aplikacji

Summved Jain
źródło
Nie dodawaj tej samej odpowiedzi do wielu pytań. Odpowiedz na najlepszą, a pozostałe oznacz jako duplikaty. Zobacz Czy można dodać zduplikowaną odpowiedź na kilka pytań?
FelixSFD
1
Jak możemy to osiągnąć bez zamykania aplikacji
Omkar Ghurye
2

To rozwiązanie naprawdę mi pomogło:

Korzystając z poniższych dwóch metod, możemy wyczyścić dane programowo

    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;
}
Priyanka SN
źródło
2

jeśli wersja Androida jest wyższa niż KitKat, możesz jej również użyć

public void onClick (Widok widoku) {

    Context context = getApplicationContext(); // add this line
    if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
        ((ActivityManager) context.getSystemService(ACTIVITY_SERVICE))
            .clearApplicationUserData();
        return;
    }
Tushar Saha
źródło
0

Jaki jest zalecany sposób wykonania tego programowo?

Jedyną możliwą opcją jest uruchomienie polecenia ADB adb shell pm clear packageprzed testem. Największym problemem jest to, że połączenie wykonywania testów i poleceń powłoki jest rodzajem bólu głowy.

Jednak my (w Mediafe) przyszliśmy z rozwiązaniem, które może działać na zwykłym, nierootowanym urządzeniu. Wszystko, co musisz zrobić, to dodać adnotację. Cała reszta jest wykonywana przez uruchomienie prostego skryptu bash .

Po prostu dodaj @ClearDataadnotację przed DOWOLNYM z testów i tada 🎉, polecenie czyszczenia ADB zostanie wykonane przed wykonaniem testu.

Oto przykład takiego testu:

@Test
@ClearData
public void someTest() {
    // your test
}

Pomysł jest następujący

  1. Przeczytaj wszystkie testy za pomocą adb shell am instrument -e log true
  2. Utwórz plan wykonania, analizując dane wyjściowe z (1)
  3. Uruchom plan wykonania wiersz po wierszu

Korzystając z tego samego pomysłu, są to wszystkie opcje, które możesz łatwo wesprzeć:

  • Wyczyść dane
  • Wyczyść pasek powiadomień
  • Parametryzuj
  • Filtruj i uruchamiaj według tagów

Używaj tylko adnotacji. Lubię to:

@Test
@ClearData
@Tags(tags = {"sanity", "medium"})
@Parameterized.Repeat(count = 3)
public void myTest() throws Exception {
    String param = params[index];
    // ...
}

Premia! 🎁 Dla każdego niezaliczonego testu:

  • Zbierz Logcat + stacktrace
  • Nagraj wideo (mp4)
  • Zrzut bazy danych (sqlite)
  • Zrzuć domyślne wspólne preferencje (xml)
  • Zbieraj pliki zrzutów, takie jak: bateria, netstats i inne.

Ogólnie rzecz biorąc, łatwo jest dodać więcej opcji, ponieważ testy są wykonywane jeden po drugim ze skryptu bash, a nie z zadania gradle.

📗 Pełny post na blogu : https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8

📘 Kod źródłowy z przykładami : https://github.com/medisafe/run-android-tests

Mam nadzieję, że to odpowiada 6 lat na pytanie;)

sromku
źródło