Android数据存储之文件存储

原创 2016年08月31日 16:53:55

内部存储和外部存储的概念

所有Android设备都有两个存储:”内部”和”外部”存储。早期Android设备的内部存储指的是内置的不可移除的内存,外部存储指的是sd card,也就是可移除存储。后来一些设备将内置存储划分为”内部”和”外部”分区,所以即便没有sd card这样的可移除存储,也始终有两个存储空间,并且无论外部存储是否可移除,API行为均一致。

内外部存储的实际路径

那么现在我们可以把存储分为三类:内部存储、不可移除的外部存储(内置内存划分的)、可移除外部存储(sd card)。
而外部存储保存的文件又分为两类:公有文件,私有文件。

内部存储目录:由 Context.getFilesDir() 获得,路径为 /data/data/com.example.capturephotodemo/files

内部存储缓存目录:由 Context.getCacheDir() 获得,路径为 /data/data/com.example.capturephotodemo/cache

外部存储私有文件存储目录:Context.getExternalFilesDir(String type)获得,传入 null 就是获取根目录 /storage/emulated/0/Android/data/com.example.capturephotodemo/files。如果传入 Environment.DIRECTORY_PICTURES,路径为 /storage/emulated/0/Android/data/com.example.capturephotodemo/files/Pictures

外部存储私公有文件目录(这里是由Environment获取,不是Context):Environment.getExternalStorageDirectory()获取是公有文件存储的根目录 /storage/emulated/0。Environment.getExternalStoragePublicDirectory(String type) 如果传入Environment.DIRECTORY_PICTURES,目录为/storage/emulated/0/Pictures

内外部存储区别

内部存储:始终可用,默认情况下只有当前应用可访问,用户卸载应用时,内部存储文件全部删除
外部存储:分为可移除和不可移除的,全局可读,不过当用户卸载应用时,只有私有文件(Context.getExternalFilesDir(String type),如下载的音频)会被删除,公有文件(Environment.getExternalStorageDirectory()或Environment.getExternalStoragePublicDirectory(String type),如拍照)不会被删除。

权限

写权限包含默认包含读的权限,不过一般为了版本兼容,必要时候还是加上读权限

    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="18" /> 

保存文件到内部存储

先看下效果,点击Button后,会在ImageView中加载Internal Storage中的保存的图片,然后会把这个图片发送出去。
这里写图片描述

先创建图片

private void createInternalFile() {
    //在内部存储创建 images/ 目录
    File imagesDir = new File(getFilesDir(), shareDir);
    //在images/目录下创建文件
    internalFile = new File(imagesDir, "launcher.png");
    //打开文件的输出流
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(internalFile);
        //获取bitmap对象
        Bitmap launcherIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.star);
        //把bitmap对象压缩到输出流中
        boolean isCompressed = launcherIcon.compress(Bitmap.CompressFormat.PNG, 100, fos);
        if (!isCompressed) {
            Log.e("david", "Failed to compress");
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

发送并加载

public void shareInternalFile(View view) {
    createInternalFile();

    //把文件以uri形式分享出去
    Uri uri = FileProvider.getUriForFile(this, AUTHORITY, internalFile);
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    shareIntent.setType("image/png");
    startActivity(Intent.createChooser(shareIntent,"Send Image"));

    //加载内部存储的文件,显示到ImageView中
    Bitmap bitmap = BitmapFactory.decodeFile(internalFile.getAbsolutePath());
    mImageView.setImageBitmap(bitmap);
}

既然内部存储只有本应用可以访问,那么接收图片的应用为何有权限访问这个图片。因为这里用了FileProvider,它赋予了Uri的临时权限

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.ckt.savingfile.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths"/>
</provider>

实际情况中,可能我要发送多张图片

ArrayList<Uri> imageUris = new ArrayList<Uri>();
imageUris.add(imageUri1); // Add your image URIs here
imageUris.add(imageUri2);

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, "Share images to.."));

保存文件到外部存储

因为外部存储可能不存在,所以总是要先检查存在性。

/**
 * 检查外部存储是否挂载
 */
private boolean isExternalStorageAvailable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

然后写入文件

private void createExternalFile() {
    if (isExternalStorageAvailable()) {
        //创建外部存储的私有文件目录
        File picDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        //在私有文件目录下创建文件
        externalFile = new File(picDir, "panda.jpg");
        //打开文件的输出流
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(externalFile);
            //获取bitmap对象
            Bitmap launcherIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.panda);
            //把bitmap对象压缩到输出流中
            boolean isCompressed = launcherIcon.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            if (!isCompressed) {
                Log.e("david", "Failed to compress");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

最后发送出去

    public void shareInternalFile(View view) {
        createExternalFile();
        Uri uri = Uri.fromFile(externalFile);
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_STREAM, uri);
        intent.setType("image/*");
        startActivity(intent);
    }

这里我并没有通过FileProvier生成Uri,因为外部存储的文件其它应用都是可以访问的,所以我们只需要知道这个文件的路径就行,这里我们用一个Uri告知其它应用这个文件的路径。
最后我还是上一个图,让大家看到效果,并用图的最后,我们会看到内部私有文件到底存放在哪里

这里写图片描述

删除文件

当用户卸载app时候,系统会删除以下各项:
1. 内部存储中的所以文件
2. 用getExternalFilesDir()保存的外部存储的文件
但是,我们还是要自己定期删除用 getCacheDir() 创建的缓存文件。

删除文件最直接的方法就是 myFile.delete(),如果文件保存在内部存储中,可以用Context.deleteFile(fileName)

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android中数据存储——文件存储数据

当一个应用程序在Android中安装后,我们在使用应用的过程中会产生很多的数据,应用都有自己的数据,那么我们应该如何存储数据呢? 数据存储方式Android 的数据存储有5种方式:1. SharedP...
  • To_be_Designer
  • To_be_Designer
  • 2015年09月07日 21:35
  • 1822

Android 数据存储之文件存储

Android 数据存储之文件存储
  • Houheshuai
  • Houheshuai
  • 2015年12月25日 09:41
  • 207

Android数据存储之文件存储

首先给大家介绍使用文件如何对数据进行存储,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的。 pub...
  • kyvi9989
  • kyvi9989
  • 2014年06月26日 12:10
  • 146

Android数据存储之“文件存储“

首先给大家介绍使用文件如何对数据进行存储,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的。 publi...
  • moliyll
  • moliyll
  • 2012年04月10日 14:36
  • 381

android数据存储之文件存储

android数据存储,可以分为五种,分别是: 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 4 使用ContentProvider存储数据 ...
  • core_ice
  • core_ice
  • 2016年09月09日 00:28
  • 101

【Android】数据存储之文件存储

前言      Android系统中有5种存储方式,分别是文件存储、SharedPreferences、SQLite数据库、ContentProvider、网络存储。这五种存储方式各有其特点。下面...
  • Gnd15732625435
  • Gnd15732625435
  • 2016年06月11日 21:41
  • 627

Android 数据存储之 文件存储

数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数...
  • wufagang
  • wufagang
  • 2016年10月20日 13:32
  • 180

Android数据存储之:文件存储

android文件存储分为内置存储和外置存储 转载来自:http://www.cnblogs.com/hanyonglu/archive/2012/03/01/2374894.html ...
  • qq_30716173
  • qq_30716173
  • 2015年11月18日 13:31
  • 159

Android当中数据存储之文件存储

最近在学习文件存储。抽空写一个小demo,就当记笔记了。废话不多说上代码 /** * 文件存储 * @author NanFeiLong */public class MainActivity ext...
  • qq_34471736
  • qq_34471736
  • 2016年09月09日 10:56
  • 277

Android 数据存储之文件存储小记

前言Android操作文件的方式和JAVA I/O操作是十分类似的,在这个我小谈一下。Android写入文件在Android中Context类提供了openFileOutput()方法,用于文件写入。...
  • lecepin
  • lecepin
  • 2016年05月11日 15:10
  • 605
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android数据存储之文件存储
举报原因:
原因补充:

(最多只允许输入30个字)