사진을 찍어서 전송하는 기능을 넣어야 해서 레퍼를 찾아보는데..
거의 자바로 만들어진 예제라 애좀 먹었다.
그리고 일단 자바를 잘 모르기 때문에..더 힘들었다.
그래서 겨우겨우 만들고 포스팅을 위해 아예 프로젝트 새로 만들어서 카메라 사진 찍는 기능만 새로 만듬.
(필요하신 분은 요청하시면 메일로 프로젝트 보내드릴꼐요)
기능설명 :
그냥 xml에 imageView 하나 올려놓고 그거 누르면 카메라로 전환되고 사진 찍으면 찍은 사진이 imageView에 보이는 예제입니다
자 설정부터 가시지요..
AndroidManifest파일입니다.
일단 권한을 줘야하지요
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
이부분을 추가해주세요위치는 <manifest xmlns....pakage="..> 이 다음입니다.
그리고 나중에 activity안에 소스를 위해
<activity></activity> 모든 엑티비티 테그 다음에
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.camera.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
프로바이더 부분 추가해주셍세요 저기authorities는 패키지 명입니다. 뒤에 fileProvider 앞에가요..
그리고 meta-data부분에 resource는 res 폴더아래 소스 디렉토리를 "xml"이라는 이름으로 만들고 그 안에 file_paths.xml이라고 하나 만들어두세요
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path path="Android/data/com.example.camera/" name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>
이렇게요 사진찍은 파일을 저장하는데 필요한 부분인듯 싶습니다(저도 기초가 없는 터라..자세힌 몰라요 아시는 분은 덧글로 설명 해주시면 매우 감사할것같아요
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:layout_width="191dp"
android:layout_height="175dp" app:srcCompat="@android:drawable/ic_menu_camera"
tools:layout_editor_absoluteY="218dp" android:id="@+id/imageView" tools:layout_editor_absoluteX="119dp"/>
<ImageView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/iv_view"/>
</android.support.constraint.ConstraintLayout>
매우 간단해요 ㅋ
이제 mainActivity입니다
package com.example.camera
import android.app.Activity
import android.app.AlertDialog
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.provider.Settings
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v4.content.FileProvider
import android.util.Log
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.io.IOException
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.*
class MainActivity : AppCompatActivity() {
val MY_PERMISSION_STRORAGE=111
var MY_PERMISSION_CAMERA=1111
var REQUEST_TAKE_PHOTO=2222
var REQUEST_TAKE_ALBUM=3333
var REQUEST_IMAGE_CROP=4444
var mCurrentPhotoPath:String?=null
var imageUri: Uri?=null
var photoURI: Uri?=null
var albumURi: Uri?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
checkPermission()
imageView.setOnClickListener {
captureCamera()
}
}
fun captureCamera(){
var state= Environment.getExternalStorageState()
try{
if(Environment.MEDIA_MOUNTED.equals(state)){
var takePictureIntent= Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if(takePictureIntent.resolveActivity(packageManager)!=null){
var photoFile: File?=null
try{
photoFile=createImageFile()
}catch(e: IOException){
Log.e("CaptureCameraError",e.toString())
}
if(photoFile!=null){
//getIriForFile의 두번쨰 인자는 MAnifest provider의 authorits와 일치해야함
var providerURI= FileProvider.getUriForFile(this,"com.example.camera.fileProvider",photoFile)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,providerURI)
startActivityForResult(takePictureIntent,REQUEST_TAKE_PHOTO)
}
}
}else{
Toast.makeText(this,"저장공간이 접근 불가능한 기기입니다", Toast.LENGTH_SHORT).show()
}
}catch (e: Exception)
{
e.printStackTrace()
}
}
fun getDateStringhhddss():String{
//fid_년월일시분초_1
val tz = TimeZone.getTimeZone("Asia/Seoul")
val gc = GregorianCalendar(tz)
var year = gc.get(GregorianCalendar.YEAR).toString()
var month = (gc.get(GregorianCalendar.MONTH).toInt()+1).toString()
if(month.length==1){
month="0" + month
}
var day = gc.get(GregorianCalendar.DATE).toString()
if(day.length==1){
day="0"+day
}
var hour=gc.get(GregorianCalendar.HOUR).toString()
if(hour.length==1){
hour="0"+hour
}
var minute=gc.get(GregorianCalendar.MINUTE).toString()
if(minute.length==1){
minute="0"+minute
}
var second=gc.get(GregorianCalendar.SECOND).toString()
if(second.length==1){
second="0"+second
}
return year+month+day+hour+minute+second
}
fun createImageFile() :File{
var timeStamp= SimpleDateFormat("yyyyMMdd").format(Date())
var sequence=1
var imageFileName=getDateStringhhddss() +"_"+ sequence.toString()
//m_area+"_"+m_device+"_"+timeStamp+ "_"+sequence.toString()
var imageFile:File?=null
var storageDir=File(Environment.getExternalStorageDirectory(),"Kotlin")
imageFileName=imageFileName + ".jpeg"
while(File(storageDir,imageFileName).exists()){
sequence++
imageFileName=getDateStringhhddss() +"_1.jpeg"
}
if(!storageDir.exists()) {
Log.i("mCurrentPhotoPAth1", storageDir.toString())
storageDir.mkdirs()
}
imageFile=File(storageDir,imageFileName)
mCurrentPhotoPath=imageFile.absolutePath
return imageFile
}
fun cropImage(){
Log.i("cropImage","Call")
Log.i("CropImage","PhotoURI :" + photoURI + " / albumURI : " + albumURi)
var cropIntent=Intent("com.android.camera.action.CROP")
cropIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
cropIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
cropIntent.setDataAndType(photoURI,"image/*")
cropIntent.putExtra("aspectX",1)
cropIntent.putExtra("aspectY",1)
cropIntent.putExtra("scale",true)
cropIntent.putExtra("output",albumURi)
startActivityForResult(cropIntent,REQUEST_IMAGE_CROP)
}
fun getAlbum(){
Log.i("getAlbum","call")
var intent= Intent(Intent.ACTION_PICK)
intent.setType("image/*")
intent.setType(android.provider.MediaStore.Images.Media.CONTENT_TYPE)
startActivityForResult(intent,REQUEST_TAKE_ALBUM)
}
fun galleryAddPic(){
Log.i("galleryAddPic","Call")
var mediaScanIntent=Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
var f=File(mCurrentPhotoPath)
var contentUri=Uri.fromFile(f)
mediaScanIntent.setData(contentUri)
sendBroadcast(mediaScanIntent)
Toast.makeText(this,"사진이 앨범에 저장되었습니다",Toast.LENGTH_SHORT).show()
imageView.setImageURI(contentUri)
}
fun checkPermission(){
if(ContextCompat.checkSelfPermission(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
// 다시보지 않기 버튼을 만드려면 이부분에 바로 요청을 하도록 하면 됨
var permissionArray=arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,android.Manifest.permission.READ_EXTERNAL_STORAGE,android.Manifest.permission.CAMERA)
// ActivityCompat.requestPermissions(this,permissionArray,MY_PERMISSION_STRORAGE)
if((ActivityCompat.shouldShowRequestPermissionRationale(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE))
|| ActivityCompat.shouldShowRequestPermissionRationale(this,android.Manifest.permission.CAMERA)){
AlertDialog.Builder(this)
.setTitle("알람")
.setMessage("저장소 권한이 거부되었습니다. 사용을 원하시면 설정에서 해당 권한을 직접 허용하셔야 합니다.")
.setNeutralButton("설정", DialogInterface.OnClickListener { dialog, which ->
var intent=Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
intent.setData(Uri.parse("package:" + packageName))
startActivity(intent)
})
.setPositiveButton("확인", DialogInterface.OnClickListener { dialog, which ->
finish()
})
.setCancelable(false)
.create()
.show()
}else{
var permissionArray=arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,android.Manifest.permission.CAMERA)
ActivityCompat.requestPermissions(this,permissionArray,MY_PERMISSION_CAMERA)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(resultCode, resultCode, data)
when(requestCode){
REQUEST_TAKE_PHOTO->
if(resultCode== Activity.RESULT_OK) {
try {
Log.i("REQUEST_TAKE_PHOTO", "OK")
galleryAddPic()
iv_view.setImageURI(imageUri)
} catch (e: Exception) {
Log.e("REQUEST_TAKE_PHOTO",e.toString())
}
}else{
Toast.makeText(this,"사진찍기를 취소하였습니다",Toast.LENGTH_SHORT).show()
}
REQUEST_TAKE_ALBUM ->
if(resultCode== Activity.RESULT_OK) {
if(data==null){
try{
var albumFile:File?=null
albumFile=createImageFile()
photoURI=data
albumURi=Uri.fromFile(albumFile)
cropImage()
}catch(e:Exception){
Log.e("TAKE_ALBUM_SINGLE ERROR",e.toString())
}
}
}
REQUEST_IMAGE_CROP->
if(resultCode== Activity.RESULT_OK){
galleryAddPic()
iv_view.setImageURI(albumURi)
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when(requestCode){
MY_PERMISSION_CAMERA->
for(i in grantResults){
if(i <0){
Toast.makeText(this,"해당 권한을 활성화 하셔야 합니다",Toast.LENGTH_SHORT).show()
}
}
}
}
}
군더더없는 그냥 진짜 앱 실행했을 때 카메라와 저장공간 권한 요청하고
이미지뷰누르면 카메라 전환되고 찍으면 이미지뷰에 사진 표시하는 딱 그기능만 있습니다
'Kotlin' 카테고리의 다른 글
사진파일 전송하기 (MultiPart Request) (0) | 2020.01.21 |
---|---|
이전 값 기억하기 (0) | 2020.01.21 |
파일 저장방법 (0) | 2020.01.21 |
안드로이드 권한 주기 (0) | 2020.01.21 |
Kotlin 안드로이드 다이얼로그 사용법 (0) | 2020.01.21 |