Очистить данные приложения программно

121

Я хочу программно очистить данные моего приложения.

Данные приложения могут содержать что угодно, например базы данных, общие настройки, внутренние и внешние файлы или любые другие файлы, созданные в приложении.

Я знаю, что мы можем очистить данные на мобильном устройстве с помощью:

Настройки-> Приложения-> Управление приложениями-> My_application-> Очистить данные

Но мне нужно сделать это через программу для Android?

Удай
источник

Ответы:

111

В API 19 (KitKat) представлен новый API: ActivityManager.clearApplicationUserData () .

Очень рекомендую использовать в новых приложениях:

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

Если вам не нужен хакерский способ, вы также можете скрыть кнопку в пользовательском интерфейсе, так что эта функциональность просто недоступна на старых телефонах.

Знание этого метода обязательно для всех, кто использует android:manageSpaceActivity.


Всякий раз, когда я использую это, я делаю это из файла, у manageSpaceActivityкоторого есть android:process=":manager". Там я вручную убиваю любые другие процессы своего приложения. Это позволяет мне позволить пользовательскому интерфейсу продолжать работать, а пользователь сам решает, что делать дальше.

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
источник
9
для меня .clearApplicationUserData (); принудительно закрывает приложение.
gaurav414u
9
Он должен убить приложение, иначе у него могут быть данные, которые он хранит, которые будут записаны обратно. Единственный безопасный способ сделать это - (1) убить приложение, (2) удалить все его данные, (3) в следующий раз, когда приложение запустится, оно запустится заново без данных.
hackbod
4
Привет, @TWiStErRob. Я хочу реализовать этот метод при нажатии кнопки ВЫХОД в моем приложении. Но это принудительно закрывает приложение. Вместо этого я хочу начать основное действие, где присутствует форма регистрации / входа. Как это будет возможно?
pblead26
1
Для версии до KitKat см. Этот ответ: stackoverflow.com/a/23470355/3256989
ultraon
2
можно ли начать какие-либо другие действия после применения этого кода
Амандип Рохила,
107

Я просто выкладываю туториал по ссылке ihrupin, размещенной здесь в этом посте.

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

Поэтому, если вы хотите, чтобы для этого была кнопка, вам нужно вызвать MyApplication.getInstance (). clearApplicationData () из onClickListener

Обновление: ваш SharedPreferencesэкземпляр может удерживать ваши данные и воссоздавать файл настроек после его удаления. Итак, вы захотите получить свой SharedPreferencesобъект и

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

Обновить:

Вам нужно добавить android:name="your.package.MyApplication"к application tagвнутренней AndroidManifest.xml , если вы еще не сделали этого. В противном случае MyApplication.getInstance()возвращается null, в результате чего возникает исключение NullPointerException .

MinceMan
источник
5
Береги себя ! Вы удаляете все, что есть в папке приложения, включая настройки общего доступа ... не только сам каталог кеша и его содержимое.
Snicolas
2
Я реализовал это решение. Но данные моего приложения не очищаются, очищается только кеш .. Осталось 5 МБ .. любое другое решение ?? Пожалуйста, помогите мне :(
SweetWisher ツ
1
@MinceMan Пожалуйста, отметьте, что это должно быть написано в классе, который расширяет Application для лучшего эффекта
creepy_driver
Очень разумно сохранить каталог lib.
Frostymarvelous
1
да, он удалил все файлы, но приложение не осознало этого, поэтому я все еще могу быть файлами в каталоге приложения. Приложение реализовало очистку после удаления приложения из недавнего приложения и его запуска. Я попытался воссоздать активность, но это не сработало
gturedi
15

объединить код из 2 ответов:

Вот итоговый ответ на основе комбинированного источника

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
источник
Будет ли это работать на всех устройствах Android независимо от версии Android? На мой
Катир
да, if else для равного или меньшего, чем kit kat ... используйте clearApplicationUserData, а выше он использует runtime.exce ... в основном команду оболочки ... довольно надежную, кроме разрешений ... она должна просто работать ...
CrandellWS
13

Самый простой способ сделать это -

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

Это очистит данные и удалит ваше приложение из памяти. Это эквивалентно опции очистки данных в разделе «Настройки» -> «Диспетчер приложений» -> «Ваше приложение» -> «Очистить данные».

Summved Jain
источник
3
Я бы не рекомендовал такой подход. Использование программ командной строки (например, pm), которые могут не существовать, рискованно. Они не являются частью «контракта» Android SDK, поэтому, существуют ли они на данном устройстве или ведут себя так же, как на других устройствах, зависит от производителей и разработчиков пользовательских ПЗУ.
CommonsWare
2
В качестве альтернативы у меня есть еще один вариант, т.е. ((ActivityManager) context.getSystemService (ACTIVITY_SERVICE)) .clearApplicationUserData (); Но у него есть ограничение: он работает только на уровне API> = 19. Не могли бы вы предоставить здесь альтернативу или другой вариант.
Summved Jain
2

Что использую везде:

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

Выполнение вышеуказанного фрагмента кода закрывает приложение и удаляет все базы данных и общие настройки.

Пехлай - Разработчик мобильных приложений
источник
-1

Если вам нужен менее подробный хак:

void deleteDirectory(String path) {
  Runtime.getRuntime().exec(String.format("rm -rf %s", path));
}
Кристофер Перри
источник
1
Вы можете указать этот путь в кавычках, если в нем есть пробелы и прочее.
TWiStErRob