Android开发之保存图片到相册的三种方法详解

 更新时间:2022年04月13日 08:10:21   作者:xiayiye5  
这篇文章主要介绍了Android开发实现的保存图片到相册功能的三种方法,文中的示例代码讲解详细,有一定的参考价值,感兴趣的可以了解一下

有三种方法如下:三个方法都需要动态申请读写权限否则保存图片到相册也会失败

方法一

 /**
     * 保存bitmap到本地
     *
     * @param bitmap Bitmap
     */
    public static void saveBitmap(Bitmap bitmap, String path) {
        String savePath;
        File filePic;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            savePath = path;
        } else {
            Log.e("tag", "saveBitmap failure : sdcard not mounted");
            return;
        }
        try {
            filePic = new File(savePath);
            if (!filePic.exists()) {
                filePic.getParentFile().mkdirs();
                filePic.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(filePic);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            Log.e("tag", "saveBitmap: " + e.getMessage());
            return;
        }
        Log.i("tag", "saveBitmap success: " + filePic.getAbsolutePath());
    }

方法二

针对小于API29以下方法,此方法会通知图库更新

 
    /**
     * API 29及以下保存图片到相册的方法
     *
     * @param toBitmap 要保存的图片
     */
    private void saveImage(Bitmap toBitmap) {
        String insertImage = MediaStore.Images.Media.insertImage(getContentResolver(), toBitmap, "壁纸", "搜索猫相关图片后保存的图片");
        if (!TextUtils.isEmpty(insertImage)) {
            Toast.makeText(this, "图片保存成功!" + insertImage, Toast.LENGTH_SHORT).show();
            Log.e("打印保存路径", insertImage + "-");
        }
    }

方法三

针对大于API29以下方法,此方法也会通知图库更新

  /**
     * API29 中的最新保存图片到相册的方法
     */
    private void saveImage29(Bitmap toBitmap) {
        //开始一个新的进程执行保存图片的操作
        Uri insertUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
        //使用use可以自动关闭流
        try {
            OutputStream outputStream = getContentResolver().openOutputStream(insertUri, "rw");
            if (toBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)) {
                Log.e("保存成功", "success");
            } else {
                Log.e("保存失败", "fail");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

上面方法二和方法三是java的写法,kotlin写法如下

package com.xiayiye.jetpackstudy.gallery


import android.Manifest
import android.content.ContentValues
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.get
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.xiayiye.jetpackstudy.R
import kotlinx.android.synthetic.main.fragment_view_pager2_image.*
import kotlinx.android.synthetic.main.pager_photo_view.view.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 显示轮播大图和保存图片的页面
 */

class ViewPager2ImageFragment : Fragment() {
    companion object {
        const val REQUEST_WRITE_EXTERNAL_STORAGE_CODE = 1000
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_view_pager2_image, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        val photoList = arguments?.getParcelableArrayList<PhotoItem>("photo_list")
        val currentPosition = arguments?.getInt("photo_position", 0)
        PagerPhotoListAdapter().apply {
            vp2Banner.adapter = this
            submitList(photoList)
        }
        //设置轮播图片后的滑动当前页
        vp2Banner.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)
                tvShowImagePage.text =
                    StringBuffer().append(position + 1).append("/").append(photoList?.size)
            }
        })
        //设置 ViewPager2 的当前页要在设置 ViewPager2 的数据后在设置当前页面,否则不生效
        vp2Banner.setCurrentItem(currentPosition ?: 0, false)
        //设置纵向滚动的方法
        vp2Banner.orientation = ViewPager2.ORIENTATION_VERTICAL
        //保存图片的方法
        ivSaveImg.setOnClickListener {
            if (Build.VERSION.SDK_INT < 29 && ContextCompat.checkSelfPermission(
                    requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                requestPermissions(
                    arrayOf<String>(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                    REQUEST_WRITE_EXTERNAL_STORAGE_CODE
                )
            } else {
                viewLifecycleOwner.lifecycleScope.launch { saveImage29() }
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_WRITE_EXTERNAL_STORAGE_CODE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //权限申请成功可以保存图片
            viewLifecycleOwner.lifecycleScope.launch { saveImage29() }
        }
    }

    /**
     * 保存图片到相册的方法
     *  API29 后此方法已废弃
     */
    private fun saveImage() {
        val holder =
            (vp2Banner[0] as RecyclerView).findViewHolderForAdapterPosition(vp2Banner.currentItem) as PagerPhotoListAdapter.PagerPhotoViewHolder
        val toBitmap = holder.itemView.ivPagerView.drawable.toBitmap()
        val insertImage = MediaStore.Images.Media.insertImage(
            requireActivity().contentResolver, toBitmap, "壁纸", "搜索猫相关图片后保存的图片"
        )
        if (insertImage.isNotEmpty()) {
            Toast.makeText(requireActivity(), "图片保存成功!-${insertImage}", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(requireActivity(), "图片保存失败!}", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * API29 中的最新保存图片到相册的方法
     */
    private suspend fun saveImage29() {
        //开始一个新的进程执行保存图片的操作
        withContext(Dispatchers.IO) {
            val holder =
                (vp2Banner[0] as RecyclerView).findViewHolderForAdapterPosition(vp2Banner.currentItem) as PagerPhotoListAdapter.PagerPhotoViewHolder
            val toBitmap = holder.itemView.ivPagerView.drawable.toBitmap()
            val insertUri = requireActivity().contentResolver.insert(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ContentValues()
            ) ?: kotlin.run {
                showSaveToast("保存失败!")
                return@withContext
            }
            //使用use可以自动关闭流
            requireActivity().contentResolver.openOutputStream(insertUri).use {
                if (toBitmap.compress(Bitmap.CompressFormat.JPEG, 90, it)) {
                    showSaveToast("保存成功!")
                } else {
                    showSaveToast("保存失败!")
                }
            }
        }
    }

    /**
     * 显示保存图片结果的方法
     */
    private fun showSaveToast(showMsg: String) =
        MainScope().launch {
            Toast.makeText(requireActivity(), showMsg, Toast.LENGTH_SHORT).show()
        }
}

到此这篇关于Android开发之保存图片到相册的三种方法详解的文章就介绍到这了,更多相关Android保存图片到相册内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Android如何读写CSV文件方法示例

    Android如何读写CSV文件方法示例

    CSV 文件是Excel 的标准文件格式,在开发过程中经常需要格式化输出数据。CSV 的格式非常简单,都是一行一行存储的,同一行不同列之间用逗号隔开。下面这篇文章主要给大家介绍了关于Android如何读写CSV文件的相关资料,需要的朋友可以参考下。
    2017-08-08
  • Android MPAndroidChart开源库图表之折线图的实例代码

    Android MPAndroidChart开源库图表之折线图的实例代码

    这篇文章主要介绍了Android MPAndroidChart开源库图表之折线图的实例代码,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Android中WebView控件支持地理位置定位方法

    Android中WebView控件支持地理位置定位方法

    今天小编就为大家分享一篇Android中WebView控件支持地理位置定位方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 详解如何在Android studio中更新sdk版本和build-tools版本

    详解如何在Android studio中更新sdk版本和build-tools版本

    这篇文章主要介绍了如何在Android studio中更新sdk版本和build-tools版本,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • android实现简单拍照功能

    android实现简单拍照功能

    这篇文章主要为大家详细介绍了android实现简单拍照功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • 从Cocos2d-x2迁移到Cocos2d-x3的过程分享

    从Cocos2d-x2迁移到Cocos2d-x3的过程分享

    Cocos2d-x 3.0发布没多久,我就迫不及待地将手头的一个习作尝试从2.2.2版本迁移到3.0rc0引擎上,本问介绍了迁移流程和遇到的问题,以及发现了针对Android平台的变动,需要的朋友可以参考下
    2014-04-04
  • Android实现通讯录效果——获取手机号码和姓名

    Android实现通讯录效果——获取手机号码和姓名

    这篇文章主要介绍了Android实现通讯录效果——获取手机号码和姓名的相关资料,需要的朋友可以参考下
    2016-03-03
  • android使用Socket通信实现多人聊天应用

    android使用Socket通信实现多人聊天应用

    这篇文章主要为大家详细介绍了android使用Socket通信实现多人聊天应用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • android使用intent传递参数实现乘法计算

    android使用intent传递参数实现乘法计算

    这篇文章主要为大家详细介绍了android使用intent传递参数实现乘法计算,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Android实现拍照、选择图片并裁剪图片功能

    Android实现拍照、选择图片并裁剪图片功能

    这篇文章主要为大家详细介绍了Android实现拍照、选择图片并裁剪图片功能的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-05-05

最新评论