Android 文件存储-图片存储

简介: 因 Android1 1谷歌禁止使用requestLegacyExternalStorage ,故将存储方式分为两种方式来进行文件存储。 存储你的应用打算与其他应用共享的文件,包括媒体、文档和其他文件。在这里咱们将图片保存至图库(共享文件)。

 因 Android1 1谷歌禁止使用requestLegacyExternalStorage ,故将存储方式分为两种方式来进行文件存储。

       存储你的应用打算与其他应用共享的文件,包括媒体、文档和其他文件。在这里咱们将图片保存至图库(共享文件)。


需要存储权限


    private void saveBitmap() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 检查该权限是否已经获取
            int i = ContextCompat.checkSelfPermission(FileStorageActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
            // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
            if (i != PackageManager.PERMISSION_GRANTED) {
                // 如果没有授予该权限,就去提示用户请求
                startRequestPermission();
            } else {
                resourceBitmap();
            }
        } else {
            resourceBitmap();
        }
    }


保存数据


    private void resourceBitmap() {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ceshi);
        boolean isSave = PictureStorageUtils.isSaveImage(this, bitmap, "sccgx");
        Log.e("File","isSave:"+isSave);
    }
/**
 * 功能描述:将图片文件保存至本地
 */  
public class PictureStorageUtils {
    public static boolean isSaveImage(Context context, Bitmap bm, String name) {
        boolean isSave;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            //大于等于android 10
            isSave = saveImageQ(context, bm, name);
        } else {
            isSave = saveImage(context, bm, name);
        }
        return isSave;
    }
    private static boolean saveImage(Context context, Bitmap outB, String name) {
        String imgName = name.isEmpty()?String.valueOf(System.currentTimeMillis()):name;
        //File.separator就是文件路径
        String fileName = Environment.getExternalStorageDirectory() + File.separator + "DCIM"
                + File.separator + "demo" + File.separator;
        try {
            File file = new File(fileName);
            if (!file.exists()) {
                file.mkdirs();
            }
            Log.e("File","saveAndGetImage:" + file);
            File filePath = new File(file + "/" + imgName + ".png");
            Log.e("File","filePath:" + filePath);
            FileOutputStream out = new FileOutputStream(filePath); //保存到本地,格式为JPEG
            if (outB.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                out.flush();
                out.close();
            }
            Log.e("File","saveAndGetImage:END");
            //刷新图库
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//高于22版本要手动授权
                // 检查该权限是否已经获取
                int i = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
                // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
                if (i != PackageManager.PERMISSION_GRANTED) {
                    // 提示用户应该去应用设置界面手动开启权限
                } else {
                    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(filePath)));
                }
            } else {
                context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(filePath)));
            }
            return true;
        } catch (FileNotFoundException e) {
            Log.e("File","FileNotFoundException e.toString: " + e.toString());
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            Log.e("File","IOException e.toString: " + e.toString());
            e.printStackTrace();
            return false;
        }
    }
    //功能描述:Android10及以上保存图片到相册
    @RequiresApi(api = Build.VERSION_CODES.Q)
    private static boolean saveImageQ(Context context, Bitmap image, String name) {
        long mImageTime = System.currentTimeMillis();
        String mImageFileName = name.isEmpty()?String.valueOf(mImageTime):name;
        final ContentValues values = new ContentValues();
        values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM
                + File.separator + "demo"); //图库(DCIM)中显示的文件夹名。
        values.put(MediaStore.MediaColumns.DISPLAY_NAME, mImageFileName);
        values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
        values.put(MediaStore.MediaColumns.DATE_ADDED, mImageTime / 1000);
        values.put(MediaStore.MediaColumns.DATE_MODIFIED, mImageTime / 1000);
        values.put(MediaStore.MediaColumns.DATE_EXPIRES, (mImageTime + DateUtils.DAY_IN_MILLIS) / 1000);
        values.put(MediaStore.MediaColumns.IS_PENDING, 1);
        Log.e("File",values.get(MediaStore.MediaColumns.RELATIVE_PATH).toString());
        ContentResolver resolver = context.getContentResolver();
        final Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        try {
            //写下我们文件的数据
            try (OutputStream out = resolver.openOutputStream(uri)) {
                if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                    throw new IOException("Failed to compress");
                }
            }
            //一切都很顺利
            values.clear();
            values.put(MediaStore.MediaColumns.IS_PENDING, 0);
            values.putNull(MediaStore.MediaColumns.DATE_EXPIRES);
            resolver.update(uri, values, null, null);
            return true;
        } catch (IOException e) {
            Log.e("File",e.getMessage());
            return false;
        }
    }
}


测试机:Galaxy A8s


       图片保存路径:Galaxy A8s\Phone\DCIM\demo

image.png


测试机:Pixel XL API 31(AS模拟器)


       图片保存路径:/storage/emulated/0/DCIM/demo/sccgx.png


image.png



相关文章
|
11月前
|
XML Android开发 数据格式
Android利用selector(选择器)实现图片动态点击效果
本文介绍了Android中ImageView的`src`与`background`属性的区别及应用,重点讲解如何通过设置背景选择器实现图片点击动态效果。`src`用于显示原图大小,不拉伸;`background`可随组件尺寸拉伸。通过创建`selector_setting.xml`,结合`setting_press.xml`和`setting_normal.xml`定义按下和正常状态的背景样式,提升用户体验。示例代码展示了具体实现步骤,包括XML配置和形状定义。
508 3
Android利用selector(选择器)实现图片动态点击效果
|
11月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
302 2
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
移动开发 安全 Java
Android历史版本与APK文件结构
通过以上内容,您可以全面了解Android的历史版本及其主要特性,同时掌握APK文件的结构和各部分的作用。这些知识对于理解Android应用的开发和发布过程非常重要,也有助于在实际开发中进行高效的应用管理和优化。希望这些内容对您的学习和工作有所帮助。
1553 83
|
11月前
|
Java Android开发
Android studio中build.gradle文件简单介绍
本文解析了Android项目中build.gradle文件的作用,包括jcenter仓库配置、模块类型定义、包名设置及依赖管理,涵盖本地、库和远程依赖的区别。
917 19
|
11月前
|
Java Android开发
Android图片的手动放大缩小
本文介绍了通过缩放因子实现图片放大缩小的功能,效果如动图所示。关键步骤包括:1) 在布局文件中设置 `android:scaleType="matrix"`;2) 实例化控件并用 `ScaleGestureDetector` 处理缩放手势;3) 使用 `Matrix` 对图片进行缩放处理。为避免内存崩溃,可在全局配置添加 `android:largeHeap="true"`。代码中定义了 `beforeScale` 和 `nowScale` 变量控制缩放范围,确保流畅体验。
392 8
|
11月前
|
存储 XML Java
Android 文件数据储存之内部储存 + 外部储存
简介:本文详细介绍了Android内部存储与外部存储的使用方法及核心原理。内部存储位于手机内存中,默认私有,适合存储SharedPreferences、SQLite数据库等重要数据,应用卸载后数据会被清除。外部存储包括公共文件和私有文件,支持SD卡或内部不可移除存储,需申请权限访问。文章通过代码示例展示了如何保存、读取、追加、删除文件以及将图片保存到系统相册的操作,帮助开发者理解存储机制并实现相关功能。
2598 2
|
11月前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
428 1
|
Java Android开发 C++
Android Studio JNI 使用模板:c/cpp源文件的集成编译,快速上手
本文提供了一个Android Studio中JNI使用的模板,包括创建C/C++源文件、编辑CMakeLists.txt、编写JNI接口代码、配置build.gradle以及编译生成.so库的详细步骤,以帮助开发者快速上手Android平台的JNI开发和编译过程。
1341 1
|
ARouter Android开发
Android不同module布局文件重名被覆盖
Android不同module布局文件重名被覆盖
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
303 20
Android经典面试题之图片Bitmap怎么做优化