【问题标题】:Clear Application's Data Programmatically以编程方式清除应用程序的数据
【发布时间】:2011-05-26 05:32:50
【问题描述】:

我想以编程方式清除应用程序的数据。

应用程序的数据可能包含数据库、共享首选项、内部-外部文件或在应用程序中创建的任何其他文件。

我知道我们可以通过以下方式清除移动设备中的数据:

设置->应用程序->管理应用程序->我的应用程序->清除 数据

但是我需要通过一个Android程序来做以上事情吗?

【问题讨论】:

    标签: android


    【解决方案1】:

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

    如果您不想要这种骇人听闻的方式,您还可以隐藏 UI 上的按钮,这样旧手机就无法使用该功能。

    使用android:manageSpaceActivity 的任何人都必须了解此方法。


    每当我使用它时,我都会从具有android:process=":manager"manageSpaceActivity 执行此操作。在那里,我手动终止了我的应用程序的所有 其他 进程。这让我可以让 UI 保持运行并让用户决定下一步去哪里。

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

    【讨论】:

    • 对我来说 .clearApplicationUserData();也是强制关闭应用程序。
    • 它必须终止应用程序,否则它所持有的数据可能会被写回。执行此操作的唯一安全方法是 (1) 终止应用程序,(2) 清除其所有数据,(3) 应用程序下次启动时,它将在没有数据的情况下重新启动。
    • 嗨@TWiStErRob 我想在我的应用程序中单击注销按钮时实现此方法。但它强制关闭应用程序。相反,我想在存在注册/登录表单的地方开始主要活动。这怎么可能?
    • 对于 KitKat 之前的版本,请参阅此答案:stackoverflow.com/a/23470355/3256989
    • 应用此代码后是否可以开始任何其他活动
    【解决方案2】:

    我只是将来自the link ihrupin posted 的教程放在这篇文章中。

    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()。 onClickListener 中的 clearApplicationData()

    更新: 您的SharedPreferences 实例可能会保留您的数据并在您删除它后重新创建首选项文件。所以你会想要得到你的SharedPreferences 对象和

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

    更新:

    如果您尚未将android:name="your.package.MyApplication" 添加到AndroidManifest.xml 中的application tag,则需要这样做。否则,MyApplication.getInstance() 返回 null,导致 NullPointerException

    【讨论】:

    • 保重!您删除了应用程序文件夹中的所有内容,包括共享首选项.. 不仅是缓存目录本身及其内容。
    • 我已经实现了这个解决方案。但是我的应用程序数据没有被清除,只有缓存被清除.. 5 MB 仍然剩余.. 还有其他解决方案吗?请帮帮我:(
    • @MinceMan 请注意,这必须写在扩展应用程序的类中以获得更好的效果
    • 是的,它删除了所有文件,但应用程序没有意识到它,所以我仍然可以是应用程序目录上的文件。从最近的应用程序中删除应用程序并启动它后,应用程序实现了清除。我试图重新创建活动,但它不起作用
    • 为什么'lib'目录没有被删除?
    【解决方案3】:

    结合来自 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();
        } 
    }
    

    【讨论】:

    • 无论安卓版本如何,这是否适用于所有安卓设备?对我来说,它适用于我拥有的所有 3 台 Android 设备(包括 Lollipop、Marshmallow 和 Pie)
    • 是的 if else 等于或小于 kit kat ...使用 clearApplicationUserData 及以上它使用 runtime.exce ...基本上是一个 shell 命令 ...除了权限之外非常可靠...它应该可以工作......
    【解决方案4】:

    最简单的方法是

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

    这将清除数据并从内存中删除您的应用。相当于下面的清除数据选项 设置 --> 应用程序管理器 --> 你的应用程序 --> 清除数据

    【讨论】:

    • 我不会推荐这种方法。使用可能不存在的命令行程序(例如,pm)是有风险的。它们不是 Android SDK“合同”的一部分,因此它们是否存在于给定设备上,或者它们的行为是否与其他设备上的行为相同,取决​​于制造商和自定义 ROM 开发人员。
    • 作为替代方案,我还有一个选项,即 ((ActivityManager)context.getSystemService(ACTIVITY_SERVICE)) .clearApplicationUserData();但它有一个限制,它只能在 API 级别 >=19 工作,您能在此处提供替代方案吗?或者可能是另一种选择。
    【解决方案5】:

    我随处使用的东西:

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

    执行上述代码会关闭应用程序并删除所有数据库和共享首选项

    【讨论】:

      【解决方案6】:

      如果你想要一个不那么冗长的 hack:

      void deleteDirectory(String path) {
        Runtime.getRuntime().exec(String.format("rm -rf %s", path));
      }
      

      【讨论】:

      • 您可能需要引用该路径以防它包含空格和内容。
      【解决方案7】:

      试试这个代码

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

      【讨论】:

        猜你喜欢
        • 2014-06-22
        • 1970-01-01
        • 2011-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-07
        • 2014-07-21
        相关资源
        最近更新 更多