Come cancellare a livello di codice i dati dell'applicazione


152

Sto sviluppando test automatizzati per un'applicazione Android (usando Robotium). Al fine di garantire la coerenza e l'affidabilità dei test, vorrei iniziare ogni test con uno stato pulito (dell'applicazione in esame). Per fare ciò, devo cancellare i dati dell'app. Questo può essere fatto manualmente in Impostazioni / Applicazioni / Gestisci applicazioni / [La mia app] / Cancella dati

Qual è il modo consigliato per farlo programmaticamente?


È possibile utilizzare lo strumento adb per cancellare i dati tra i lanci delle applicazioni? adb -w
smith324,

Sfortunatamente, questa opzione non è disponibile (la guida adb è obsoleta).
user597603

Sarebbe fantastico. Quando eseguo il debug dei problemi del database, devo navigare fino all'opzione Cancella dati così tanto che interrompe davvero il mio flusso.
Jason Prado,

Come farlo tramite Android Studio è discusso qui: stackoverflow.com/q/31713579/905686 .
user905686

In particolare, eseguire questa operazione: stackoverflow.com/a/57461180/94557
Matt Wolfe,

Risposte:


171

Puoi utilizzare lo strumento di gestione dei pacchetti per cancellare i dati per le app installate (in modo simile alla pressione del pulsante "cancella dati" nelle impostazioni dell'app sul tuo dispositivo). Quindi usando adb potresti fare:

adb shell pm clear my.wonderful.app.package

1
Su Android 2.1-update1, questo sfortunatamente produce Error: unknown command 'clear'.
Paul Lammertsma,

@Palani: funziona per me per qualsiasi versione sopra 2.1-r1 (andoid-7). qualche messaggio di errore?
edovino,

1
Il comando sopra si collega alla shell Android ed esegue "pm clear my.wonderful.app.package" in Android. Nel mio dispositivo, il comando "pm" non ha l'opzione "cancella". Non ha nulla a che fare con SDK. Dipende dal firmware del dispositivo.
Palani,

sto cercando dati chiari di app browser (defaut) e Chrome nel dispositivo Android a livello di programmazione dalla mia app Android. Aiutatemi per favore ..
Brijesh Patel,

Non funziona su tutti i dispositivi, ma è meraviglioso per i dispositivi su cui funziona
Cory Trese,

34

Seguendo la risposta di @ edovino, il modo di cancellare programmaticamente tutte le preferenze di un'applicazione sarebbe

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

Attenzione : l'applicazione forzerà la chiusura.


5
Se hai qualche codice di test in esecuzione dopo questo, fallisce.
rajath,

L'esecuzione richiede e le autorizzazioni devono essere dichiarate nel manifest?
reubenjohn,

1
No, non richiede alcun permesso speciale.
Sebastiano,

Grazie, mi hai salvato la vita!
Sidd,

1
se non voglio forzare la chiusura dell'app allora?
NJ,

22

con questo puoi cancellare i dati delle app di SharedPreferences

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

e per cancellare l'app db, questa risposta è corretta -> Cancellazione del database dell'applicazione


14

Dalla versione API 19 è possibile chiamare ActivityManager.clearApplicationUserData ().

((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();

13
Cordiali saluti, chiamare questo terminerà la tua app.
Zach Rattner,

8

Controlla questo codice per:

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

6

Se hai solo un paio di preferenze condivise da cancellare, questa soluzione è molto più bella .

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

Non è necessario abilitare la "modalità strumentazione" ? Qual è quella modalità comunque?
ADTC

Sì, ciò richiede un'applicazione "strumentata", ovvero il test viene eseguito insieme al codice dell'applicazione su un dispositivo reale in corso , il che significa che è possibile accedere a tutto lo stato dell'applicazione e modificarlo in fase di esecuzione a scopo di test.
Thomas Keller,

cosa dovrebbe essere in (...)?
NickUnuchek,

@NickUnuchek Il nome del file delle preferenze.
Thomas Keller,

3

Utilizzando il contesto , possiamo cancellare file specifici dell'app come preferenze, file di database. Ho usato il codice qui sotto per i test dell'interfaccia utente usando 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");
    }

3

Il modo più semplice per farlo è

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

Questo cancellerà i dati e rimuoverà la tua app dalla memoria. È equivalente all'opzione Cancella dati in Impostazioni -> Gestione applicazioni -> La tua app -> Cancella dati.

Ciò rimuoverà completamente i dati e forzerà la chiusura dell'app


Si prega di non aggiungere la stessa risposta a più domande. Rispondi a quello migliore e contrassegna il resto come duplicati. Vedi È accettabile aggiungere una risposta duplicata a diverse domande?
FelixSFD

1
Come possiamo raggiungere questo obiettivo senza
chiudere l'

2

Questa soluzione mi ha davvero aiutato:

Utilizzando di seguito due metodi possiamo cancellare i dati in modo programmatico

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

2

se la versione di Android è al di sopra di kitkat puoi usare anche questo

public void onClick (Visualizza vista) {

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

0

Qual è il modo consigliato per farlo programmaticamente?

L'unica opzione possibile è eseguire il comando ADB adb shell pm clear packageprima del test. Il problema più grande è che è un tipo di mal di testa che combina l'esecuzione dei test e i comandi della shell.

Tuttavia, noi (di Mediafe) abbiamo fornito alcune soluzioni che possono funzionare per te su un normale dispositivo non root. Tutto quello che devi fare è aggiungere un'annotazione. Tutto il resto viene eseguito eseguendo un semplice script bash .

Basta aggiungere @ClearDataun'annotazione prima di QUALSIASI dei tuoi test e tada 🎉, il comando di cancellazione ADB verrà eseguito prima dell'esecuzione del test.

Questo è un esempio di tale test:

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

L'idea è la seguente

  1. Leggi tutti i test utilizzando adb shell am instrument -e log true
  2. Compilare il piano di esecuzione analizzando l'output di (1)
  3. Esegui il piano di esecuzione riga per riga

Usando la stessa idea, queste sono tutte opzioni che puoi facilmente supportare:

  • Cancella i dati
  • Cancella barra di notifica
  • Parametrizzazione
  • Filtra ed esegui per tag

Usa solo annotazioni. Come questo:

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

Bonus! 🎁 Per ogni test fallito:

  • Raccogli Logcat + stacktrace
  • Registra video (mp4)
  • Dump DB (sqlite)
  • Scarica preferenze condivise predefinite (xml)
  • Raccogli file dumpsys come: batteria, netstats e altro.

In generale, è facile aggiungere più opzioni, poiché i test vengono eseguiti uno ad uno dallo script bash anziché dall'attività gradle.

📗 Il post completo del blog : https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8

📘 Il codice sorgente con esempi : https://github.com/medisafe/run-android-tests

Spero che questo risponda alla domanda di 6 anni;)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.