Android 控件截圖保存本地并分享

目錄

需求

需求分析

一、截圖控件生成圖片

二、將圖片保存至本地

2.1 權限

2.2 保存圖片

2.3 調用

三、分享

四、通過測試機型


需求

截圖當前頁面某個控件的內容,并且保存在本地,可分享。

需求分析

  • 1.截圖控件生成圖片

  • 2.保存至本地(需考慮版本兼容以及權限問題)

  • 3.分享(a.調用系統分享,b.自己集成三方SDK)

分析完事,咱們根據分析來一步步實現

一、截圖控件生成圖片

????private?Runnable?toastRunnable?=?new?Runnable()?{public?void?run()?{Bitmap?bm?=?Bitmap.createBitmap(ll_dialog.getWidth(),?ll_dialog.getHeight(),Bitmap.Config.ARGB_8888);//創建畫布Canvas?canvas?=?new?Canvas(bm);//View渲染到的畫布。ll_dialog.draw(canvas);MLog.e("保存圖片");}};
  • 1.圖片要在頁面中加載出來,需要獲取該控件的寬高。

  • 2.根據空寂那的寬高設置Bitmap的

  • 3.View渲染到的畫布,這個時候bm就生成成功了。

二、將圖片保存至本地

保存圖片的方式根據「版本和權限」分為兩種:

  • Android Q(Android 10) 以上

    • 1、保存到應用的內部存儲空間 (內部存儲)

    • 2、保存到 Android 系統設置的共享存儲空間(外部儲存)

  • Android Q(Android 10) 以下

    • 獲取外部存儲目錄(本文用的是這個)

      • 函數使用:getExternalStorageDirectory()

    • 獲取外部存儲公共目錄

      • 函數使用:getExternalStoragePublicDirectory()

圖片(包括照片和屏幕截圖),存儲在 DCIM/ 或 Pictures/ 目錄。

2.1 權限

「Android Q不再需要申請文件讀寫權限」,默認可以讀寫自己沙盒文件和公共媒體文件。所以Q以上不需要再動態申請文件讀寫權限。

所以我們只需要兼容10以下的權限申請即可。

public?class?PerUtils?{public?static?int?REQUEST_CODE_WRITE?=?1001;//校驗權限public?static?boolean?checkPerWRITE(Activity?activity)?{if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.R)?{return?true;}?else?{String[]?permissions?=?{Manifest.permission.READ_EXTERNAL_STORAGE,?Manifest.permission.WRITE_EXTERNAL_STORAGE};for?(String?str?:?permissions)?{if?(activity.checkSelfPermission(str)?!=?PackageManager.PERMISSION_GRANTED)?{activity.requestPermissions(permissions,?REQUEST_CODE_WRITE);return?false;}}}return?true;}/***?檢測請求結果碼判定是否授權**?@param?grantResults*?@return*/public?static?boolean?checkPermissionResult(int[]?grantResults)?{if?(grantResults?!=?null)?{for?(int?result?:?grantResults)?{if?(result?!=?PackageManager.PERMISSION_GRANTED)?{return?false;}}}return?true;}
}

Activity.class調用

????if?(PerUtils.checkPerWRITE(Activity.this)){saveBitmap();}@Overridepublic?void?onRequestPermissionsResult(int?requestCode,?@NonNull?String[]?permissions,?@NonNull?int[]?grantResults)?{super.onRequestPermissionsResult(requestCode,?permissions,?grantResults);try?{if?(requestCode?==?PerUtils.REQUEST_CODE_WRITE)?{if?(PerUtils.checkPermissionResult(grantResults))?{//授權成功saveBitmap();}else{//授權失敗}}}?catch?(Exception?e)?{}}

2.2 保存圖片

import?android.content.ContentResolver;
import?android.content.ContentValues;
import?android.content.Context;
import?android.content.Intent;
import?android.database.Cursor;
import?android.graphics.Bitmap;
import?android.net.Uri;
import?android.os.Build;
import?android.os.Environment;
import?android.provider.MediaStore;
import?android.util.Log;import?androidx.annotation.RequiresApi;import?java.io.File;
import?java.io.FileOutputStream;
import?java.io.IOException;
import?java.io.OutputStream;public?class?ShareImageUtils?{//?Android?Q?以上@RequiresApi(api?=?Build.VERSION_CODES.Q)public?static?String?saveQUp(Bitmap?image,?Context?context,?String?fileName,?int?quality)?{//?文件夾路徑String?imageSaveFilePath?=?Environment.DIRECTORY_DCIM?+?File.separator;MLog.e("TAG",?"文件夾目錄?>>>?"?+?imageSaveFilePath);File?filePath?=?new?File(imageSaveFilePath);if?(!filePath.exists())?{filePath.mkdirs();}//?文件名字MLog.e("TAG",?"文件名字?>>>?"?+?fileName);ContentValues?contentValues?=?new?ContentValues();contentValues.put(MediaStore.MediaColumns.TITLE,?fileName);contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME,?fileName);contentValues.put(MediaStore.MediaColumns.MIME_TYPE,?"image/jpeg");contentValues.put(MediaStore.MediaColumns.DATE_TAKEN,?fileName);//該媒體項在存儲設備中的相對路徑,該媒體項將在其中保留contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH,?imageSaveFilePath);Uri?uri?=?null;OutputStream?outputStream?=?null;ContentResolver?localContentResolver?=?context.getContentResolver();try?{uri?=?localContentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,?contentValues);outputStream?=?localContentResolver.openOutputStream(uri);//?Bitmap圖片保存image.compress(Bitmap.CompressFormat.JPEG,?quality,?outputStream);outputStream.flush();outputStream.close();return?getRealPathFromURI(uri);}?catch?(Exception?e)?{e.printStackTrace();if?(uri?!=?null)?{localContentResolver.delete(uri,?null,?null);}return?"";}?finally?{image.recycle();try?{if?(outputStream?!=?null)?{outputStream.close();}}?catch?(IOException?e)?{e.printStackTrace();}}}//根據Uri獲取路徑private?static?String?getRealPathFromURI(Uri?contentURI)?{String?result;Cursor?cursor?=?MyApp.getAppContext().getContentResolver().query(contentURI,?null,?null,?null,?null);if?(cursor?==?null)?{?//?Source?is?Dropbox?or?other?similar?local?file?pathresult?=?contentURI.getPath();}?else?{cursor.moveToFirst();int?idx?=?cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);result?=?cursor.getString(idx);cursor.close();}return?result;}//?Android?Q?以下public?static?String?saveQNext(Bitmap?image,?Context?context,?String?fileName,?int?quality)?{String?path?=?Environment.getExternalStorageDirectory().getAbsolutePath()?+?File.separator;Log.i("TAG",?"saveQNext:?>>>?"?+?path);File?filePath?=?new?File(path);if?(!filePath.exists())?{filePath.mkdirs();}//?文件名稱Log.i("TAG",?"saveQNext:?"?+?fileName);File?file?=?new?File(path,?fileName);try?{FileOutputStream?fos?=?new?FileOutputStream(file);//?通過io流的方式來壓縮保存圖片image.compress(Bitmap.CompressFormat.JPEG,?quality,?fos);fos.flush();fos.close();//?保存圖片后發送廣播通知更新數據庫,不更新數據庫不會立即顯示Uri?uri?=?Uri.fromFile(file);context.sendBroadcast(new?Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,?uri));return?getRealPathFromURI(uri);}?catch?(IOException?e)?{e.printStackTrace();return?"";}}
}???????????

如此便將生成的Bitmap保存在本地了。

2.3 調用

????????????String?fileName?=?System.currentTimeMillis()?+?".jpg";String?path?=?"";//根據版本使用不同的方法if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.Q)?{path?=?ShareImageUtils.saveQUp(bm,?mContext,?fileName,?100);}?else?{path?=?ShareImageUtils.saveQNext(bm,?mContext,?fileName,?100);}if?(!MStringUtils.isNullOrEmpty(path))?{//保存成功}?else?{//保存失敗}

三、分享

調用系統圖片進行分享

????????//由文件得到uriUri?imageUri?=?Uri.fromFile(new?File(path));MLog.e("share",?"uri:"?+?path);Intent?shareIntent?=?new?Intent();shareIntent.setAction(Intent.ACTION_SEND);shareIntent.putExtra(Intent.EXTRA_STREAM,?imageUri);shareIntent.setType("image/*");mContext.startActivity(Intent.createChooser(shareIntent,?"Share"));

四、通過測試機型

  • 1.Android 13 三星

  • 2.Android 12 小米 K40

  • 3.Android 7.1 模擬器

  • 4.鴻蒙2.0系統 華為Play

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/42065.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/42065.shtml
英文地址,請注明出處:http://en.pswp.cn/news/42065.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【SpringCloud】Ribbon定制化配置

文章目錄 使用Ribbon自帶負載均衡算法添加負載均衡算法ConfigurationRestTemplate使用上面負載均衡算法 自定義負載均衡算法負載均衡算法實現RestTemplate在Controller中使用該負載均衡算法ServiceIInstance解釋 使用Ribbon自帶負載均衡算法 添加負載均衡算法Configuration /…

實現矩陣地圖與rviz地圖重合

文章目錄 一、rviz地圖轉換矩形地圖(只能用于全局規劃)二、在rviz上顯示地圖邊界信息,可視化調整,實現重合(只能用于局部規劃)一、rviz地圖轉換矩形地圖(只能用于全局規劃) 此方法矩形地圖可能會與rviz地圖不重合,通過改變偏移量x_offset,y_offset接近地圖 可以將矩…

FL Studio for Windows-21.1.0.3713中文直裝版功能介紹及系統配置要求

FL Studio 21簡稱FL水果軟件,全稱是:Fruity Loops Studio編曲,由于其Logo長的比較像一款水果因此,在大家更多的是喜歡稱他為水果蘿卜,FL studio21是目前最新的版本,這是一款可以讓你的計算機就像是一個全功能的錄音室&…

Docker Dockerfile Docker-compose學習筆記

文章目錄 Centos環境下安裝Docker配置鏡像源 Windows環境下安裝Docker配置鏡像源 使用Dokcer鏡像1.獲取鏡像2.查看鏡像信息(1)列出鏡像(2)鏡像標簽(3)鏡像詳細信息(4)鏡像歷史 3.搜索鏡像4.刪除和清理鏡像(1)使用標簽刪除鏡像(2)使用ID刪除鏡像(3)清理鏡像 5.創建鏡像(1)基于已…

基于SpringBoot和Freemarker的頁面靜態化

頁面靜態化能夠緩輕數據庫的壓力,還能提高頁面的并發能力,但是網頁靜態化是比較適合大規模且相對變化不太頻繁的數據。 頁面靜態化在實際應用中還是比較常見的,比如博客詳情頁、新聞網站或者文章類網站等等。這類數據變化不頻繁比較適合靜態…

56.linux 進程管理命令和用戶管理命令

目錄 一、進程管理命令 1.ps 2.pstree 3.kill 4.pkill 5.&后臺運行程序 6.jobs 7.fg bg 8.top 二、用戶管理命令 1.系統存儲用戶信息的文件 2.添加新用戶 3.修改用戶密碼 4.刪除用戶 一、進程管理命令 1.ps 用于查看當前系統中運行的進程信息。它可以…

Golang 程序性能優化利器 PGO 詳解(一):簡單介紹及使用

在軟件開發過程中,性能優化是不可或缺的一部分。無論是在Web服務、數據處理系統還是實時通信中,良好的性能都是至關重要的。Golang 從1.20版版本開始引入的 Profile Guided Optimization(PGO)機制能夠幫助更好地優化 Go 程序的性能…

The Age of Data and AI: Challenges and Opportunities

Simply put Abstract: This paper examines the impact of the “Age of Data” on the field of artificial intelligence (AI). With the proliferation of digital technologies and advancements in data collection, storage, and processing, organizations now have ac…

進行 200 瓦太陽能 (PV) 模塊設計以測量太陽能光伏陣列的電壓、電流和功率、綜合負荷頻率和電壓控制系統的方法研究(Simulink實現)

💥💥💞💞歡迎來到本博客????💥💥 🏆博主優勢:🌞🌞🌞博客內容盡量做到思維縝密,邏輯清晰,為了方便讀者。 ??座右銘&a…

Levenshtein python調用

函數解釋: Levenshtein距離又稱作編輯距離(Edit Distance),是指兩個字符之間,由一個字符轉變成另一個字符所需的最少編輯操作次數。被允許的操作有以下幾種: a. Replace替換,將一個字符替換成另…

如何使用CSS實現一個響應式視頻播放器?

聚沙成塔每天進步一點點 ? 專欄簡介? 使用CSS實現響應式視頻播放器? 寫在最后 ? 專欄簡介 前端入門之旅:探索Web開發的奇妙世界 記得點擊上方或者右側鏈接訂閱本專欄哦 幾何帶你啟航前端之旅 歡迎來到前端入門之旅!這個專欄是為那些對Web開發感興趣…

vue輸入框只能輸入數字類型,禁止輸入和粘貼e

js怎么去除1e里面e 方法一:使用 Number() 函數將科學計數法表示的字符串轉換為數字。然后,使用 toString() 方法將其轉換回字符串形式,這樣就會自動移除科學計數法中的 "e" var num 1e10; // 科學計數法表示的數字 var numStr …

【小夢C嘎嘎——啟航篇】string介紹以及日常使用的接口演示

【小夢C嘎嘎——啟航篇】string 使用😎 前言🙌C語言中的字符串標準庫中的string類string 比較常使用的接口對上述函數和其他函數的測試代碼演示: 總結撒花💞 😎博客昵稱:博客小夢 😊最喜歡的座右…

c語言每日一練(9)

前言:每日一練系列,每一期都包含5道選擇題,2道編程題,博主會盡可能詳細地進行講解,令初學者也能聽的清晰。每日一練系列會持續更新,暑假時三天之內必有一更,到了開學之后,將看學業情…

rollup工具打包報錯問題匯總

1. (!) this has been rewritten to undefined 原因:這是因為打包后沒有給this指向window,導致this undefined,因此需要配置context參數來指定代碼執行環境的參數為window 解決:rollup.config.js文件中添加配置 module.exports…

算法通關村第十關 | 數組中第k個最大元素

1.數組中第k大的數字 題目: LeetCode:數組中的第k個最大元素,給定整數數組nums和整數k,請返回數組中第k個最大的元素,請注意,你需要找的是數組排序后第k個最大的元素,而不是第k個不同的元素。 運…

JVM——配置常用參數,GC調優策略

文章目錄 JVM 配置常用參數Java內存區域常見配置參數概覽堆參數回收器參數項目中常用配置常用組合 常用 GC 調優策略GC 調優原則GC 調優目的GC 調優策略 JVM 配置常用參數 Java內存區域常見配置參數概覽堆參數;回收器參數;項目中常用配置;常…

element-Plus中el-menu菜單無法正常收縮解決方案

<el-menu :collapse"true">如圖所示收縮之后&#xff0c;有子級的菜單還有箭頭文字顯示 從代碼對比看層級就不太對了&#xff0c;嵌套錯誤了&#xff0c;正常下方官網的ul標簽下直接是li&#xff0c;在自己的代碼中&#xff0c;ul標簽下是div標簽&#xff0c;層…

FairyGUI編輯器自定義菜單擴展插件

本文涉及到的軟件有&#xff1a;FairyGUI&#xff0c;VSCode 代碼環境涉及到了&#xff1a;Lua VSCode插件&#xff1a;EmmyLua 在編寫FairyGUI編輯器菜單前&#xff0c;了解一下FairyGUIEditor的API會有效的幫助我們解決很多問題。FairyGUI的擴展是通過編輯器自帶的插件功能…

【嵌入式】MKV31F512VLL12 微控制器 (MCU) 、Cyclone? IV E EP4CE10E22I8LN,FPGA-現場可編程門陣列芯片

1、MKV31F512VLL12 微控制器 (MCU) 是適用于BLDC、PMSM和ACIM電機控制應用的高性能解決方案。這些MCU采用運行頻率為100MHz/120MHz、帶數字信號處理 (DSP) 和浮點單元 (FPU) 的ARM Cortex-M4內核。KV3x MCU配備兩個采樣率高達1.2MS/s的16位ADC、多個控制定時器以及512KB閃存。 …