So programmgesteuertes Löschen von Anwendungsdaten

152

Ich entwickle automatisierte Tests für eine Android-Anwendung (mit Robotium). Um die Konsistenz und Zuverlässigkeit der Tests zu gewährleisten, möchte ich jeden Test mit einem sauberen Zustand (der zu testenden Anwendung) beginnen. Dazu muss ich die App-Daten löschen. Dies kann manuell unter Einstellungen / Anwendungen / Anwendungen verwalten / [Meine App] / Daten löschen erfolgen

Was ist der empfohlene Weg, um dies programmgesteuert durchzuführen?

user597603
quelle
Ist es möglich, das ADB-Tool zu verwenden, um die Daten zwischen den Starts der Anwendung zu löschen? adb -w
smith324
Leider ist diese Option nicht verfügbar (die ADB-Hilfe ist veraltet).
user597603
Das wäre so toll. Beim Debuggen von Datenbankproblemen muss ich so oft zur Option Daten löschen navigieren, dass mein Datenfluss wirklich unterbrochen wird.
Jason Prado
Die Vorgehensweise über Android Studio wird hier erläutert : stackoverflow.com/q/31713579/905686 .
user905686
Tun Sie dies insbesondere: stackoverflow.com/a/57461180/94557
Matt Wolfe

Antworten:

171

Sie können das Paket-Manager-Tool verwenden, um Daten für installierte Apps zu löschen (ähnlich wie durch Drücken der Schaltfläche "Daten löschen" in den App-Einstellungen auf Ihrem Gerät). Mit adb können Sie also Folgendes tun:

adb shell pm clear my.wonderful.app.package
Edovino
quelle
1
Unter Android 2.1-Update1 ergibt sich dies leider Error: unknown command 'clear'.
Paul Lammertsma
@ Palani: funktioniert für mich für jede Version über 2.1-r1 (andoid-7). Irgendwelche Fehlermeldungen?
Edovino
1
Der obige Befehl stellt eine Verbindung zur Android-Shell her und führt "pm clear my.wonderful.app.package" in Android aus. In meinem Gerät hat der Befehl "pm" keine Option "clear". Es hat nichts mit SDK zu tun. Dies hängt von der Gerätefirmware ab.
Palani
Ich suche nach klaren Daten von Browser (defaut) und Chrome Browser Apps in Android-Gerät programmatisch von meiner Android App. Bitte helfen Sie dafür ..
Brijesh Patel
Funktioniert nicht auf jedem Gerät, aber es ist wunderbar für die Geräte, auf denen es funktioniert
Cory Trese
34

Nach der Antwort von @ edovino können Sie alle Einstellungen einer Anwendung programmgesteuert löschen

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

Warnung : Die Anwendung wird zwangsweise geschlossen.

Sebastiano
quelle
5
Wenn danach Testcode ausgeführt wird, schlägt dieser fehl.
Rajath
Erfordert die Ausführung dieses Vorgangs, dass Berechtigungen im Manifest deklariert werden?
Rubenjohn
1
Nein, es ist keine besondere Erlaubnis erforderlich.
Sebastiano
Thx, du hast mein Leben gerettet!
Sidd
1
Wenn ich das Schließen der App dann nicht erzwingen möchte?
NJ
22

Damit können Sie SharedPreferences-App-Daten löschen

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

und zum Löschen der App- Datenbank ist diese Antwort korrekt -> Löschen der Anwendungsdatenbank

guleryuz
quelle
14

Ab API-Version 19 kann ActivityManager.clearApplicationUserData () aufgerufen werden.

((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();
Joakim
quelle
13
Nur zu Ihrer Information, wenn Sie dies aufrufen, wird Ihre App beendet.
Zach Rattner
8

Überprüfen Sie diesen Code auf:

@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 Krishna
quelle
6

Wenn Sie nur ein paar gemeinsame Einstellungen löschen müssen, ist diese Lösung viel besser .

@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
quelle
Muss dafür nicht der "Instrumentierungsmodus" aktiviert sein? Was ist dieser Modus überhaupt?
ADTC
Ja, dies erfordert eine „instrumentiert“ Anwendung, dh Ihre Testläufe zusammen mit Ihren Anwendungscode auf einem echten Gerät ausgeführt , was bedeutet , dass Sie alle Ihre Anwendung des Staates zugreifen können und es für Testzwecke auf der Laufzeit ändern.
Thomas Keller
was soll in (...) sein?
NickUnuchek
@NickUnuchek Der Name der Voreinstellungsdatei.
Thomas Keller
3

Mithilfe des Kontexts können wir app-spezifische Dateien wie Einstellungen und Datenbankdateien löschen. Ich habe den folgenden Code für UI-Tests mit Espresso verwendet.

    @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
quelle
3

Der einfachste Weg, dies zu tun, ist

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

Dadurch werden die Daten gelöscht und Ihre App aus dem Speicher entfernt. Dies entspricht der Option zum Löschen von Daten unter Einstellungen -> Anwendungsmanager -> Ihre App -> Daten löschen.

Dadurch werden die Daten vollständig entfernt und das Schließen der App erzwungen

Summierter Jain
quelle
Bitte fügen Sie nicht dieselbe Antwort auf mehrere Fragen hinzu. Beantworten Sie die beste Frage und markieren Sie den Rest als Duplikate. Siehe Ist es akzeptabel, mehrere Fragen doppelt zu beantworten?
FelixSFD
1
Wie können wir dies erreichen, ohne die App zu schließen
Omkar Ghurye
2

Diese Lösung hat mir wirklich geholfen:

Mit den folgenden zwei Methoden können wir Daten programmgesteuert löschen

    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
quelle
2

Wenn die Android-Version über Kitkat liegt, können Sie diese auch verwenden

public void onClick (Ansicht anzeigen) {

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

Was ist der empfohlene Weg, um dies programmgesteuert durchzuführen?

Die einzig mögliche Option besteht darin, den ADB-Befehl adb shell pm clear packagevor dem Test auszuführen . Das größte Problem ist, dass es Kopfschmerzen gibt, die Testausführung und Shell-Befehle kombinieren.

Wir (bei Mediafe) haben jedoch eine Lösung entwickelt, die auf normalen Geräten ohne Rootberechtigung für Sie funktioniert. Sie müssen lediglich eine Anmerkung hinzufügen. Der Rest wird durch Ausführen eines einfachen Bash-Skripts erledigt .

Fügen Sie einfach @ClearDataAnmerkung vor jedem Ihrer Tests und tada 🎉, ADB klarer Befehl wird vor der Testdurchführung ausgeführt werden.

Dies ist ein Beispiel für einen solchen Test:

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

Die Idee ist wie folgt

  1. Lesen Sie alle Tests mit adb shell am instrument -e log true
  2. Erstellen Sie einen Ausführungsplan, indem Sie die Ausgabe von (1) analysieren.
  3. Führen Sie den Ausführungsplan zeilenweise aus

Mit der gleichen Idee sind dies alles Optionen, die Sie leicht unterstützen können:

  • Daten löschen
  • Benachrichtigungsleiste löschen
  • Parametrieren
  • Nach Tags filtern und ausführen

Verwenden Sie nur Anmerkungen. So was:

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

Bonus! 🎁 Für jeden fehlgeschlagenen Test:

  • Sammle Logcat + Stacktrace
  • Video aufnehmen (mp4)
  • Dump DB (SQLite)
  • Gemeinsame Standardeinstellungen sichern (xml)
  • Sammle Dumpsys-Dateien wie: Batterie, Netstats und andere.

Im Allgemeinen ist es einfach, weitere Optionen hinzuzufügen, da die Tests einzeln über das Bash-Skript und nicht über die Gradle-Aufgabe ausgeführt werden.

📗 Der vollständige Blog-Beitrag : https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8

📘 Der Quellcode mit Beispielen : https://github.com/medisafe/run-android-tests

Hoffe das beantwortet 6 Jahre Frage;)

sromku
quelle