1. 先从一个例子说起:使用隐式 Intent 启动相机拍照保存为头像:

final Intent captureImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // 检查相机是否可用
        boolean canTakePhoto = mPhotoFile != null &&
                captureImage.resolveActivity(packageManager) != null;
        if (canTakePhoto) {
            Uri uri = Uri.fromFile(mPhotoFile);
            // 把拍到的照片保存地址的 url 传入 Intent
            captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
mPhotoButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivityForResult(captureImage, REQUEST_PHOTO);
            }
        });
public File getPhotoFile(Crime crime) {
        // 保存到 External Storage 中
        File externalFileDir = mContext
                .getExternalFilesDir(Environment.DIRECTORY_PICTURES);

        if (externalFileDir == null) {
            return null;
        }

        return new File(externalFileDir, crime.getPhotoFileName());
}

public String getPhotoFileName() {
        return "IMG_" + getId().toString() + ".jpg";
}
// 回调时设置已经储存的图片
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        if (REQUEST_DATE == requestCode) {
            updateDate();
        } else if (REQUEST_CONTACT == requestCode && data != null) {
            mCrime.setSuspect(suspect);
            mSuspectButton.setText(suspect);
        } else if (requestCode == REQUEST_PHOTO) {
            updatePhotoView();
        }
    }

2. 由此引申的 Android 储存系统的知识点:

表格 1:Context类提供的基本文件和目录处理方法

Method

Purpose

File getFilesDir()

获取/data/data//files目录

FileInputStream openFileInput(String name)

打开现有文件进行读取

FileOutputStream openFileOutput(String name, int mode)

打开文件进行写入,如不存在就创建它

File getDir(String name, int mode)

获取/data/data//目录的子目录(如不存在就先创 建它)

String[] fileList()

获取/data/data//files目录下的文件列表。可与其他方 法配合使用,例如openFileInput(String)

File getCacheDir()

获取/data/data//cache目录。应注意及时清理该目 录,并节约使用空间

表格 2:Context类提供的外部文件和目录处理方法

方 法

使 用 目 的

File getExternalCacheDir()

获取主外部存储上的缓存文件目录。用法类似getCacheDir()方法,但要 注意, Android一般不会自动清理该目录

File[] getExternalCacheDirs()

获取多个外部存储上的缓存文件目录

File getExternalFilesDir(String)

获取主外部存储上存放常规文件的文件目录。通过String参数,可访问特 定内容类型的子目录。内容类型常量以DIRECTORY_为前缀,定义在 Environment 中 。 例 如 , 用 于 图 像 文 件 的 Environment.DIRECTORY_ PICTURES

File[] getExternalFilesDirs(String)

类似getExternalFilesDir(String)方法,但该方法可获取指定类型的 所有文件目录

File[] getExternalMediaDirs()

获 取 Android存储 图片 、视 频和 音乐 文件 的所 有外 部文 件目 录。和 getExternalFilesDir(Environment.DIRECTORY_PICTURES)方法区别 在于,调用该方法,多媒体扫描器会自动扫描目标目录,并将存放的多媒 体文件暴露给能够播放音乐、浏览视频和图片的应用。也就是说, getExternalMediaDirs()方法返回目录中存放的任何文件都会自动出现 在多媒体应用中

手机的储存分为 Internal Storage 和 External Storage(主存储路径/storage/emulated/0)两种,如果再加上一张 sd 卡,也就多出来了一个 External Storage(副储存路径/storage/emulated/1)
  1. Internal Storage
  • 使用表格 1中的方法保存在 Interal Storage 上的文件以 app 的包名作为标识存放在 Android 文件系统的特定目录下[/data/data/com.example.xx];
  • 从技术上讲,如果文件被设置为可读的,那么其他 app 就可以读取该 internal 文件。然而,其他 app 需要知道包名与文件名。若没有设置为可读或者可写,其他app是没有办法读写的。因此我们只要使用了MODE_PRIVATE ,那么这些文件就不可能被其他app所访问。
  • 在应用被卸载时,这些文件会被系统删除
  1. External Storage
  • 使用表格 2中的方法保存在 External Storage 上的文件保存在[/storage/emulated/0/Android/data/com.example.app/files/xxx]下
  • 同样在应用被卸载时,这些文件会被系统删除
  1. 文件储存为 public 文件
  • 同样是保存在 External Storage 上的文件
  • 使用Environment.getExternalStoragePublicDirectory()得到的目录是[/storage/emulated/0],此处保存的文件永远不会被系统删除
    补充:使用 External Storage 前要先检查其状态
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

参考–>《Android 编程权威指南》,AllenWang的个人博客–>关于储存的详解保存到文件–Trainiing
拓展–>Android存储挖坑记–>清晰详细的储存详解