android开发中获取手机上可用SD卡方法分享

现在的android手机型号复杂多样,造成了开发过程中使用官方的获取sd卡的方法在部分的手机上并不适用,所以需要进行开发的自己封装,以下就是代码,希望分享出来,大家共同学习

/**
* 获取手机sd卡的工具类
* @author wy
*/
public class SDCardUtils {
/*
* avoid initializations of tool classes
*/
private SDCardUtils() {
// TODO Auto-generated constructor stub
}

/**
* @Title: getExtSDCardPaths
* @Description: to obtain storage paths, the first path is theoretically
* the returned value of
* Environment.getExternalStorageDirectory(), namely the
* primary external storage. It can be the storage of internal
* device, or that of external sdcard. If paths.size() >1,
* basically, the current device contains two type of storage:
* one is the storage of the device itself, one is that of
* external sdcard. Additionally, the paths is directory.
* @return List<String>
* @throws IOException
* 获取手机上所有可用的sd卡路径
* @return
*/
public static ArrayList<String> getExtSDCardPaths() {
ArrayList<String> paths = new ArrayList<String>();
String extFileStatus = Environment.getExternalStorageState();
File extFile = Environment.getExternalStorageDirectory();
if (extFileStatus.equals(Environment.MEDIA_MOUNTED) && extFile.exists()
&& extFile.isDirectory()) {
paths.add(extFile.getAbsolutePath());
}
try {
// obtain executed result of command line code of 'mount', to judge
// whether tfCard exists by the result
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("mount");
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
int mountPathIndex = 1;
while ((line = br.readLine()) != null) {
// format of sdcard file system: vfat/fuse
if ((!line.contains("fat") && !line.contains("fuse") && !line
.contains("storage"))
|| line.contains("secure")
|| line.contains("asec")
|| line.contains("firmware")
|| line.contains("shell")
|| line.contains("obb")
|| line.contains("legacy") || line.contains("data")) {
continue;
}
String[] parts = line.split(" ");
int length = parts.length;
if (mountPathIndex >= length) {
continue;
}
String mountPath = parts[mountPathIndex];
if (!mountPath.contains("/") || mountPath.contains("data")
|| mountPath.contains("Data")) {
continue;
}
File mountRoot = new File(mountPath);
if (!mountRoot.exists() || !mountRoot.isDirectory()) {
continue;
}
boolean equalsToPrimarySD = mountPath.equals(extFile
.getAbsolutePath());
if (equalsToPrimarySD) {
continue;
}
paths.add(mountPath);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return paths;
}

/**
* SD卡剩余空间大小
* @param path 取得SD卡文件路径
* @return 单位MB
*/
public static long getSDFreeSize(String path) {
StatFs sf = new StatFs(path);
// 获取单个数据块的大小(Byte)
long blockSize = sf.getBlockSize();
// 空闲的数据块的数量
long freeBlocks = sf.getAvailableBlocks();
// 返回SD卡空闲大小
return (freeBlocks * blockSize) / 1024 / 1024; //
}

/**
* SD卡总容量
* @param path 取得SD卡文件路径
* @return 单位MB
*/
public static long getSDAllSize(String path) {
StatFs sf = new StatFs(path);
// 获取单个数据块的大小(Byte)
long blockSize = sf.getBlockSize();
// 获取所有数据块数
long allBlocks = sf.getBlockCount();
// 返回SD卡大小
// return allBlocks * blockSize; //单位Byte
// return (allBlocks * blockSize)/1024; //单位KB
return (allBlocks * blockSize) / 1024 / 1024;
}

/**
* 判断当前内存卡是否可用
* @param mContext
* @return
*/
public static final boolean isExist(String sdPath) {
ArrayList<String> list = getExtSDCardPaths();
for (int i = 0; i < list.size(); i++) {
if(list.contains(sdPath)) {
return true;
}
}
return false;
}
}

Android手机外置SD卡(TF卡)的获取方法

    Android手机上的外置SD卡,起初的时候,即在Android出世的前几年,那时手机的存储是十分有限的,不像现在到处可见16G、32G和64G的存储,因而那时候的手机有的厂商允许插入外置的SD卡,此时这张卡仍处于手机的扩展部分。后来,随着手机的发展以及存储能力的增加,这张外置SD卡,逐渐成为了手机的一部分,不再允许可挺拔了,当然现在依然有的手机允许对存储进行拓展,比如三星等。

    那张拓展的存储卡,现在叫做TF卡,且不是所有的手机都支持它,但是有时候有些奇葩需求偏要优先存储在TF卡里面,这叫不得不要求开发人员去检查这张卡是否存在、是否可用。又因为这是手机厂商可拓展、可自定义的部分,所有不同厂商生产的手机,以及同一厂商生产的不同型号的手机,TF卡的位置都相差很大,并没有一个统一的名称或位置。因而这是比较困难的一部分,但是还好Android是开源的,我们可以通过运行时来判断手机是否有TF卡,以及TF卡是否可用。

    下面这个方法可以获取手机的可以存储,包括SD卡、TF卡等,对多存储卡进行了匹配,详细的代码如下:

     1 public class SDCardScanner {
     2     /*
     3      * avoid initializations of tool classes
     4      */
     5     private SDCardScanner() {
     6     }
     7
     8     /**
     9      * @Title: getExtSDCardPaths
    10      * @Description: to obtain storage paths, the first path is theoretically
    11      *               the returned value of
    12      *               Environment.getExternalStorageDirectory(), namely the
    13      *               primary external storage. It can be the storage of internal
    14      *               device, or that of external sdcard. If paths.size() >1,
    15      *               basically, the current device contains two type of storage:
    16      *               one is the storage of the device itself, one is that of
    17      *               external sdcard. Additionally, the paths is directory.
    18      * @return List<String>
    19      * @throws IOException
    20      */
    21     public static List<String> getExtSDCardPaths() {
    22         List<String> paths = new ArrayList<String>();
    23         String extFileStatus = Environment.getExternalStorageState();
    24         File extFile = Environment.getExternalStorageDirectory();
    25         if (extFileStatus.endsWith(Environment.MEDIA_UNMOUNTED)
    26                 && extFile.exists() && extFile.isDirectory()
    27                 && extFile.canWrite()) {
    28             paths.add(extFile.getAbsolutePath());
    29         }
    30         try {
    31             // obtain executed result of command line code of 'mount', to judge
    32             // whether tfCard exists by the result
    33             Runtime runtime = Runtime.getRuntime();
    34             Process process = runtime.exec('mount');
    35             InputStream is = process.getInputStream();
    36             InputStreamReader isr = new InputStreamReader(is);
    37             BufferedReader br = new BufferedReader(isr);
    38             String line = null;
    39             int mountPathIndex = 1;
    40             while ((line = br.readLine()) != null) {
    41                 // format of sdcard file system: vfat/fuse
    42                 if ((!line.contains('fat') && !line.contains('fuse') && !line
    43                         .contains('storage'))
    44                         || line.contains('secure')
    45                         || line.contains('asec')
    46                         || line.contains('firmware')
    47                         || line.contains('shell')
    48                         || line.contains('obb')
    49                         || line.contains('legacy') || line.contains('data')) {
    50                     continue;
    51                 }
    52                 String[] parts = line.split(' ');
    53                 int length = parts.length;
    54                 if (mountPathIndex >= length) {
    55                     continue;
    56                 }
    57                 String mountPath = parts[mountPathIndex];
    58                 if (!mountPath.contains('/') || mountPath.contains('data')
    59                         || mountPath.contains('Data')) {
    60                     continue;
    61                 }
    62                 File mountRoot = new File(mountPath);
    63                 if (!mountRoot.exists() || !mountRoot.isDirectory()
    64                         || !mountRoot.canWrite()) {
    65                     continue;
    66                 }
    67                 boolean equalsToPrimarySD = mountPath.equals(extFile
    68                         .getAbsolutePath());
    69                 if (equalsToPrimarySD) {
    70                     continue;
    71                 }
    72                 paths.add(mountPath);
    73             }
    74         } catch (IOException e) {
    75             // TODO Auto-generated catch block
    76             e.printStackTrace();
    77         }
    78         return paths;
    79     }
    80 }

    首先,我把它写成了一个工具类,因而声明了一个私有的构造器,目的就是要防止该类被实例化。

    然后,首先获取了Android标准一部分的外置SD卡,如果它可用的话。

    然后利用运行时,通过命令行函数'mount'来获取所有的存储位置,并对返回的结果进行SD卡或者TF卡的查找。

    最后返回了所有可用于存储的不同的卡的位置,用一个List来保存。由于不是所有的手机都支持TF卡,因而这个List包含的路径未必很多,只有一个SD卡的手机只会返回一个路径,多个可用存储位置的会返回多个路径。

    但有一点,是必须的,paths.get(0)肯定是外置SD卡的位置,因为它是primary external storage.

时间: 2024-08-31 11:39:50

android开发中获取手机上可用SD卡方法分享的相关文章

android开发中获取手机分辨率大小的方法_Android

所以,记录下核心代码: 复制代码 代码如下: DisplayMetrics metrics=new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics); 获取到本机的分辨率: 复制代码 代码如下: int widthPixels=metrics.widthPixels;int heightPixels=metrics.heightPixels; 当然,可以直接用TextView显示出来,还可以直接

android开发中获取手机分辨率大小的方法

所以,记录下核心代码: 复制代码 代码如下:DisplayMetrics metrics=new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics); 获取到本机的分辨率:复制代码 代码如下:int widthPixels=metrics.widthPixels;int heightPixels=metrics.heightPixels; 当然,可以直接用TextView显示出来,还可以直接去运用

Android开发中在TableView上添加悬浮按钮的方法_Android

如果直接在TableVIewController上贴Button的话会导致这个会随之滚动,下面解决在TableView上实现位置固定悬浮按钮的两种方法: 1.在view上贴tableView,然后将悬浮按钮贴在view的最顶层 2.使用window 首先看一下最终的效果,在tableViewController上添加一个悬浮按钮,该按钮不能随着视图的滚动而滚动 首先介绍上面的第一种方法: 1)创建tableview和底部按钮的属性 //屏幕宽 #define kScreenW [UIScreen

Android开发中在TableView上添加悬浮按钮的方法

如果直接在TableVIewController上贴Button的话会导致这个会随之滚动,下面解决在TableView上实现位置固定悬浮按钮的两种方法: 1.在view上贴tableView,然后将悬浮按钮贴在view的最顶层 2.使用window 首先看一下最终的效果,在tableViewController上添加一个悬浮按钮,该按钮不能随着视图的滚动而滚动 首先介绍上面的第一种方法: 1)创建tableview和底部按钮的属性 //屏幕宽 #define kScreenW [UIScreen

Android开发中获取View视图宽与高的常用方法小结

本文实例讲述了Android开发中获取View视图宽与高的常用方法.分享给大家供大家参考,具体如下: 一.根据WindowManager管理器获得 1)这两种方法在屏幕未显示的时候,还是处于0的状态,即要在setContentView调用之后才有效. 2)Activity必须如此设置才能获得view的宽高 //设置为无标题 requestWindowFeature(Window.FEATURE_NO_TITLE); //设置为全屏模式getWindow().setFlags(WindowMana

Android开发中Eclipse报错及对应处理方法总结_Android

本文较为详细的总结了Android开发中Eclipse报错及对应处理方法.分享给大家供大家参考,具体如下: 报错1: Conversion to Dalvik format failed with error 1 报错原因:原因是我在android工程中不小心多导入Java的mina,结果一跑程序就报这个错误. 解决方法:将Java中用到的mina包移除,就OK了. 小结:以后遇到这种报错时,记得提醒自己可能是由于自己导错包了. 附: 网上其他处理方法:<丢失Android系统库或者Conver

如何将为Android开发的AIR应用转移到SD卡

如果你想用户能够将为Android开发的AIR应用转移到SD卡上,所需要做的是在你的应用程序描述符中修改一下.如果你想你的应用程序默认安装到内置存储器中,但是允许用户把它转移到SD卡上,设置android:installLocation 为"auto": <android>      <manifestAdditions>          <![CDATA[              <manifest android:installLocatio

Android开发中听筒无法播放音乐的解决方法_Android

本文实例讲述了Android开发中听筒无法播放音乐的解决方法.分享给大家供大家参考,具体如下: 这个问题让我蛋疼了,既然百度也木有资料. 耗时的主要原因是因为权限不足时,而没有终止程序,只用了一小行日志提醒,没有看到 用听筒播放很简单 AudioManager.setMode(AudioManager.MODE_IN_CALL) //设定为通话中即可 还是这一句代码的事,不过记得要加上权限 Android.permission.MODIFY_AUDIO_SETTINGS 不然会像我一样蛋疼半天

Android开发中Listview动态加载数据的方法示例

本文实例讲述了Android开发中Listview动态加载数据的方法.分享给大家供大家参考,具体如下: 最近在研究网络数据加载的问题,比如我有几百,甚至上千条数据,这些数据如果一次性全部加载到arraylist,然后再加载到Listview中.我们必然会去单独开线程来做,这样造成的结果就是会出现等待时间很长,用户体验非常不好.我的想法是动态加载数据,第一次加载十条,然后往下面滑动的时候再追加十条,再往下面滑动的时候再去追加,这样大大减少了用户等待的时间,同时给处理数据留下了时间.网上看到了这样一