Android 常见SD卡操作

中二病也要开发ANDROID 2018-04-08

Android 常见SD卡操作

[TOC]

参考

https://blog.csdn.net/mad1989/article/details/37568667.

【0.】 Environment 类SD卡相关方法

MethodDescription
getExternalStoragePublicDirectory(String type)获取指定类型的目录
getExternalStorageState()获取SD卡的状态
getExternalStorageDirectory()获取SD卡的根目录
getExternalStorageState(File path)获取指定文件的状态

【1.】 检测SD卡是否可用

String sdCardState = Environment.getExternalStorageState();
if (sdCardState.equals(Environment.MEDIA_MOUNTED)) {
    L.e("SD Card is available!");
} else {
    L.e("SD Card is unavailable!");
}

【2.】 获取SD卡的空间

/**
 * 获取SD卡的大小
 */
public void getSDCardSize(View view) {
    File sdCard = Environment.getExternalStorageDirectory();
    //获取SD卡的可用大小
    //sdCard.getFreeSpace();
    //getUsableSpace 要比getFreeSpace精确一些
    long lFree = sdCard.getUsableSpace();
    //获取SD开的总大小
    long totalSize = sdCard.getTotalSpace();
    //格式化,Formatter类,会自动地将大小转化为合适的单位
    String total = android.text.format.Formatter.formatFileSize(this, totalSize);
    String free = android.text.format.Formatter.formatFileSize(this, lFree);
    L.e(MessageFormat.format("Sad Card Info 【Total Size】= {0} 【Free Size】={1}", total, free));
}

【3.】 SD卡的操作权限

manifests 文件中加入SD权限

<!--写入SD卡权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

申请权限

private static final int WRITE_SD_CARD_REQUEST_CODE = ;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sdcard);

    int state = ActivityCompat.checkSelfPermission
            (this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (state != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(
                this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                WRITE_SD_CARD_REQUEST_CODE);
    }
}
//处理权限的申请结果
@Override
public void onRequestPermissionsResult
(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == WRITE_SD_CARD_REQUESTCODE) {
        //如果拒绝了权限,结束Activity
        if (grantResults[] != PackageManager.PERMISSION_GRANTED) {
            this.finish();
        } else {
            L.e("具有权限");
        }
    }
}

【4.】绕过权限访问向SD卡中写入数据

有时候,我们需要向SD卡中存储一些缓存数据,但是这时候如果申请读写SD卡权限的话似乎也不太必要,那么你可通过下面的这个方法向SD卡中写入数据。

文件的存储路径为: storage/sdcard/Android/data/应用程序包名/cache/

/**
 * 绕过权限先SD卡中写入数据
 */
public void writeCacheData(View view) throws IOException {
    //获得SD卡中写入
    //获取到本应用程序在SD卡中的的缓存目录
    File cacheFileDir = this.getExternalCacheDir();
    File file = new File(cacheFileDir, "temp.txt");
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    fileOutputStream.write("Hello World!".getBytes("UTF-8"));
    fileOutputStream.flush();
    fileOutputStream.close();

    //将刚刚写入的信息读取出来
    File readFile = new File(cacheFileDir, "temp.txt");
    FileInputStream fileInputStream = new FileInputStream(readFile);
    StringBuilder builder = new StringBuilder();

    int i;
    while ((i = fileInputStream.read()) != -)
        builder.append((char) i);
    L.e(builder.toString());

    fileInputStream.close();
}

【5.】向SD卡中写入数据

众所周知SD卡下面有许多不同的目录用来放置不同的类型的文件,比如说Download目录 ,Movies目录 等等。

我们可以通过Environment.getExternalStoragePublicDirectory(String type) 方法来获得不同的目录。

常见值如下:

ValueDescription
DIRECTORY_MUSIC音乐目录
DIRECTORY_RINGTONES铃声
DIRECTORY_ALARMS闹钟
DIRECTORY_NOTIFICATIONS通知
DIRECTORY_PICTURES照片
DIRECTORY_MOVIES电影
DIRECTORY_DOWNLOADS下载
.........

一个Demo,将照片保存到SD卡中

/**
 * 向SD卡中写入数据
 */
public void writeImageIntoSDCard(View view) throws IOException {
    //获取SD卡Picture路径
    File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File petFile = new File(picDir, "pet3.jpg");

    //写入照片
    FileOutputStream fileOutputStream = new FileOutputStream(petFile);
    Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.pet3);
    bitmap.compress(Bitmap.CompressFormat.JPEG, , fileOutputStream);

    fileOutputStream.flush();
    fileOutputStream.close();
    
    //如果仅仅是上面的代码是无法在图库中看到的,所以我们需要发送一个广播让系统来扫描SD卡
    this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(petFile)));
}

【6.】 从SD卡中读取数据

我想写入SD卡都会了的话,读取就更不是问题了,但是为了例子的完整性,还是写一个简单的例子吧。 将我们写入SD卡中的图片读取出来.

/**
 * 从SD卡中读取图片
 */
public void readImageFromSDCard(View view) {
    File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File petFile = new File(picDir, "pet3.jpg");
    Bitmap bitmap = BitmapFactory.decodeFile(petFile.getPath());
    mPetIV.setImageBitmap(bitmap);
}

相关推荐