Como limpar programaticamente os dados do aplicativo

152

Estou desenvolvendo testes automatizados para um aplicativo Android (usando o Robotium). Para garantir a consistência e a confiabilidade dos testes, gostaria de iniciar cada teste com o estado limpo (do aplicativo em teste). Para fazer isso, preciso limpar os dados do aplicativo. Isso pode ser feito manualmente em Configurações / Aplicativos / Gerenciar aplicativos / [Meu aplicativo] / Limpar dados

Qual é a maneira recomendada de fazer isso programaticamente?

user597603
fonte
É possível usar a ferramenta adb para limpar os dados entre os lançamentos de aplicativos? adb -w
smith324
Infelizmente, esta opção não está disponível (a ajuda do adb está desatualizada).
user597603
Isso seria ótimo. Ao depurar problemas do banco de dados, tenho que navegar muito para a opção Limpar dados e isso realmente interrompe meu fluxo.
Jason Prado
Como fazer isso via Android Studio é discutido aqui: stackoverflow.com/q/31713579/905686 .
User905686
Especificamente, faça o seguinte: stackoverflow.com/a/57461180/94557
Matt Wolfe

Respostas:

171

Você pode usar a ferramenta gerenciadora de pacotes para limpar os dados dos aplicativos instalados (semelhante ao pressionar o botão 'limpar dados' nas configurações do aplicativo no seu dispositivo). Então, usando adb, você poderia fazer:

adb shell pm clear my.wonderful.app.package
edovino
fonte
1
No Android 2.1-update1, isso infelizmente produz Error: unknown command 'clear'.
Paul Lammertsma
@Palani: funciona para mim para qualquer versão acima de 2.1-r1 (andoid-7). alguma mensagem de erro?
Edovino
1
O comando acima se conecta ao shell do Android e executa "pm clear my.wonderful.app.package" no android. No meu dispositivo, o comando "pm" não tem a opção "limpar". Não tem nada a ver com sdk. Depende do firmware do dispositivo.
Palani
m à procura de dados claros de navegador (defaut) e Chrome navegador no dispositivo Android programmaticaly de minha ajuda app.Please android para ele ..
Brijesh Patel
Não funciona em todos os dispositivos, mas é maravilhoso para os dispositivos em que trabalha #
Cory Trese
34

Seguindo a resposta de @ edovino, a maneira de limpar programaticamente todas as preferências de um aplicativo seria

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

Aviso : o aplicativo forçará o fechamento.

Sebastiano
fonte
5
Se você tiver algum código de teste em execução depois disso, ele falhará.
rajath
A execução deste requer e as permissões devem ser declaradas no manifesto?
Reubenjohn
1
Não, não requer nenhuma permissão especial.
Sebastiano
Thx, você salvou minha vida!
Sidd
1
se eu não quiser forçar o fechamento do aplicativo, então?
NJ
22

você pode limpar os dados do aplicativo SharedPreferences com este

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

e para limpar o aplicativo db, esta resposta está correta -> Limpando o banco de dados de aplicativos

guleryuz
fonte
14

Na API versão 19, é possível chamar ActivityManager.clearApplicationUserData ().

((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();
Joakim
fonte
13
Apenas para sua informação, chamar isso encerrará seu aplicativo.
Zach Rattner
8

Verifique este código para:

@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
fonte
6

Se você tiver apenas algumas preferências compartilhadas para limpar, essa solução será muito melhor .

@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
fonte
Isso não requer que o "modo de instrumentação" esteja ativado? O que é esse modo afinal?
ADTC 19/08/19
Sim, isso requer um aplicativo "instrumentado", ou seja, seu teste é executado ao lado do código do aplicativo em um dispositivo real em processo , o que significa que você pode acessar todo o estado do seu aplicativo e alterá-lo no tempo de execução para fins de teste.
Thomas Keller
o que deveria estar (...)?
NickUnuchek
@NickUnuchek O nome do arquivo de preferências.
Thomas Keller
3

Usando o contexto , podemos limpar arquivos específicos do aplicativo, como preferência, arquivo de banco de dados. Eu usei o código abaixo para testar a interface do usuário usando o 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
fonte
3

A maneira mais simples de fazer isso é

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

Isso limpará os dados e removerá o aplicativo da memória. É equivalente à opção limpar dados em Configurações -> Gerenciador de aplicativos -> Seu aplicativo -> Limpar dados.

Isso removerá os dados completamente e forçará o fechamento do aplicativo

Jain Summved
fonte
Não adicione a mesma resposta a várias perguntas. Responda à melhor e marque o restante como duplicado. Consulte É aceitável adicionar uma resposta duplicada a várias perguntas?
FelixSFD
1
Como podemos conseguir isso sem o fechamento de aplicativos
Omkar Ghurye
2

Esta solução realmente me ajudou:

Usando dois métodos abaixo, podemos limpar os dados programaticamente

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

se a versão android estiver acima do kitkat, você também pode usá-la

public void onClick (Visualizar exibição) {

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

Qual é a maneira recomendada de fazer isso programaticamente?

A única opção possível é executar o comando ADB adb shell pm clear packageantes do teste. O maior problema é que é um tipo de dor de cabeça combinando a execução de testes e os comandos do shell.

No entanto, nós (na Mediafe) viemos com uma solução que pode funcionar para você em um dispositivo não raiz comum. Tudo que você precisa fazer é adicionar uma anotação. Todo o resto é feito executando o script bash simples .

Basta adicionar @ClearDataanotação antes de QUALQUER dos seus testes e tada 🎉, o comando ADB clear será executado antes da execução do teste.

Este é um exemplo desse teste:

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

A ideia é a seguinte

  1. Leia todos os testes usando adb shell am instrument -e log true
  2. Construa o plano de execução analisando a saída de (1)
  3. Execute o plano de execução linha por linha

Usando a mesma idéia, todas essas opções podem ser facilmente suportadas:

  • Apagar os dados
  • Limpar barra de notificação
  • Parametrizar
  • Filtrar e executar por tags

Use apenas anotações. Como isso:

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

Bônus! 🎁 Para cada teste com falha:

  • Coletar Logcat + stacktrace
  • Gravar vídeo (mp4)
  • Banco de dados de despejo (sqlite)
  • Despejar preferências compartilhadas padrão (xml)
  • Colete arquivos dumpsys como: bateria, netstats e outros.

Em geral, é fácil adicionar mais opções, pois os testes são executados um a um a partir do script bash, em vez da tarefa gradle.

📗 A publicação completa do blog : https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8

Code O código fonte com exemplos : https://github.com/medisafe/run-android-tests

Espero que isso responda 6 anos pergunta;)

sromku
fonte