사실 이전에 권한에 관한 내용을 살펴보면서 카메라를 사용하는 방법에 대해 간단히 살펴본 적이 있습니다. 그래서 이번에는 카메라 앱을 호출하는 것 이외에 카메라로 사진을 찍은 뒤 찍은 사진을 가져오는 방법에 대해서도 알아보려고 합니다.
먼저 화면을 아래와 같이 디자인합니다. 버튼을 가운데 배치하고 id를 btnCamera로 하였습니다.
app -> manifests -> AndroidManifest.xml 파일을 수정해 App에서 카메라로의 접근권한이 필요함을 선언합니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity 안에서 2개의 변수를 추가합니다. 하나는 권한을 확인할때의 권한 확인을 위한 것이고 다른 하나는 권한 요청을 위한 권한 자체를 정의하는 변수입니다.
val CAMERA = arrayOf(Manifest.permission.CAMERA)
val CAMERA_CODE = 98
그리고 실제 권한을 확인하는 메서드를 추가합니다. 메서드의 인수로 필요한 권한을 배열로 전달하도록 되어 있는데 메서드내부에서 이 배열을 순회하면서 각각의 권한이 있는지를 확인하게 됩니다. 만약 권한이 주어져 있지 않으면 ActivityCompat.requestPermissions을 호출하여 사용자에게 권한을 요청하게 됩니다.
fun checkPermission(permissions: Array<out String>): Boolean
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (permission in permissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, permissions, CAMERA_CODE)
return false;
}
}
}
return true;
}
권한을 확인하고 나면 곧바로 onRequestPermissionsResult 함수를 호출하게 됩니다. 따라서 해당 메서드를 필요한 내용으로 재정의 합니다. 어떠한 권한요청에 대한 결과인지는 requestCode를 통해서 확인하며 만약 권한이 주어져 있지 않다면 '카메라 권한을 승인해 주세요.'라는 메시지를 내고 그대로 앱 동작을 중지하게 됩니다.
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray)
{
when(requestCode) {
CAMERA_CODE -> {
for (grant in grantResults) {
if (grant != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "카메라 권한을 승인해 주세요.", Toast.LENGTH_LONG).show()
}
}
}
}
}
위에서 만들어둔 권한체크함수를 호출하는 것을 포함하여 카메라를 호출하는 메서드를 작성합니다. 우선 권한이 있는지를 확인하고 최종적으로 권한이 주어진 게 맞다면 Intent에 ACTION_IMAGE_CAPTURE를 담아 startActivityForResult를 호출하면 카메라 앱이 실행됩니다.
fun CallCamera()
{
if (checkPermission(CAMERA)) {
val itt = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(itt, CAMERA_CODE)
}
}
마지막으로 처음에 만들어뒀던 버튼을 눌렀을때 CallCamera 메서드를 호출할 수 있도록 합니다.
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.btnCamera.setOnClickListener() {
CallCamera()
}
}
주의 : kotlin 4.1에 들어서면서 kotlin android extentions가 제거되었습니다. 따라서 기존처럼 곧장 위젯의 ID를 통해 접근할 수 없습니다. 따라서 상기와 같이 ViewBinding을 사용해야 합니다.
이제 버튼을 누르면 카메라앱을 실행할 수 있습니다.
호출된 카메라 앱을 통해 사진을 찍으면 앱에서는 아무런 변화도 없습니다. 카메라 앱을 통해 사진을 찍었을 때 찍은 사진을 가져오려면 onActivityResult 메서드를 작성해야 합니다. onActivityResult는 사진촬영이 완료되면 호출되는 메서드라고 생각하면 됩니다. 또한 촬영한 사진에 관한 정보는 data Intent로 전달되므로 여기에서 사진을 추출해야 합니다.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
CAMERA_CODE -> {
if (data?.extras?.get("data") != null) {
val img = data?.extras?.get("data") as Bitmap
binding.imageView.setImageBitmap(img)
}
}
}
}
}
화면은 아래와 같이 버튼위에 ImageView 위젯을 추가합니다. ID는 imageView로 합니다. 위에 onActivityResult 메서드에서는 사진을 가져올 때 가져온 사진을 imageView의 setImageBitmap메서드를 호출하여 설정하고 있습니다.
다시 앱을 실행시켜 사진을 촬영하면 새롭게 추가한 imageView위젯에 해당 사진이 표시되는 걸 확인할 수 있습니다.
'Mobile > Kotlin' 카테고리의 다른 글
[Kotlin] 프로세스(Process)와 스레드(Thread) (0) | 2021.01.05 |
---|---|
[Kotlin] 사진저장하고 가져오기 (4) | 2021.01.05 |
[kotlin] ORM라이브러리 Room (0) | 2020.12.30 |
[kotlin] SQLite - 연결및 사용하기 (0) | 2020.12.30 |
[kotlin] SQLite - SQLite Open Helper 구현하기 (0) | 2020.12.29 |