Comment effacer par programmation les données d'application

152

Je développe des tests automatisés pour une application Android (utilisant Robotium). Afin d'assurer la cohérence et la fiabilité des tests, je souhaite démarrer chaque test à l'état propre (de l'application sous test). Pour ce faire, je dois effacer les données de l'application. Cela peut être fait manuellement dans Paramètres / Applications / Gérer les applications / [Mon application] / Effacer les données

Quelle est la méthode recommandée pour y parvenir par programme?

user597603
la source
Est-il possible d'utiliser l'outil adb pour effacer les données entre les lancements d'applications? adb -w
smith324
Malheureusement, cette option n'est pas disponible (l'aide adb est obsolète).
user597603
Ce serait tellement génial. Lors du débogage des problèmes de base de données, je dois tellement accéder à l'option Effacer les données et cela brise vraiment mon flux.
Jason Prado
Comment le faire via Android Studio est expliqué ici: stackoverflow.com/q/31713579/905686 .
user905686
Plus précisément, faites ceci: stackoverflow.com/a/57461180/94557
Matt Wolfe

Réponses:

171

Vous pouvez utiliser l'outil de gestion de packages pour effacer les données des applications installées (comme en appuyant sur le bouton `` Effacer les données '' dans les paramètres de l'application sur votre appareil). Donc, en utilisant adb, vous pouvez faire:

adb shell pm clear my.wonderful.app.package
Edovino
la source
1
Sur Android 2.1-update1, cela cède malheureusement Error: unknown command 'clear'.
Paul Lammertsma
@Palani: fonctionne pour moi pour toute version supérieure à 2.1-r1 (andoid-7). des messages d'erreur?
edovino
1
La commande ci-dessus se connecte au shell Android et exécute "pm clear my.wonderful.app.package" dans Android. Dans mon appareil, la commande "pm" n'a pas d'option "clear". Ce n'est rien lié à sdk. Cela dépend du micrologiciel de l'appareil.
Palani
Je recherche des données claires sur les applications de navigateur (par défaut) et de navigateur Chrome dans la programmation des appareils Android à partir de mon application Android.Veuillez aider pour cela ..
Brijesh Patel
Ne fonctionne pas sur tous les appareils, mais c'est merveilleux pour les appareils sur lesquels il fonctionne
Cory Trese
34

Suite à la réponse de @ edovino, le moyen d'effacer toutes les préférences d'une application par programme serait

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

Attention : l'application va forcer la fermeture.

Sebastiano
la source
5
Si vous avez un code de test en cours d'exécution après cela, il échoue.
rajath
L'exécution de cette opération nécessite-t-elle la déclaration des autorisations dans le manifeste?
reubenjohn
1
Non, cela ne nécessite aucune autorisation spéciale.
Sebastiano
Thx, tu m'as sauvé la vie!
Sidd
1
si je ne veux pas forcer la fermeture de l'application, alors?
NJ
22

vous pouvez effacer les données d'application SharedPreferences avec ce

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

et pour effacer la base de données de l'application, cette réponse est correcte -> Effacer la base de données de l'application

guleryuz
la source
14

À partir de la version 19 de l'API, il est possible d'appeler ActivityManager.clearApplicationUserData ().

((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();
Joakim
la source
13
Juste pour info, appeler cela mettra fin à votre application.
Zach Rattner
8

Vérifiez ce code pour:

@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
la source
6

Si vous n'avez que quelques préférences partagées à effacer, cette solution est bien plus agréable .

@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
la source
Cela ne nécessite-t-il pas l' activation du "mode instrumentation" ? Quel est ce mode de toute façon?
ADTC
Oui, cela nécessite une application «instrumentée», c'est-à-dire que votre test s'exécute avec le code de votre application sur un appareil réel en cours , ce qui signifie que vous pouvez accéder à tout l'état de votre application et le modifier à l'exécution à des fins de test.
Thomas Keller
que devrait contenir (...)?
NickUnuchek
@NickUnuchek Le nom du fichier de préférences.
Thomas Keller
3

En utilisant le contexte , nous pouvons effacer les fichiers spécifiques à l'application comme les préférences, le fichier de base de données. J'ai utilisé le code ci-dessous pour les tests d'interface utilisateur avec 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
la source
3

La manière la plus simple de procéder est

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

Cela effacera les données et supprimera votre application de la mémoire. Cela équivaut à l'option d'effacement des données sous Paramètres -> Gestionnaire d'applications -> Votre application -> Effacer les données.

Cela supprimera complètement les données et forcera la fermeture de l'application

Jain sommé
la source
Veuillez ne pas ajouter la même réponse à plusieurs questions. Répondez à la meilleure et marquez le reste comme des doublons. Voir Est-il acceptable d'ajouter une réponse en double à plusieurs questions?
FelixSFD
1
Comment pouvons-nous y parvenir sans fermeture de l'application
Omkar Ghurye
2

Cette solution m'a vraiment aidé:

En utilisant les deux méthodes ci-dessous, nous pouvons effacer les données par programme

    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
la source
2

si la version Android est supérieure à kitkat, vous pouvez également l'utiliser

public void onClick (vue vue) {

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

Quelle est la méthode recommandée pour y parvenir par programme?

La seule option possible est d'exécuter la commande ADB adb shell pm clear packageavant le test. Le plus gros problème est que c'est une sorte de casse-tête combinant l'exécution de tests et les commandes shell.

Cependant, nous (chez Mediafe) avons proposé une solution qui peut fonctionner pour vous sur un appareil non enraciné régulier. Tout ce que vous avez à faire est d'ajouter une annotation. Tout le reste est fait en exécutant un simple script bash .

Ajoutez simplement une @ClearDataannotation avant TOUT de vos tests et tada 🎉, la commande ADB clear sera exécutée avant l'exécution du test.

Voici un exemple d'un tel test:

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

L'idée est la suivante

  1. Lire tous les tests en utilisant adb shell am instrument -e log true
  2. Construire un plan d'exécution en analysant la sortie de (1)
  3. Exécutez le plan d'exécution ligne par ligne

En utilisant la même idée, ce sont toutes des options que vous pouvez facilement prendre en charge:

  • Effacer les données
  • Effacer la barre de notification
  • Paramétrer
  • Filtrer et exécuter par balises

N'utilisez que des annotations. Comme ça:

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

Prime! 🎁 Pour chaque test échoué:

  • Récupérer Logcat + stacktrace
  • Enregistrer une vidéo (mp4)
  • Dump DB (sqlite)
  • Vider les préférences partagées par défaut (xml)
  • Collectez des fichiers dumpsys tels que: batterie, netstats et autres.

En général, il est facile d'ajouter plus d'options, puisque les tests sont exécutés un par un à partir du script bash plutôt que de la tâche gradle.

📗 Le billet de blog complet : https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8

📘 Le code source avec des exemples : https://github.com/medisafe/run-android-tests

J'espère que cela répond à la question de 6 ans;)

sromku
la source