Business encountered the need for partial screenshots of the business logic, Baidu came out to use the way of caching screenshots, but after copy found a lot of delete lines, and then the official document indicates that it is outdated, it is recommended to use PIxelCopy API
For screenshots of the UI for feedback reports or unit testing the PixelCopy API is recommended.
Now I will encapsulate the code copy out, we directly use it!
/** * createBitmapFromView(window: window, View: View, callBack: (Bitmap? . Boolean) -> Unit) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { var bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888, true) convertLayoutToBitmap( window, view, If (copyResult == PixelCopy.SUCCESS) {callBack(bitmap,true)}else{callBack(null,false) } } } else { var bitmap: Bitmap? = null / / open the view caching bitmap the isDrawingCacheEnabled = true / / set the view caching bitmap quality view. The drawingCacheQuality = View.DRAWING_CACHE_QUALITY_HIGH val cache: bitmap = view.getdrawingCache () if (cache! = null && ! Cache.isrecycled) {bitmap = bitmap.createBitmap (cache)} // Destroy view cache bitmap view.destroyDrawingCache() // Disable view cache bitmap view.setDrawingCacheEnabled(false) callBack(bitmap,bitmap! =null) } } @RequiresApi(Build.VERSION_CODES.O) private fun convertLayoutToBitmap( window: Window, view: View, dest: Bitmap, listener: PixelCopy. OnPixelCopyFinishedListener) {/ / get the location of the layout val location = IntArray (2) the getLocationInWindow (location) PixelCopy. Request (window, Rect(location[0], location[1], location[0] + view.width, location[1] + view.height), dest, listener, Handler(Looper.getMainLooper()) ) }Copy the code
Save the picture and copy it together!
fun saveBitmapGallery(context: Context, bitmap: Bitmap): Boolean {the if (Build) VERSION) SDK_INT > = Build. VERSION_CODES. Q) {/ / return from a URI val insert = context. ContentResolver. The insert ( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, // ContentValues()/ sdCard/DCIM/Pictures */ ContentValues() : return false / / is empty Failure directly returned to the / / the opened the output stream directly save the picture good context. The contentResolver. OpenOutputStream (insert). The use {it? : return false bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it) } return true } else { MediaStore.Images.Media.insertImage(context.contentResolver, bitmap, "title", "desc") return true } } fun saveFile2Gallery(context: Context, url: String): Boolean {/ / returns an URI val insert = context. ContentResolver. The insert (MediaStore. Images. Media. EXTERNAL_CONTENT_URI, */ ContentValues())? Return false / / is empty Failure directly returned to the / / the opened the output stream directly save the picture good context. The contentResolver. OpenOutputStream (insert). The use {OS - > OS? : return false var x = download(url, os) return x } return false } private fun download(url: String, os: OutputStream): Boolean { val url = URL(url) (url.openConnection() as HttpURLConnection).also { conn -> conn.requestMethod = "GET" conn.connectTimeout = 5 * 1000 if (conn.responseCode == 200) { conn.inputStream.use { ins -> val buf = ByteArray(2048) var len: Int while (ins.read(buf).also { len = it } ! = -1) { os.write(buf, 0, len) } os.flush() } return true } else { return false } } }Copy the code
use
The following uses the SAM conversion feature of kotlin1.4. I don’t know if it is supported in earlier versions, but it should be possible to use normal lambda
PhotoUtils.createBitmapFromView(window, binding.cvShare) {bitmap,isCopySuccess-> if(isCopySuccess){ bitmap? . Let {PhotoUtils. SaveBitmapGallery (this, bitmap) showPromptMessage (" successfully saved ")}} else {showPromptMessage (" save failed ")}}Copy the code