안드로이드 개발 중 스크린 캡쳐가 검은 화면으로 저장되는 문제 해결하기

이윤진·2023년 2월 20일
0

Android 개발

목록 보기
3/9

프로젝트 개발 중, 결과 달성률 보고 페이지를 이미지로 저장하는 기능을 만들어야 했다.

함수를 이용하여

val captureImage = getScreenShotFromView(viewBinding.baseLayout)

val filename = "${System.currentTimeMillis()}.jpg"

//이미지 저장
if (captureImage!=null){
	saveMediaToStorage(captureImage, filename)
}

이렇게 이미지 저장을 하도록 구현했지만, 저장된 화면은 그냥 까만 화면이었다.

이 문제는 내가 스크린 하려는 페이지가 아직 화면에 제대로 띄워지지 않은 상태에서 캡쳐가 되어서 생긴 문제였다.
이를 해결하기 위해 post 함수를 사용했다.
post 함수는 내가 저장하고자 하는 페이지가 화면에 완전히 띄워질 때까지 기다렸다가 명령을 실행할 수 있게 해주는 함수다.

viewBinding.image.setOnClickListener {
//이미지 캡쳐 해서 만들기
//post를 해야 검은 화면이 안 뜬다.
//->뷰가  Attach 되지 않았다면 될 때까지 runnable을 연기시켜 줍니다
	viewBinding.baseLayout.post {
		val captureImage = getScreenShotFromView(viewBinding.baseLayout)

        val filename = "${System.currentTimeMillis()}.jpg"

		//이미지 저장
        if (captureImage!=null){
        	saveMediaToStorage(captureImage, filename)
        }
    }
}

post 함수 안에 캡쳐 함수를 넣었더니 의도대로 화면이 제대로 캡쳐되었다.

getScreenShotFromView 함수

	//view를 캡쳐하는 함수
    private fun getScreenShotFromView(v: View): Bitmap? {
        // create a bitmap object
        var screenshot: Bitmap? = null
        try {
            // inflate screenshot object
            // with Bitmap.createBitmap it
            // requires three parameters
            // width and height of the view and
            // the background color
            screenshot = Bitmap.createBitmap(v.measuredWidth, v.measuredHeight, Bitmap.Config.ARGB_8888)
            // Now draw this bitmap on a canvas
            val canvas = Canvas(screenshot)
            v.draw(canvas)
        } catch (e: Exception) {
            Log.e("GFG", "Failed to capture screenshot because:" + e.message)
        }
        // return the bitmap
        return screenshot
    }

saveMediaToStorage 함수

	//이미지를 저장하는 함수
    private fun saveMediaToStorage(bitmap: Bitmap, filename : String) {
        // Generating a file name
		// val filename = "${System.currentTimeMillis()}.jpg"

        // Output stream
        var fos: OutputStream? = null

        // For devices running android >= Q
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // getting the contentResolver
            this.contentResolver?.also { resolver ->

                // Content resolver will process the contentvalues
                val contentValues = ContentValues().apply {

                    // putting file information in content values
                    put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
                    put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg")
                    put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
                }

                // Inserting the contentValues to
                // contentResolver and getting the Uri
                val imageUri: Uri? = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)

                // Opening an outputstream with the Uri that we got
                fos = imageUri?.let { resolver.openOutputStream(it) }
            }
        } else {
            // These for devices running on android < Q
            val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
            val image = File(imagesDir, filename)
            fos = FileOutputStream(image)
        }

        fos?.use {
            // Finally writing the bitmap to the output stream that we opened
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
            Toast.makeText(this , "Captured View and saved to Gallery" , Toast.LENGTH_SHORT).show()
        }
    }
profile
Android/Flutter 개발

0개의 댓글