140

I want to clear my application's data programmatically.

Application's data may contain anything like databases, shared preferences, Internal-External files or any other files created within the application.

I know we can clear data in the mobile device through:

Settings->Applications-> ManageApplications-> My_application->Clear Data

But I need to do the above thing through an Android Program?

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
uday
  • 1,625
  • 3
  • 14
  • 16

6 Answers6

143

There's a new API introduced in API 19 (KitKat): ActivityManager.clearApplicationUserData().

I highly recommend using it in new applications:

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

If you don't want the hacky way you can also hide the button on the UI, so that functionality is just not available on old phones.

Knowledge of this method is mandatory for anyone using android:manageSpaceActivity.


Whenever I use this, I do so from a manageSpaceActivity which has android:process=":manager". There, I manually kill any other processes of my app. This allows me to let a UI stay running and let the user decide where to go next.

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
  • 44,762
  • 26
  • 170
  • 254
  • 15
    for me .clearApplicationUserData(); is force closing the app as well. – gaurav414u Apr 07 '15 at 10:07
  • Check your logcat: "it crashes" doesn't mean anything without an Exception/stacktrace. Also you may need some permissions (e.g. write external storage?). – TWiStErRob Apr 07 '15 at 10:15
  • Then it's probably something after, check the logs! – TWiStErRob Apr 07 '15 at 13:44
  • 13
    It has to kill the app, or else it could have data it is holding on to that will get written back. The only safe way to do this is to (1) kill the app, (2) clear all of its data, (3) next time the app starts up it will start fresh with no data. – hackbod Nov 30 '15 at 22:35
  • 5
    Hi @TWiStErRob I want to implement this method when clicked on LOGOUT button in my application. But it force closes the app. Instead I want to start the main activity where the signup/sign in form is present.. How will this be possible? – pblead26 Jul 25 '16 at 14:14
  • @pblead26 see update, if you need more than this, please open a new question, as your followup is unrelated to this current question OP asked. – TWiStErRob Jul 25 '16 at 16:39
  • @Dharmendra sorry, just a utility method to deal with `NameNotFoundException`, I inlined it. This exception shouldn't be thrown in this case because we're querying the current *running* activity. – TWiStErRob Aug 11 '16 at 10:46
  • Can you maybe explain how to call the killProcessesAround method? I dont get where/how it should be used? – BvuRVKyUVlViVIc7 Oct 18 '16 at 09:55
  • @Lichtamberg see hackbod's comment. I call it right before calling `clearApplicationUserData`. – TWiStErRob Oct 18 '16 at 10:01
  • So you mean like this? try { killProcessesAround(CurrentManageSpaceActivity.this); ((ActivityManager) getApplicationContext().getSystemService(ACTIVITY_SERVICE)).clearApplicationUserData(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } – BvuRVKyUVlViVIc7 Oct 18 '16 at 10:12
  • 1
    For pre KitKat version see this answer: http://stackoverflow.com/a/23470355/3256989 – ultraon Oct 24 '16 at 13:07
  • 2
    is it possible to start any other activity after apply this code – Amandeep Rohila Feb 22 '17 at 07:39
  • @AmandeepRohila When I use the `android:process` attribute as described I still have a running activity that's part of the app, so after the `clearApplicationUserData()` returns you should be able to fire up another activity with `startActivity` as usual. Make sure you call clear in background and start the activity on the UI thread! It's also advised that your other process doesn't use any files/db/prefs, just a plain activity. – TWiStErRob Feb 22 '17 at 23:26
  • 1
    @TWiStErRob I want to launch an activity with a dialog after invoking `clearApplicationUserData()`. I am trying to use the steps outlined with a separate activity using the `android:process` but calling `clearApplicationUserData()` seems to kill everything. Is this not possible? – Robert May 15 '18 at 19:52
  • 1
    As far as I know it's impossible to run anything after calling this function, because it acts exactly as clear-data. I've made a request to improve it, here:https://issuetracker.google.com/issues/174903931 . Please consider starring. – android developer Dec 07 '20 at 08:05
  • @androiddeveloper and it is marked as "Won't Fix" – Farid Apr 28 '22 at 15:24
111

I'm just putting the tutorial from the link ihrupin posted here in this 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;
    }
}

So if you want a button to do this you need to call MyApplication.getInstance(). clearApplicationData() from within an onClickListener

Update: Your SharedPreferences instance might hold onto your data and recreate the preferences file after you delete it. So your going to want to get your SharedPreferences object and

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

Update:

You need to add android:name="your.package.MyApplication" to the application tag inside AndroidManifest.xml if you had not done so. Else, MyApplication.getInstance() returns null, resulting a NullPointerException.

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
MinceMan
  • 7,483
  • 3
  • 38
  • 40
  • 5
    Take care ! You remove everyting in the app folder, including share preferences.. not only the cache dir itself and its content. – Snicolas May 22 '13 at 13:44
  • 2
    I have implemented this solution . But my application data is not cleared only cache is cleared.. 5 MB is still remaining.. any other solution?? Please help me out :( – SweetWisher ツ Sep 05 '13 at 06:55
  • 1
    @MinceMan Please mention that this must be writted in class that extends Application for better effect – vishalmullur Sep 18 '14 at 11:47
  • Very smart to keep the lib dir. – frostymarvelous Nov 13 '14 at 15:31
  • To people posting updates, it'd be good to either make the updated text flow with the rest of the text, or specify from when the updates apply. – dayuloli Mar 17 '15 at 16:34
  • 1
    yes it removed all files but app not realized it so i still could be files on app dir. App realized clearing after remove app from recent app thren start it. I tried to recreate activity but it not work – gturedi Nov 06 '15 at 14:01
  • how can i use this and still keep the shared preferences file without uploading it to a server or anything like that? – Sweetie Anang Feb 15 '18 at 12:28
  • Either don't call `prefs.edit().clear().commit();` or add `prefs.edit().commit();` to have your prefs recreate it after you deleted it. – MinceMan Jun 12 '18 at 17:38
  • 1
    Why isn't the 'lib' directory removed? – Anonsage Jun 14 '19 at 21:15
  • 1
    One benefit of this approach is that it does not reset user granted permissions like activityManager.clearApplicationUserData() does. – AtomicBoolean Oct 07 '19 at 18:45
24

combine code from 2 answers:

Here is the resulting combined source based answer

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
  • 2,708
  • 5
  • 49
  • 111
  • Will this work on all Android devices irrespective of the Android version? For me, it works on all 3 Android devices I own (with Lollipop, Marshmallow and Pie) – Kathir Jan 25 '19 at 11:55
  • yea the if else is for equal or less than kit kat ...use clearApplicationUserData and above it uses runtime.exce... basically a shell command ...pretty reliable other than permissions...it should just work... – CrandellWS Jan 26 '19 at 01:17
2

What I use everywhere :

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

Executing above piece of code closes application and removes all databases and shared preferences

PEHLAJ
  • 9,980
  • 9
  • 41
  • 53
0

If you want a less verbose hack:

void deleteDirectory(String path) {
  Runtime.getRuntime().exec(String.format("rm -rf %s", path));
}
Christopher Perry
  • 38,891
  • 43
  • 145
  • 187
0

Try this code

private void clearAppData() {
    try {
        if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
            ((ActivityManager)getSystemService(ACTIVITY_SERVICE)).clearApplicationUserData();
        } else {
            Runtime.getRuntime().exec("pm clear " + getApplicationContext().getPackageName());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Fakhriddin Abdullaev
  • 4,169
  • 2
  • 35
  • 37