Android開發(fā)之保存圖片到相冊的三種方法詳解
有三種方法如下:三個方法都需要動態(tài)申請讀寫權(quán)限否則保存圖片到相冊也會失敗
方法一
/** * 保存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, "壁紙", "搜索貓相關(guān)圖片后保存的圖片"); if (!TextUtils.isEmpty(insertImage)) { Toast.makeText(this, "圖片保存成功!" + insertImage, Toast.LENGTH_SHORT).show(); Log.e("打印保存路徑", insertImage + "-"); } }
方法三
針對大于API29以下方法,此方法也會通知圖庫更新
/** * API29 中的最新保存圖片到相冊的方法 */ private void saveImage29(Bitmap toBitmap) { //開始一個新的進程執(zhí)行保存圖片的操作 Uri insertUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues()); //使用use可以自動關(guān)閉流 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) } //設(shè)置輪播圖片后的滑動當前頁 vp2Banner.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { super.onPageSelected(position) tvShowImagePage.text = StringBuffer().append(position + 1).append("/").append(photoList?.size) } }) //設(shè)置 ViewPager2 的當前頁要在設(shè)置 ViewPager2 的數(shù)據(jù)后在設(shè)置當前頁面,否則不生效 vp2Banner.setCurrentItem(currentPosition ?: 0, false) //設(shè)置縱向滾動的方法 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) { //權(quán)限申請成功可以保存圖片 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, "壁紙", "搜索貓相關(guān)圖片后保存的圖片" ) if (insertImage.isNotEmpty()) { Toast.makeText(requireActivity(), "圖片保存成功!-${insertImage}", Toast.LENGTH_SHORT).show() } else { Toast.makeText(requireActivity(), "圖片保存失敗!}", Toast.LENGTH_SHORT).show() } } /** * API29 中的最新保存圖片到相冊的方法 */ private suspend fun saveImage29() { //開始一個新的進程執(zhí)行保存圖片的操作 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可以自動關(guān)閉流 requireActivity().contentResolver.openOutputStream(insertUri).use { if (toBitmap.compress(Bitmap.CompressFormat.JPEG, 90, it)) { showSaveToast("保存成功!") } else { showSaveToast("保存失敗!") } } } } /** * 顯示保存圖片結(jié)果的方法 */ private fun showSaveToast(showMsg: String) = MainScope().launch { Toast.makeText(requireActivity(), showMsg, Toast.LENGTH_SHORT).show() } }
到此這篇關(guān)于Android開發(fā)之保存圖片到相冊的三種方法詳解的文章就介紹到這了,更多相關(guān)Android保存圖片到相冊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實現(xiàn)應(yīng)用內(nèi)置語言切換功能
這篇文章主要為大家詳細介紹了Android實現(xiàn)應(yīng)用內(nèi)置語言切換功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02Android自定義View實現(xiàn)多片葉子旋轉(zhuǎn)滑動(五)
這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)多片葉子葉子旋轉(zhuǎn)滑動,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03Android 中使用ContentObserver模式獲取短信用正則自動填充驗證碼
這篇文章主要介紹了Android 中使用ContentObserver模式獲取短信用正則自動填充驗證碼,首先使用了ContentObserver監(jiān)聽短信,然后從短信中用正則的分組去拿到驗證碼,具體實現(xiàn)代碼大家參考下本文2017-02-02安卓逆向騰訊動漫app返回數(shù)據(jù)加密分析案例分享
這篇文章主要為大家介紹了安卓逆向騰訊動漫app返回數(shù)據(jù)加密分析的案例分享,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2022-02-02