计算缓存大小并且清空缓存 && Android存储访问及目录


Android的外部存储

  Android支持外部存储(case-insensitive filesystem with immutable POSIX permission classes and modes)。

  外部存储可以通过物理介质提供(如SD卡),也可以通过将内部存储中的一部分封装而成,设备可以有多个外部存储实例。

 

访问外部存储的权限

  从Android 1.0开始,写操作受权限WRITE_EXTERNAL_STORAGE保护。

  从Android 4.1开始,读操作受权限READ_EXTERNAL_STORAGE保护。

  从Android 4.4开始,应用可以管理在它外部存储上的特定包名目录,而不用获取WRITE_EXTERNAL_STORAGE权限。

  比如,一个包名为com.example.foo的应用,可以自由访问外存上的Android/data/com.example.foo/目录。

 

  外部存储对数据提供的保护较少,所以系统不应该存储敏感数据在外部存储上。

  特别地,配置和log文件应该存储在内部存储中,这样它们可以被有效地保护。

 

  对于多用户的情况,一般每个用户都会有自己独立的外部存储,应用仅对当前用户的外部存储有访问权限。

 

Environment API的目录

  getDataDirectory():用户数据目录。

  getDownloadCacheDirectory():下载缓存内容目录。

 

  getExternalStorageDirectory():主要的外部存储目录。

  但是这个目录很可能当前不能访问,比如这个目录被用户的PC挂载,或者从设备中移除,或者其他问题发生,你可以通过getExternalStorageState()来获取当前状态。

  还有多用户或者多外部存储的情况,此文不再讨论。

 

  为了不污染用户的根命名空间,一般不会直接使用这个外部存储的根目录。

  任何应用私有的文件的应该被放置在 Context.getExternalFilesDir返回的目录下,在应用被卸载的时候,系统会清理的就是这个目录。

  另一些共享文件应该被放置在 getExternalStoragePublicDirectory(String)返回的目录中。

  写这个路径需要 WRITE_EXTERNAL_STORAGE权限,读需要 READ_EXTERNAL_STORAGE权限,当然写权限默认包含了读权限。

 

  KITKAT 即Android 4.4开始,如果你的应用只是需要存储一些内部数据,可以考虑使用 :

  getExternalFilesDir(String)或者getExternalCacheDir(),它们不需要获取权限。

 

  getExternalStoragePublicDirectory(String type)这个方法接收一个参数,表明目录所放的文件的类型,传入的参数是Environment类中的DIRECTORY_XXX静态变量,比如DIRECTORY_DCIM等。

  注意:传入的类型参数不能是null,返回的目录路径有可能不存在,所以必须在使用之前确认一下,比如使用File.mkdirs创建该路径。

 

  getRootDirectory()得到Android的根目录。

  isExternalStorageEmulated()设备的外存是否是用内存模拟的,是则返回true。(API Level 11)

  isExternalStorageRemovable()设备的外存是否是可以拆卸的,比如SD卡,是则返回true。(API Level 9)

 

Context API中的目录

  getExternalFilesDir(String type)是应用在外部存储上的目录。

  和Environment类的getExternalStoragePublicDirectory(String type)方法类似,返回包含参数指定的特定类型文件的子目录。

  getExternalCacheDir()是应用的在外部存储上的缓存目录。

 

   从Android 4.4这两个方法不需要读写权限,是针对于本应用来说,如果要访问其他应用的相关目录,还是需要声明读写权限。

  Android 4.4之前的版本要访问的话还是要声明读写权限的,如果没有在manifest中写权限,上面两个get方法都会返回null。

 

  与上面两个方法形成对比的是下面两个方法:

  getFilesDir() 

  getCacheDir()

  这两个方法得到的是内存上的目录。

 

  这些目录都是属于应用的,当应用被卸载的时候,里面的内容都会被移除,但是不要依赖于系统的操作。


getCacheDir()方法用于获取/data/data/<applicationpackage>/cache目录 (应用缓存)

getFilesDir()方法用于获取/data/data/<applicationpackage>/files目录

//下面两个方法是否能够在程序被卸载时被删除与API的等级有关

Context.getExternalFilesDir()方法可以获取到SDCard/Android/data/你的应用的包名/files/目录,一般放一些长时间保存的数据

Context.getExternalCacheDir()方法可以获取到SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据

 

/data/data/package_name/database/webview.db*WebView缓存)

/data/data/package_name/database/webviewCache.db*WebView缓存)

public class utils {

   /**
    * 缓存大小
    * @param context
    * @return
    * @throws Exception
    */
   public static String getTotalCacheSize(Context context) throws Exception {
      long cacheSize = getFolderSize(context.getCacheDir());
      if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
         cacheSize += getFolderSize(context.getExternalCacheDir());
      }
      return getFormatSize(cacheSize);
   }

   /**
    * 清空缓存
    * @param context
    */
   public static void clearAllCache(Context context) {
      UtilsLog.d();
      /**
       * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache)
       */
      //这样
      deleteDir(context.getCacheDir());
      //这样 本应用数据清除
      deleteDir(new File("/data/data/"+context.getPackageName()+"/cache"));//

      /**
       * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases)
       */
      //还可以这样
      deleteDir(new File("/data/data/"+context.getPackageName()+"/databases"));//

      /**
       * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs)
       */
      deleteDir(new File("/data/data/"+context.getPackageName()+"/shared_prefs"));//

      /**
       * 清除/data/data/com.xxx.xxx/files
       */
      deleteDir(context.getFilesDir());
      deleteDir(new File("/data/data/"+context.getPackageName()+"/files"));//

      /**
       *   mnt/sdcard/android/data/com.xxx.xxx/
       */
      deleteDir(new File(Constant.LOCAL_URL));

      UtilsLog.d();
      if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
         /**
          * mnt/sdcard/android/data/com.xxx.xxx/cache
          */
         deleteDir(context.getExternalCacheDir());
      }
   }

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

   // 获取文件
   // Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/
   // 目录,一般放一些长时间保存的数据
   // Context.getExternalCacheDir() -->
   // SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
   public static long getFolderSize(File file) throws Exception {
      long size = 0;
      try {
         File[] fileList = file.listFiles();
         for (int i = 0; i < fileList.length; i++) {
            // 如果下面还有文件
            if (fileList[i].isDirectory()) {
               size = size + getFolderSize(fileList[i]);
            } else {
               size = size + fileList[i].length();
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
      return size;
   }

   /**
    * 格式化单位
    * 
    * @param size
    * @return
    */
   public static String getFormatSize(double size) {
      double kiloByte = size / 1024;
      if (kiloByte < 1) {
         // return size + "Byte";
         return "0K";
      }

      double megaByte = kiloByte / 1024;
      if (megaByte < 1) {
         BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
         return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
      }

      double gigaByte = megaByte / 1024;
      if (gigaByte < 1) {
         BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
         return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
      }

      double teraBytes = gigaByte / 1024;
      if (teraBytes < 1) {
         BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
         return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
      }
      BigDecimal result4 = new BigDecimal(teraBytes);
      return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
   }
}


参考

http://www.2cto.com/kf/201503/385492.html


http://www.cnblogs.com/rayray/p/3413673.html


http://www.cnblogs.com/mengdd/p/3742623.html






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值