Android 储存系统--使用相机拍照保存到文件

本文从启动相机拍照并保存为头像的例子出发,探讨Android的存储系统。介绍了内部存储(Internal Storage)和外部存储(External Storage)的使用,包括文件的私有性和可访问性。当应用卸载时,这些文件会随之删除。同时,讨论了如何保存公共文件到外部存储,这些文件不会被系统自动删除。文章引用了权威指南和博客资源,提供了深入的存储知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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类提供的基本文件和目录处理方法

MethodPurpose
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所访问。
    • 在应用被卸载时,这些文件会被系统删除
  2. External Storage
    • 使用表格 2中的方法保存在 External Storage 上的文件保存在[/storage/emulated/0/Android/data/com.example.app/files/xxx]下
    • 同样在应用被卸载时,这些文件会被系统删除
  3. 文件储存为 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存储挖坑记–>清晰详细的储存详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值