Clear Application's Data Programmatically
Asked Answered
P

6

141

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?

Pak answered 26/5, 2011 at 5:32 Comment(0)
S
147

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);
        }
    }
}
Sincerity answered 22/3, 2015 at 17:3 Comment(16)
for me .clearApplicationUserData(); is force closing the app as well.Touchstone
Check your logcat: "it crashes" doesn't mean anything without an Exception/stacktrace. Also you may need some permissions (e.g. write external storage?).Sincerity
Then it's probably something after, check the logs!Sincerity
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.Acridine
Hi @Sincerity 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?Intercessory
@Intercessory see update, if you need more than this, please open a new question, as your followup is unrelated to this current question OP asked.Sincerity
@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.Sincerity
Can you maybe explain how to call the killProcessesAround method? I dont get where/how it should be used?Finitude
@Lichtamberg see hackbod's comment. I call it right before calling clearApplicationUserData.Sincerity
So you mean like this? try { killProcessesAround(CurrentManageSpaceActivity.this); ((ActivityManager) getApplicationContext().getSystemService(ACTIVITY_SERVICE)).clearApplicationUserData(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); }Finitude
For pre KitKat version see this answer: https://mcmap.net/q/150970/-how-to-programmatically-clear-application-dataPsychopathist
is it possible to start any other activity after apply this codeClobber
@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.Sincerity
@Sincerity 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?Foveola
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:issuetracker.google.com/issues/174903931 . Please consider starring.Amoebic
@androiddeveloper and it is marked as "Won't Fix"Taxicab
E
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.

Expiation answered 31/1, 2012 at 1:58 Comment(10)
Take care ! You remove everyting in the app folder, including share preferences.. not only the cache dir itself and its content.Serdab
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 :(Fluency
@Expiation Please mention that this must be writted in class that extends Application for better effectKamacite
Very smart to keep the lib dir.Pattipattie
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.Recap
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 workBromidic
how can i use this and still keep the shared preferences file without uploading it to a server or anything like that?Gilliam
Either don't call prefs.edit().clear().commit(); or add prefs.edit().commit(); to have your prefs recreate it after you deleted it.Expiation
Why isn't the 'lib' directory removed?Montsaintmichel
One benefit of this approach is that it does not reset user granted permissions like activityManager.clearApplicationUserData() does.Merbromin
I
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();
    } 
}
Impostume answered 29/5, 2018 at 2:27 Comment(2)
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)Paroxysm
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...Impostume
P
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

Pd answered 10/7, 2017 at 6:56 Comment(0)
G
0

If you want a less verbose hack:

void deleteDirectory(String path) {
  Runtime.getRuntime().exec(String.format("rm -rf %s", path));
}
Gemmulation answered 28/4, 2014 at 17:0 Comment(1)
You may want to quote that path in case it has spaces and stuff.Sincerity
V
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();
    }
}
Vargo answered 31/1, 2021 at 6:54 Comment(1)
Can you add an explanation to this or a link to where you got it from please?Fungus

© 2022 - 2024 — McMap. All rights reserved.