Limpar dados do aplicativo programaticamente


121

Desejo limpar os dados do meu aplicativo programaticamente.

Os dados do aplicativo podem conter qualquer coisa como bancos de dados, preferências compartilhadas, arquivos internos-externos ou quaisquer outros arquivos criados dentro do aplicativo.

Eu sei que podemos limpar os dados no dispositivo móvel por meio de:

Configurações-> Aplicativos-> Gerenciar aplicativos-> Meu_aplicativo-> Limpar dados

Mas preciso fazer o que precede por meio de um programa Android?

Respostas:


111

Há uma nova API introduzida na API 19 (KitKat): ActivityManager.clearApplicationUserData () .

Eu recomendo fortemente usá-lo em novos aplicativos:

import android.os.Build.*;
if (VERSION_CODES.KITKAT <= VERSION.SDK_INT) {
    ((ActivityManager)context.getSystemService(ACTIVITY_SERVICE))
            .clearApplicationUserData(); // note: it has a return value!
} else {
    // use old hacky way, which can be removed
    // once minSdkVersion goes above 19 in a few years.
}

Se você não quiser o jeito hacky, também pode ocultar o botão na IU, de forma que essa funcionalidade não esteja disponível em telefones antigos.

O conhecimento deste método é obrigatório para todos os usuários android:manageSpaceActivity.


Sempre que eu uso isso, eu o faço a partir de um manageSpaceActivityque tem android:process=":manager". Lá, eu mato manualmente quaisquer outros processos do meu aplicativo. Isso me permite deixar uma IU continuar em execução e permitir que o usuário decida para onde ir em seguida.

private static void killProcessesAround(Activity activity) throws NameNotFoundException {
    ActivityManager am = (ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE);
    String myProcessPrefix = activity.getApplicationInfo().processName;
    String myProcessName = activity.getPackageManager().getActivityInfo(activity.getComponentName(), 0).processName;
    for (ActivityManager.RunningAppProcessInfo proc : am.getRunningAppProcesses()) {
        if (proc.processName.startsWith(myProcessPrefix) && !proc.processName.equals(myProcessName)) {
            android.os.Process.killProcess(proc.pid);
        }
    }
}

9
para mim .clearApplicationUserData (); é forçar o fechamento do aplicativo também.
gaurav414u

9
Ele tem que encerrar o aplicativo, ou então pode haver dados que estão retendo que serão gravados de volta. A única maneira segura de fazer isso é (1) encerrar o aplicativo, (2) limpar todos os seus dados, (3) na próxima vez que o aplicativo for inicializado, ele será reiniciado sem dados.
hackbod

4
Olá @TWiStErRob, quero implementar este método quando clico no botão LOGOUT em meu aplicativo. Mas força o fechamento do aplicativo. Em vez disso, quero iniciar a atividade principal em que o formulário de inscrição / login está presente. Como isso será possível?
pblead26

1
Para a versão anterior do KitKat, veja esta resposta: stackoverflow.com/a/23470355/3256989
ultraon

2
é possível iniciar qualquer outra atividade após aplicar este código
Amandeep Rohila

106

Estou apenas colocando o tutorial do link ihrupin postado aqui neste post.

package com.hrupin.cleaner;

import java.io.File;

import android.app.Application;
import android.util.Log;

public class MyApplication extends Application {

    private static MyApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }

    public static MyApplication getInstance() {
        return instance;
    }

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

Portanto, se quiser que um botão faça isso, você precisa chamar MyApplication.getInstance (). clearApplicationData () de um onClickListener

Atualizar: sua SharedPreferencesinstância pode reter seus dados e recriar o arquivo de preferências depois de excluí-lo. Então você vai querer pegar seu SharedPreferencesobjeto e

prefs.edit().clear().commit();

Atualizar:

Você precisa adicionar android:name="your.package.MyApplication"ao application tagAndroidManifest.xml interno, caso ainda não tenha feito isso. Caso contrário , MyApplication.getInstance()retorna null, resultando em um NullPointerException .


5
Cuidar ! Você remove tudo na pasta do aplicativo, incluindo preferências de compartilhamento .. não apenas o diretório de cache em si e seu conteúdo.
Snicolas

2
Eu implementei esta solução. Mas os dados do meu aplicativo não são limpos, apenas o cache é limpo .. 5 MB ainda estão restantes .. alguma outra solução? Por favor me ajude :(
SweetWisher ツ

1
@MinceMan Por favor, mencione que isso deve ser escrito na aula que estende o aplicativo para melhor efeito
creepy_driver

Muito inteligente para manter o diretório lib.
Frostymarvelous

1
sim, ele removeu todos os arquivos, mas o aplicativo não percebeu, então eu ainda poderia ser arquivos no diretório do aplicativo. O aplicativo percebeu a limpeza após remover o aplicativo do aplicativo recente e iniciá-lo. Tentei recriar a atividade, mas não funcionou
gturedi

15

combinar código de 2 respostas:

Aqui está a resposta com base na fonte combinada resultante

private void clearAppData() {
    try {
        // clearing app data
        if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
            ((ActivityManager)getSystemService(ACTIVITY_SERVICE)).clearApplicationUserData(); // note: it has a return value!
        } else {
            String packageName = getApplicationContext().getPackageName();
            Runtime runtime = Runtime.getRuntime();
            runtime.exec("pm clear "+packageName);
        }

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

Isso funcionará em todos os dispositivos Android, independentemente da versão do Android? Para mim, funciona em todos os três dispositivos Android que possuo (com Lollipop, Marshmallow e Pie)
Kathir

sim o if else é igual ou inferior a kit kat ... use clearApplicationUserData e acima ele usa runtime.exce ... basicamente um comando shell ... bastante confiável além de permissões ... ele deve funcionar ...
CrandellWS

13

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á seu aplicativo da memória. É equivalente à opção de limpar dados em Configurações -> Gerenciador de aplicativos -> Seu aplicativo -> Limpar dados


3
Eu não recomendaria essa abordagem. Usar programas de linha de comando (por exemplo, pm) que podem não existir é arriscado. Eles não fazem parte do "contrato" do Android SDK e, portanto, se existem em um determinado dispositivo ou se se comportam da mesma forma que em outros dispositivos depende dos fabricantes e desenvolvedores de ROM personalizadas.
CommonsWare

2
Como alternativa, tenho mais uma opção, ou seja, ((ActivityManager) context.getSystemService (ACTIVITY_SERVICE)) .clearApplicationUserData (); Mas tem uma limitação de que só funciona no nível de API> = 19 Você pode fornecer uma alternativa aqui ou pode ser outra opção.
Summved Jain de

2

O que eu uso em todos os lugares:

 Runtime.getRuntime().exec("pm clear me.myapp");

Executar o trecho de código acima fecha o aplicativo e remove todos os bancos de dados e preferências compartilhadas


-1

Se você quiser um hack menos prolixo:

void deleteDirectory(String path) {
  Runtime.getRuntime().exec(String.format("rm -rf %s", path));
}

1
Você pode citar esse caminho caso tenha espaços e outras coisas.
TWiStErRob
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.