Borrar los datos de la aplicación mediante programación

121

Quiero borrar los datos de mi aplicación mediante programación.

Los datos de la aplicación pueden contener cualquier cosa como bases de datos, preferencias compartidas, archivos internos-externos o cualquier otro archivo creado dentro de la aplicación.

Sé que podemos borrar datos en el dispositivo móvil a través de:

Configuración-> Aplicaciones-> Administrar aplicaciones-> Mi_aplicación-> Borrar datos

¿Pero necesito hacer lo anterior a través de un programa de Android?

uday
fuente

Respuestas:

111

Hay una nueva API introducida en API 19 (KitKat): ActivityManager.clearApplicationUserData () .

Recomiendo encarecidamente usarlo en nuevas aplicaciones:

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

Si no desea la forma pirata, también puede ocultar el botón en la interfaz de usuario, por lo que la funcionalidad simplemente no está disponible en teléfonos antiguos.

El conocimiento de este método es obligatorio para cualquiera que lo utilice android:manageSpaceActivity.


Siempre que uso esto, lo hago desde un manageSpaceActivityarchivo que tiene android:process=":manager". Allí, elimino manualmente cualquier otro proceso de mi aplicación. Esto me permite dejar una interfaz de usuario ejecutándose y dejar que el usuario decida a dónde ir.

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);
        }
    }
}
TWiStErRob
fuente
9
para mí .clearApplicationUserData (); fuerza el cierre de la aplicación también.
gaurav414u
9
Tiene que matar la aplicación, o de lo contrario podría tener datos que está guardando y que se volverán a escribir. La única forma segura de hacer esto es (1) matar la aplicación, (2) borrar todos sus datos, (3) la próxima vez que la aplicación se inicie, comenzará de nuevo sin datos.
hackbod
4
Hola @TWiStErRob Quiero implementar este método cuando hago clic en el botón LOGOUT en mi aplicación. Pero fuerza el cierre de la aplicación. En su lugar, quiero comenzar la actividad principal donde esté presente el formulario de registro / inicio de sesión. ¿Cómo será esto posible?
pblead26
1
Para la versión anterior a KitKat, consulte esta respuesta: stackoverflow.com/a/23470355/3256989
ultraon
2
¿Es posible iniciar cualquier otra actividad después de aplicar este código?
Amandeep Rohila
106

Solo estoy poniendo el tutorial del enlace que ihrupin publicó aquí en esta publicación.

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

Entonces, si desea un botón para hacer esto, debe llamar a MyApplication.getInstance (). clearApplicationData () desde dentro de un onClickListener

Actualización: su SharedPreferencesinstancia puede retener sus datos y volver a crear el archivo de preferencias después de eliminarlo. Entonces querrás obtener tu SharedPreferencesobjeto y

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

Actualizar:

Debe agregar android:name="your.package.MyApplication"al application tagAndroidManifest.xml interno si no lo había hecho. De lo contrario, MyApplication.getInstance()devuelve null, lo que resulta en una NullPointerException .

MinceMan
fuente
5
Cuídate ! Elimina todo en la carpeta de la aplicación, incluidas las preferencias de uso compartido ... no solo el directorio de caché en sí y su contenido.
Snicolas
2
He implementado esta solución. Pero los datos de mi aplicación no se borran, solo se borra el caché .. Aún quedan 5 MB .. ¿Alguna otra solución? Por favor, ayúdame :(
SweetWisher ツ
1
@MinceMan Por favor, mencione que esto debe escribirse en la clase que amplía la Aplicación para un mejor efecto
creepy_driver
Muy inteligente para mantener el directorio lib.
frostymarvelous
1
sí, eliminó todos los archivos, pero la aplicación no se dio cuenta, por lo que todavía podría haber archivos en el directorio de la aplicación. La aplicación se borró después de eliminar la aplicación de la aplicación reciente y luego iníciela. Intenté recrear la actividad pero no funcionó
gturedi
15

combinar código de 2 respuestas:

Aquí está la respuesta basada en fuente 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();
    } 
}
CrandellWS
fuente
¿Funcionará esto en todos los dispositivos Android independientemente de la versión de Android? Para mí, funciona en los 3 dispositivos Android que tengo (con Lollipop, Marshmallow y Pie)
Kathir
sí, el if else es igual o menor que kit kat ... use clearApplicationUserData y arriba usa runtime.exce ... básicamente un comando de shell ... bastante confiable aparte de los permisos ... debería funcionar ...
CrandellWS
13

La forma más sencilla de hacer esto es

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

Esto borrará los datos y eliminará su aplicación de la memoria. Es equivalente a la opción de borrar datos en Configuración -> Administrador de aplicaciones -> Su aplicación -> Borrar datos

Summved Jain
fuente
3
No recomendaría este enfoque. Usar programas de línea de comandos (por ejemplo, pm) que podrían no existir es riesgoso. No forman parte del "contrato" de Android SDK, por lo que si existen en un dispositivo determinado o si se comportan igual que en otros dispositivos depende de los fabricantes y desarrolladores de ROM personalizados.
CommonsWare
2
Como alternativa, tengo una opción más, es decir ((ActivityManager) context.getSystemService (ACTIVITY_SERVICE)) .clearApplicationUserData (); Pero tiene la limitación de que solo funciona con un nivel de API> = 19. ¿Puede proporcionar una alternativa aquí o puede ser otra opción?
Summved Jain
2

Lo que uso en todas partes:

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

La ejecución del código anterior cierra la aplicación y elimina todas las bases de datos y preferencias compartidas

Pehlaj - Desarrollador de aplicaciones móviles
fuente
-1

Si quieres un truco menos detallado:

void deleteDirectory(String path) {
  Runtime.getRuntime().exec(String.format("rm -rf %s", path));
}
Christopher Perry
fuente
1
Es posible que desee citar esa ruta en caso de que tenga espacios y esas cosas.
TWiStErRob