How to programmatically clear application data
Asked Answered
S

10

157

I am developing automated tests for an android application (using Robotium). In order to ensure the consistency and reliability of tests, I would like to start each test with clean state (of the application under test). In order to do so, I need to clear the app data. This can be done manually in Settings/Applications/Manage Applications/[My App]/Clear data

What is the recommended way to get this done programmatically?

Scotia answered 31/1, 2011 at 22:42 Comment(5)
Is it feasible to use the adb tool to clear the data between application launches? adb -wAdim
Unfortunately, this option is not available (the adb help is outdated).Scotia
This would be so great. When debugging database issues, I have to navigate to the Clear Data option so much and it really breaks my flow.Robichaux
How to do it via Android Studio is discussed here: https://mcmap.net/q/152745/-android-studio-clear-application-data-for-instrumentation-test/905686.Egis
Specifically, do this: https://mcmap.net/q/152745/-android-studio-clear-application-data-for-instrumentation-testPulido
J
176

You can use the package-manager tool to clear data for installed apps (similar to pressing the 'clear data' button in the app settings on your device). So using adb you could do:

adb shell pm clear my.wonderful.app.package
Jobie answered 21/12, 2011 at 11:11 Comment(5)
On Android 2.1-update1, this unfortunately yields Error: unknown command 'clear'.Odette
@Palani: works for me for any version above 2.1-r1 (andoid-7). any error messages?Jobie
Above command connects to android shell and executes "pm clear my.wonderful.app.package" in android. In my device, "pm" command don't have "clear" option. Its nothing related with sdk. It depends on device firmware.Unsavory
m looking for clear data of browser(defaut)and chrome browser apps in android device programmaticaly from my android app.Please help for it..Depend
Doesn't work on every device, but it is wonderful for the devices that it works onAntiparallel
L
37

Following up to @edovino's answer, the way of clearing all of an application's preferences programmatically would be

private void clearPreferences() {
    try {
        // clearing app data
        Runtime runtime = Runtime.getRuntime();
        runtime.exec("pm clear YOUR_APP_PACKAGE_GOES HERE");

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Warning: the application will force close.

Lulalulea answered 5/5, 2014 at 10:34 Comment(4)
If you have any test code running after this, it fails.Utu
Does executing this require and permissions to be declared in the manifest?Gown
No, it does not require any special permission.Lulalulea
if I don't want to force close app then ?Tagalog
D
22

you can clear SharedPreferences app-data with this

Editor editor = 
context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();

and for clearing app db, this answer is correct -> Clearing Application database

Dorotheadorothee answered 20/6, 2011 at 23:9 Comment(0)
B
18

From API version 19 it is possible to call ActivityManager.clearApplicationUserData().

((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();
Behead answered 21/7, 2015 at 6:14 Comment(1)
Just FYI, calling this will terminate your app.Floruit
S
9

Check this code to:

@Override
protected void onDestroy() {
// closing Entire Application
    android.os.Process.killProcess(android.os.Process.myPid());
    Editor editor = getSharedPreferences("clear_cache", Context.MODE_PRIVATE).edit();
    editor.clear();
    editor.commit();
    trimCache(this);
    super.onDestroy();
}


public static void trimCache(Context context) {
    try {
        File dir = context.getCacheDir();
        if (dir != null && dir.isDirectory()) {
            deleteDir(dir);

        }
    } catch (Exception e) {
        // TODO: handle exception
    }
}


public static boolean deleteDir(File dir) {
    if (dir != null && dir.isDirectory()) {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
        }
    }

    // <uses-permission
    // android:name="android.permission.CLEAR_APP_CACHE"></uses-permission>
    // The directory is now empty so delete it

    return dir.delete();
}
Showpiece answered 14/10, 2011 at 6:11 Comment(0)
C
7

If you have just a couple of shared preferences to clear, then this solution is much nicer.

@Override
protected void setUp() throws Exception {
    super.setUp();
    Instrumentation instrumentation = getInstrumentation();
    SharedPreferences preferences = instrumentation.getTargetContext().getSharedPreferences(...), Context.MODE_PRIVATE);
    preferences.edit().clear().commit();
    solo = new Solo(instrumentation, getActivity());
}
Course answered 15/10, 2012 at 13:8 Comment(4)
Doesn't this require "instrumentation mode" to be enabled? What is that mode anyway?Linen
Yep, this requires an "instrumented" application, i.e. your test runs alongside your application code on a real device in process, which means that you can access all of your application's state and change it on run time for testing purposes.Course
what should be in (...) ?Sylvestersylvia
@Sylvestersylvia The name of the preferences file.Course
N
3

Using Context,We can clear app specific files like preference,database file. I have used below code for UI testing using Espresso.

    @Rule
    public ActivityTestRule<HomeActivity> mActivityRule = new ActivityTestRule<>(
            HomeActivity.class);

    public static void clearAppInfo() {
        Activity mActivity = testRule.getActivity();
        SharedPreferences prefs =
                PreferenceManager.getDefaultSharedPreferences(mActivity);
        prefs.edit().clear().commit();
        mActivity.deleteDatabase("app_db_name.db");
    }
Niggling answered 12/4, 2016 at 7:13 Comment(0)
J
2

if android version is above kitkat you may use this as well

public void onClick(View view) {

    Context context = getApplicationContext(); // add this line
    if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
        ((ActivityManager) context.getSystemService(ACTIVITY_SERVICE))
            .clearApplicationUserData();
        return;
    }
John answered 9/12, 2016 at 14:14 Comment(0)
J
1

What is the recommended way to get this done programmatically?

The only possible option is to run ADB command adb shell pm clear package before the test. The biggest problem is that it's kind of headache combining tests execution and shell commands.

However, we (at Mediafe) came with some solution that can work for you on regular unrooted device. All you need to do is to add an annotation. All the rest is done by running simple bash script.

Just add @ClearData annotation before ANY of your tests and tada 🎉, ADB clear command will be executed before the test execution.

This is an example of such test:

@Test
@ClearData
public void someTest() {
    // your test
}

The idea is as follows

  1. Read all tests by using adb shell am instrument -e log true
  2. Build execution plan by parsing the output from (1)
  3. Run the execution plan line by line

Using the same idea these are all options you can easily support:

  • Clear data
  • Clear notification bar
  • Parameterize
  • Filter and run by tags

Use only annotations. Like this:

@Test
@ClearData
@Tags(tags = {"sanity", "medium"})
@Parameterized.Repeat(count = 3)
public void myTest() throws Exception {
    String param = params[index];
    // ...
}

Bonus! 🎁 For each failed test:

  • Collect Logcat + stacktrace
  • Record video (mp4)
  • Dump DB (sqlite)
  • Dump default shared preferences (xml)
  • Collect dumpsys files like: battery, netstats and other.

In general, it's easy to add more options, since the tests are executed one by one from bash script rather than from gradle task.

📗 The full blog post: https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8

📘 The source code with examples: https://github.com/medisafe/run-android-tests

Hope this answers 6 years question ;)

Jungian answered 29/3, 2017 at 21:33 Comment(0)
A
0

This way added by Sebastiano was OK, but it's necessary, when you run tests from i.e. IntelliJ IDE to add:

 try {
    // clearing app data
    Runtime runtime = Runtime.getRuntime();
    runtime.exec("adb shell pm clear YOUR_APP_PACKAGE_GOES HERE");

}

instead of only "pm package..."

and more important: add it before driver.setCapability(App_package, package_name).

Ardatharde answered 17/9, 2020 at 7:57 Comment(1)
inside an app when using runtime.exec you cant write adb shell you just need to start from pm..Waldenburg

© 2022 - 2024 — McMap. All rights reserved.