gradle

android {
	buildFeatures {
	        viewBinding = true
	    }
}
<uses-permission android:name="android.permission.CAMERA"/> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-feature android:name="android.hardware.Camera"/>

camera2 관련 블로그!!!!!

[android] Camera2 API 를 알아보자

deprecated 된게 너무 많아서..더 공부해야할 것 같음!!

private const val TAG = "MainActivity2"

class MainActivity : BaseActivity() {
   
    val PERMISSION_STORAGE : Int = 99
    val PERMISSION_CAMERA : Int = 100
    val CAMERA_CODE : Int = 10
    val GALLERY_CODE : Int = 101

    private var mContext: Context = this

    val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    var realURI: Uri? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //setContentView(R.layout.activity_main)
        setContentView(binding.root)

        requirePermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSION_STORAGE)

//        binding.btnPermission.setOnClickListener(View.OnClickListener {
//           requirePermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSION_STORAGE)
//        })
    }

    override fun permissionGranted(requestCode: Int) {
        Log.d(TAG, "permissionGranted: $requestCode")
        when (requestCode){
            PERMISSION_STORAGE -> {
                setViews()
            }
            PERMISSION_CAMERA -> {
                openCamera()
            }
        }
    }

    override fun permissionDenied(requestCode: Int) {
        when (requestCode){
            PERMISSION_STORAGE -> {
                Toast.makeText(mContext,"외부 저장소 권한을 승인해야 앱을 사용할 수 있습니다", Toast.LENGTH_SHORT).show()
                finish()
            }
            PERMISSION_CAMERA -> {
                Toast.makeText(mContext,"카메라 권한을 승인해야 카메라를 사용할 수 있습니다", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private fun setViews(){
        binding.btnCamera.setOnClickListener(View.OnClickListener {
            requirePermissions(arrayOf(Manifest.permission.CAMERA), PERMISSION_CAMERA)
        })

        binding.btnGallery.setOnClickListener(View.OnClickListener {
            openGallery() // 갤러리에서 사진 가져오기
        })
    }

    private fun openCamera(){
        Log.d(TAG, "openCamera: ")
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

        createImageUri(newFileName(), "image/jpg")?.let { uri ->
            realURI = uri
            intent.putExtra(MediaStore.EXTRA_OUTPUT, realURI)
            startActivityForResult(intent, CAMERA_CODE)
        }

    }

   private fun openGallery() {
       val intent = Intent(Intent.ACTION_PICK)
       intent.type = MediaStore.Images.Media.CONTENT_TYPE
       startActivityForResult(intent, GALLERY_CODE)
   }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(resultCode == RESULT_OK){
            Log.d(TAG, "onActivityResult: $requestCode")
            when (requestCode){
                CAMERA_CODE -> {
                    realURI?.let { uri ->
                        val bitmap = loadBitmap(uri)
                        binding.ivPreview.setImageBitmap(bitmap)

                        realURI = null
                     }
                }
                GALLERY_CODE -> {
                    data?.data?.let { uri ->
                        binding.ivPreview.setImageURI(uri)
                    }
                }
            }
        }
    }

    // 촬영한 이미지를 저장할 uri를 미디어스토어에 생성하는 메서드
    private fun createImageUri(filename: String, mimeType: String): Uri? {
        var values = ContentValues()
        values.put(MediaStore.Images.Media.DISPLAY_NAME, filename)
        values.put(MediaStore.Images.Media.MIME_TYPE, mimeType)
        return contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
    }

    // 파일명을 만들어줌
    private fun  newFileName(): String {
        val sdf = SimpleDateFormat("yyyyMMdd_HHmmss")
        val filename = sdf.format(System.currentTimeMillis())

        return "$filename.jpg"
    }

    private fun loadBitmap(photoURI: Uri) : Bitmap? {
        var image: Bitmap? = null
        try {
            image = if(Build.VERSION.SDK_INT > 27){
                val source: ImageDecoder.Source = ImageDecoder.createSource(this.contentResolver, photoURI)
                ImageDecoder.decodeBitmap(source)
            } else {
                MediaStore.Images.Media.getBitmap(this.contentResolver, photoURI)
            }
        }catch (e: Exception){

        }
        return image
    }

   }