Cancella i dati dell'applicazione a livello di programmazione


121

Desidero cancellare i dati della mia applicazione a livello di programmazione.

I dati dell'applicazione possono contenere qualsiasi cosa come database, preferenze condivise, file interni-esterni o qualsiasi altro file creato all'interno dell'applicazione.

So che possiamo cancellare i dati nel dispositivo mobile tramite:

Impostazioni-> Applicazioni-> ManageApplications-> My_application-> Cancella dati

Ma devo fare quanto sopra tramite un programma Android?

Risposte:


111

C'è una nuova API introdotta nell'API 19 (KitKat): ActivityManager.clearApplicationUserData () .

Consiglio vivamente di usarlo in nuove applicazioni:

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 non vuoi il modo hacker, puoi anche nascondere il pulsante sull'interfaccia utente, in modo che la funzionalità non sia disponibile sui vecchi telefoni.

La conoscenza di questo metodo è obbligatoria per chiunque utilizzi android:manageSpaceActivity.


Ogni volta che lo uso, lo faccio da un manageSpaceActivityche ha android:process=":manager". Lì, uccido manualmente qualsiasi altro processo della mia app. Ciò mi consente di lasciare in esecuzione un'interfaccia utente e di consentire all'utente di decidere dove andare dopo.

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
per me .clearApplicationUserData (); è forzare anche la chiusura dell'app.
gaurav414u

9
Deve terminare l'app, altrimenti potrebbe avere dati su cui si sta trattenendo che verranno riscritti. L'unico modo sicuro per farlo è (1) uccidere l'app, (2) cancellare tutti i suoi dati, (3) la prossima volta che l'app si avvia, ricomincerà da capo senza dati.
hackbod

4
Ciao @TWiStErRob, voglio implementare questo metodo quando si fa clic sul pulsante LOGOUT nella mia applicazione. Ma forza chiude l'app. Invece voglio iniziare l'attività principale in cui è presente il modulo di iscrizione / accesso .. Come sarà possibile?
pblead26

1
Per la versione pre KitKat vedere questa risposta: stackoverflow.com/a/23470355/3256989
ultraon

2
è possibile iniziare qualsiasi altra attività dopo aver applicato questo codice
Amandeep Rohila

106

Sto solo inserendo il tutorial dal link ihrupin pubblicato qui in questo 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;
    }
}

Quindi, se vuoi che un pulsante faccia questo, devi chiamare MyApplication.getInstance (). clearApplicationData () da un onClickListener

Aggiorna: la tua SharedPreferencesistanza potrebbe conservare i tuoi dati e ricreare il file delle preferenze dopo averlo eliminato. Quindi vorrai ottenere il tuo SharedPreferencesoggetto e

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

Aggiornare:

È necessario aggiungere android:name="your.package.MyApplication"alla application tagall'interno AndroidManifest.xml se non avesse fatto così. Altrimenti, MyApplication.getInstance()restituisce null, risultando una NullPointerException .


5
Stai attento ! Rimuovi tutto nella cartella dell'app, comprese le preferenze di condivisione .. non solo la directory della cache stessa e il suo contenuto.
Snicolas

2
Ho implementato questa soluzione. Ma i dati della mia applicazione non vengono cancellati solo la cache viene cancellata .. 5 MB sono ancora rimasti .. qualsiasi altra soluzione ?? Per favore aiutami :(
SweetWisher ツ

1
@MinceMan Si prega di menzionare che questo deve essere scritto in classe che estende l'applicazione per un effetto migliore
creepy_driver

Molto intelligente per mantenere la directory lib.
frostymarvelous

1
sì, ha rimosso tutti i file ma l'app non se ne è accorta, quindi potrei ancora essere file su app dir. L'app è stata cancellata dopo aver rimosso l'app dall'app recente e avviata. Ho provato a ricreare l'attività ma non ha funzionato
gturedi

15

combina il codice da 2 risposte:

Ecco la risposta basata sulla fonte combinata risultante

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

Funzionerà su tutti i dispositivi Android indipendentemente dalla versione Android? Per me, funziona su tutti e 3 i dispositivi Android che possiedo (con Lollipop, Marshmallow e Pie)
Kathir

sì, if else è uguale o inferiore a kit kat ... usa clearApplicationUserData e sopra usa runtime.exce ... fondamentalmente un comando di shell ... abbastanza affidabile a parte i permessi ... dovrebbe funzionare ...
CrandellWS

13

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 di cancellazione dei dati in Impostazioni -> Gestione applicazioni -> La tua app -> Cancella dati


3
Non consiglierei questo approccio. Usare programmi da riga di comando (ad esempio pm) che potrebbero non esistere è rischioso. Non fanno parte del "contratto" di Android SDK, quindi se esistono su un determinato dispositivo o se si comportano come su altri dispositivi dipende dai produttori e dagli sviluppatori di ROM personalizzate.
CommonsWare

2
In alternativa ho un'altra opzione, ad esempio ((ActivityManager) context.getSystemService (ACTIVITY_SERVICE)) .clearApplicationUserData (); Ma ha una limitazione che funziona solo a livello API> = 19 Puoi fornire un'alternativa qui o potrebbe essere un'altra opzione.
Summved Jain il


-1

Se vuoi un hack meno dettagliato:

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

1
Puoi citare quel percorso nel caso in cui abbia spazi e cose del genere.
TWiStErRob
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.