当前位置: 首页 > news >正文

Android 保存图片

这个主要讲的InputStream去保存。
如果需要BItmap与InputStream相互转换可以参考

Android Bitmap、InputStream、Drawable、byte[]、Base64之间的转换关系

保存图片我们需要考虑系统版本,Q前后还是不一样的。

  /*** 保存图片* @param context  上下文* @param inputStream 流* @param suffixName  后缀名(.png  .jpg)* @return* @throws IOException*/public static String saveImageFromInput(Context context, InputStream inputStream, String suffixName) throws IOException {if (androidQ()) {Uri uri = saveImageFromInputByAndroidQMedia(context, inputStream, suffixName);String imagePathByUri = getImagePathByUri(context, uri);return imagePathByUri;} else {String imagePtah = createFilePath(context, suffixName,randomName() + suffixName).getAbsolutePath();saveImageFromInputByAndroid(context, inputStream, imagePtah);return imagePtah;}}/*** 保存媒体库(AndroidQ)* @param context* @param inputStream* @param suffixName* @return*/private static Uri saveImageFromInputByAndroidQMedia(Context context, InputStream inputStream, String suffixName) {BufferedInputStream bis = null;OutputStream outputStream = null;BufferedOutputStream bos = null;Uri uri = null;try {bis = new BufferedInputStream(inputStream);uri = getImageUriByMediaStore(context, suffixName);if (uri != null) {outputStream = context.getContentResolver().openOutputStream(uri);if (outputStream != null) {bos = new BufferedOutputStream(outputStream);byte[] buf = new byte[102400];int bytes = bis.read(buf);while (bytes >= 0) {bos.write(buf, 0, bytes);bos.flush();bytes = bis.read(buf);}}}} catch (IOException e) {e.printStackTrace();} finally {closeSilently(bis);closeSilently(bos);closeSilently(outputStream);return uri;}}/*** 保存本地* @param context* @param inputStream* @param imagePath*/private static void saveImageFromInputByAndroid(Context context, InputStream inputStream, String imagePath) {BufferedInputStream bis = null;OutputStream outputStream = null;BufferedOutputStream bos = null;try {bis = new BufferedInputStream(inputStream);outputStream = new FileOutputStream(imagePath);if (outputStream != null) {bos = new BufferedOutputStream(outputStream);byte[] buf = new byte[102400];int bytes = bis.read(buf);while (bytes >= 0) {bos.write(buf, 0, bytes);bos.flush();bytes = bis.read(buf);}}} catch (IOException e) {e.printStackTrace();} finally {closeSilently(bis);closeSilently(bos);closeSilently(outputStream);}}public static Uri getImageUriByMediaStore(Context context, String suffixName) throws IOException {Uri uri;if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {// 7.0之前获取uri方式uri = Uri.fromFile(createFilePath(context, "image", randomName() + suffixName));} else if (androidQ()) {ContentValues contentValues = new ContentValues();contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, randomName() + suffixName);contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/*");contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);} else {//7.0之后获取uri方式uri = FileProvider.getUriForFile(context, FileAppProvider.getProviderName(context), createFilePath(context, "image", randomName() + suffixName));}return uri;}/*** 创建文件路径* @param context* @param folderName* @param fileName* @return* @throws IOException*/private static File createFilePath(Context context, String folderName, String fileName) throws IOException {String path;if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/app/" + folderName + "/" + fileName;} else {path = context.getCacheDir().getAbsolutePath() + "/app/" + folderName + "/" + fileName;}return createFile(new File(path));}/*** 创建文件* @param imageFile* @return* @throws IOException*/private static File createFile(File imageFile) throws IOException {if (!imageFile.getParentFile().exists()) {imageFile.getParentFile().mkdirs();}if (imageFile.exists()) {imageFile.delete();}if (!imageFile.exists()) {imageFile.createNewFile();}return imageFile;}/*** 获取uri 对应 path* @param context* @param uri* @return*/public static String getImagePathByUri(Context context, Uri uri) {String imagePath = null;if (context != null && uri != null) {String[] proj = {MediaStore.Images.Media.DATA};Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);if (cursor.moveToFirst()) {int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);imagePath = cursor.getString(column_index);}cursor.close();}return imagePath;}public static void closeSilently(Closeable c) {if (c == null) return;try {c.close();} catch (Throwable t) {// Do nothing}}public static boolean androidQ() {return Build.VERSION.SDK_INT > Build.VERSION_CODES.Q;}/*** 生成随机名称** @return*/public static String randomName() {return System.currentTimeMillis() + "_" + new Random().nextInt();}

FileAppProvider
public class FileAppProvider extends FileProvider {public static String getProviderName(Context context) {return context.getPackageName() + ".app.file.app.provider";}
}

file_app_provider.xml

<?xml version="1.0" encoding="utf-8"?>
<!--Copyright 2017 Yan Zhenjie.Licensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
-->
<paths><external-pathname="external_path"path="."/><external-files-pathname="external_files_path"path="."/><external-cache-pathname="external_cache_path"path="."/><files-pathname="file_path"path="."/><cache-pathname="cache_path"path="."/></paths>

清单文件添加:

  <providerandroid:name="com.app.file.provider.FileZqcfProvider"android:authorities="${applicationId}.app.file.app.provider"android:exported="false"android:grantUriPermissions="true"android:multiprocess="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_app_provider" /></provider>

http://www.lryc.cn/news/137108.html

相关文章:

  • Android相机-架构
  • 从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值
  • 如何在Linux系统中处理PDF文件?
  • SpringBoot实现热部署/加载
  • 我是如何使用Spring Retry减少1000 行代码
  • ARM开发(stm32 cortex-A7核IIC实验)
  • 「Java」《Java集合框架详解:掌握常用集合类,提升开发效率》
  • 游戏出海需知:Admob游戏广告变现策略
  • 【linux】NFS调试总结
  • wireshark进行网络监听
  • 时间复杂度
  • Unity实现广告滚动播放、循环播放、鼠标切换的效果
  • LangChain + Streamlit + Llama:将对话式AI引入本地机器
  • Python 读写 Excel 文件库推荐和使用教程
  • “深入解析JVM:理解Java虚拟机的工作原理和优化技巧“
  • 解决SEGGER Embedded Studio无法显示Nordic MCU外设寄存器问题
  • Oracle-day1:scott用户、查询、取整、截取、模糊查询、别名——23/8/23
  • stm32之3.key开关
  • GPT带我学-设计模式-代理模式
  • VMware Workstation Pro 无法使用开机状态下拍的快照来克隆虚拟机,怎么解决?
  • 【JAVA】XML及其解析技术、XML检索技术、设计模式
  • Ansible 自动化安装软件
  • 简单介绍 React Native 整合 Formik 实现表单校验
  • 蓝帽杯半决赛2022
  • 电路学习+硬件每日学习十个知识点(40)23.8.20 (希腊字母读音,阶跃信号和冲激信号的关系式,信号的波形变换,信号的基本运算,卷积积分,卷积和)
  • Python——列表(list)推导式
  • 代码随想录算法训练营day43 | LeetCode 1049. 最后一块石头的重量 II 494. 目标和 474. 一和零
  • Linux安装jdk、mysql、并部署Springboot项目
  • tomcat更改端口号和隐藏端口号
  • 生信分析Python实战练习 2 | 视频19