[16. 콘텐츠 프로바이더 컴포넌트]
[16-1. 콘텐츠 프로바이더 이해]
[콘텐츠 프로바이더]
-콘텐츠 프로바이더 : 앱의 데이터를 다른 앱과 공유할 때 사용
-데이터 : 대상 앱의 데이터베이스/파일/앱에 할당된 메모리 등에 존재
[콘텐츠 프로바이더 생성/등록]
<생성> -ContentProvider 클래스 상속받은 후, 내부에 onCreate() / getType() / query() / insert() / update() / delete() 함수 재정의 |
<등록> -이 역시 컴포넌트이므로 매니페스트에 등록 필수 -<provider> 태그로 등록. name 속성에 등록할 클래스명 지정 + authorities 속성에 식별 문자열 지정 필수 |
[콘텐츠 프로바이더 사용]
-인텐트와 관련 X
-필요한 순간에 시스템에서 자동 생성해주므로 내부에 재정의한 함수만 호출해주면 됨
① [외부 앱에서 콘텐츠 프로바이더 사용]
-매니페스트에 해당 앱 패키지 공개 설정해주어야 함
1) 대상앱 패키지명을 <package> 태그로 명시 OR
2) 사용하려는 콘텐츠 프로바이더의 authorities 속성을 <provider> 태그로 선언
② [시스템에 등록된 콘텐츠 프로바이더 사용]
-ContentResolver 객체 이용
-contentResolver 속성으로 ContentResolver 객체 얻은 후, 데이터 조작함수 호출함
delete() |
insert() |
query() |
update() |
-이 함수들의 첫 번째 매개변수는 대상 콘텐츠 프로바이더 식별하는 URI 객체.
-URI객체의 < URL 문자열 형식 >
1) 프로토콜명 + 호스트
content://com.example.test_provider
2) 프로토콜명 + 호스트 + (경로) : 경로는 선택사항이지만, 대개 조건명시에 사용
content://com.example.test_provider/user/1
-단어로 끝나면 : 단어에 해당하는 모든 데이터 의미
-숫자로 끝나면 : 숫자로 식별되는 데이터 의미
[16-2. 안드로이드 기본 앱과 연동]
⇒ [주소록 앱 연동]
① 주소록 앱 사용 퍼미션 설정
<uses-permission android:name=“android.permission.READ_CONTACTS”/>
② 주소록 목록 화면 띄우기 코드 작성
-인텐트로 목록 화면 실행
val intent = Intent(Intent.ACTION_PICK , ContactsContract.CommonDataKinds.Phone.CONTENT_URI)
//액션문자열 지정 //URi객체 연동 시 사용할 데이터 정보 상수값 지정
requestContactsLauncher.launch(intent) //시스템에 정의한 인텐트 전달
-인텐트 액션문자열 Intent.ACTION_PICK 으로 지정 -데이터 정보 Uri 객체에 연동 시 사용할 상수값 지정 -정의한 인텐트를 ActivityResultLauncher의 launch() 함수로 시스템에 전달 |
<데이터 정보 상수>
ContactsContract.Contacts.CONTENT_URI | 모든 사람 데이터 |
ContactsContract.CommonDataKinds.Phone.CONTENT_URI | 전화번호 있는 사람 데이터 |
ContactsContract.CommonDataKinds.Email.CONTENT_URI | 이메일 정보 있는 사람 데이터 |
③ 주소록에서 한 사람 선택 시 실행되는 함수
-출력된 목록 화면에서 사용자가 사람 선택하여 되돌아오면
ActiityResultCallback의 onActivityResult() 함수가 자동 실행됨
-이 함수의 매개변수로 주소록 앱에서 전달한 데이터 받을 수 있는데, 전달받은 URL 마지막 단어가 선택한 사용자 고유 식별값임
<콘텐츠 프로바이더 이용> : 식별값 이용 구체적인 추가 데이터 다시 요청
-주소록 앱의 콘텐츠 프로바이더를 이용함
-프로바이더 이용하여 가져올 데이터를 지정하는데, 지정값에 따라 데이터 가져옴
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME | 이름 |
ContactsContract.CommonDataKinds.Phone.NUMBER | 전화번호 |
⇒ [갤러리 앱 연동]
<이미지 작업 시 고려사항>
① 안드로이드에서 이미지는 Drawable 이나 Bitmap 객체로 표현 (둘은 상호호환O)
Drawable | 리소스 이미지 표현 |
Bitmap | 파일, 네트워크로 내려받은 이미지 표현 |
② Bitmap 객체는 BitmapFactory 클래스로 생성함
▶ <BitmapFactory 제공 Bitmap 생성 함수>: decode 로 시작
BitmapFactory.decodeByteArray() | byte[] 배열 데이터로 비트맵 생성 |
BitmapFactory.decodeFile() | 파일로부터 읽어들인 데이터로 생성 |
BitmapFactory.decodeResource() | 리소스 이미지로 비트맵 생성 |
BitmapFactory.decodeStream() | InputStream으로 읽은 데이터로 생성 |
③ BitmapFacory의 함수로 Bitmap 생성 시, OOM 오류 고려할 것
*OOM : 용량 커서 발생 오류
-생성 함수의 매개변수에 따로 옵션 지정 X -> 원본 그대로 읽어들여서 OOM 발생
-생성 함수의 매개변수에 옵션 지정할 것 : 이미지 크기 줄이기 inSampleSize 속성
④ 이미지 처리 라이브러리 이용이 더 효율적인 경우 존재 O : Glide/Picasso
[갤러리 앱 연동 방법]
Ⓐ ‘인텐트’로 갤러리 앱의 사진 목록 출력하기
<인텐트 세팅> -인텐트 액션 문자열 : Intent.ACTION_PICK 지정 -데이터 상수값 : MediaStore.Images.Media.EXTTERNAL_CONTENT_URI 지정 -타입 : image/* 로 지정 |
<지정한 인텐트 정보 전달> requestGalleryLauncher.launch(intent) //전달 |
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
intent.type = “image/*“
requestGalleryLauncher.launch(intent)
Ⓑ 갤러리 앱 사진 목록에서 사용자 선택 사진을 액티비티 화면에 출력하기
<inSampleSize값 옵션 지정하여 이미지 크기 줄이기> <이미지 불러오기 > -contentResolver.openInputStream(data!!.data!!) 구문 //갤러리 앱의 ‘콘텐츠 프로바이더’가 제공하는 InputStream 객체 가져오는 구문 //이 객체에 사용자가 선택한 사진 데이터 담겨있음 |
⇒ [카메라 앱 연동]
① [사진 데이터를 가져오는 방법 ]
-카메라 앱으로 사진 촬영 후 (파일로 저장X) 데이터만 넘겨주는 방식
<인텐트로 사진촬영 액티비티 실행>
-카메라 실행 -> 사용자 사진 촬영 후 -> 다시 내가 만든 앱으로 되돌아옴
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) //액션 문자열 지정
requestCameraThumbnailLauncher.launch(intent) //시스템에 전달
<카메라앱에서 넘어온 사진 데이터 가져오기>
requestCameraThumbnailLauncher = registerForACtivityResult(
ActivityResultContracts.StartsActivityForResult() )
{
val bitmap = it?.data?.extras?.get(“data”) as Bitmap
}
② [ 사진 파일을 공유하는 방법 ]
-카메라 앱으로 사진 촬영 후 (파일로 저장O) 저장 실패/성공 여부만 넘겨주는 방식
<파일 공유 ‘준비 작업’>
(1) 외장 메모리에 사진 저장할 파일 만들어 줘야 함 <파일 생성 함수> ▶getExternalStoragePublicDirectory() 로 파일 생성 : 모든 앱에서 이용 O 파일 생성 -> 이 함수 사용 시. 따로 퍼미션 설정 필요 ▶getExternalFilesDir() 로 파일 생성: 이 앱에서만 이용O 파일 생성 |
*API 레벨 24부터. “file://프로토콜” 구성 URI는 외부 노출 X : 엄격모드 적용
*따라서, 앱끼리 파일 공유하려면 content://프로토콜 구성 URI 이용 + 이 URI에 임시 접근 권한 부여 필요해짐
(2) FileProvider 클래스 사용 ▶파일 프로바이더용 XML 파일 -이 파일의 path 속성에 지정한 경로의 파일 권한 설정 -이 경로가 getExternalFilesDir() 함수로 파일 만들었을 때 파일 저장되는 위치 ▶매티페스트 파일에 ‘파일 프로바이더용 XML’ 파일을 등록 <provider>로 등록 시. 하위에 <meta-data> 의 resource 속성에 프로바이더용 XML 파일 지정 |
<코드에서 카메라 앱 연동>
① 파일 만들기
val timeStamp: String = SimpleDateFormat(“yyyyMMdd_HHmmss”).format(Date())
val storageDir : File? = getExternalFilesDir(Environment,DIRECTORY_PICTURES)
val file = File.createTempFile( //파일명 중복되지 않도록 날짜와 시간을 이용
“JPEG_${timeStamp}_”,
“.jpg”,
storageDir
)
filePath = file.absolutePath //나중에 파일 내용 읽을 때 사용 목적 파일 경로 저장
② 카메라 앱 실행 인텐트 준비
-앞에서 설정 정보 바탕으로 FileProvider 이용 Uri 객체 만들고
이를 카메라 앱 실행 인텐트의 엑스트라 데이터로 설정
val phothURI:Uri = FileProvider.getUriForFile(
this,
“com.example.test16.fileprovider”, file
)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
requestCameraFileLauncher.launch(intent)
③ 비트맵 이미지 생성
-촬영 후 다시 앱으로 돌아왔을 때 실행될 코드
requestCameraFileLauncher = registerForActiviryResult(
ActivityResultContracts.StartActivityForResult())
{
val option = BitmapFactory.Options()
option.inSampleSize = 10 //사이즈 줄이고
val bitmap = BitmapFactory.decodeFile(filePath, option) //비트맵 사진 생성
bitmap?.let{
binding.cameraFileResult.setImageBitmap(bitmap)
}
}
⇒ [지도 앱 연동]
(1) 인텐트 세팅 -액션문자열 Intent.ACTION_VIEW 지정 -데이터 정보에 보여줄 지도 특정위치 (geo: 위도, 경도) 지정한 URL 값 지정 (2) 세팅한 인텐트를 시스템에 전달 |
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(“geo: 37.5662952, 126.9779451”))
// (액션 문자열 지정 , 인텐트 데이터 정보에 (위도, 경도) 지정 )
startActivity(intent) //시스템에 전달
⇒ [전화 앱 연동]
(1) 인텐트 세팅 -액션문자열 Intent.ACTION_CALL 지정 -데이터 정보에 전화 걸 번호 데이터 지정 | “tel: 전화번호“ (2) 세팅한 인텐트를 시스템에 전달 |
val intent = INtent(Intent.ACTION_CALL, Uri.parse(“tel:02-120”))
startActivity(intent) //시스템에 전달
[16-3. 카메라, 갤러리 앱과 연동 앱 만들기] : 실습
[참고] : Do It 안드로이드 앱 프로그래밍 with 코틀린 |
'App(앱)_관련 공부 모음 > [교재] Andorid App_Kotlin 기반' 카테고리의 다른 글
18. [네트워크 프로그래밍] (0) | 2022.03.26 |
---|---|
17. [저장소에 데이터 보관] (0) | 2022.03.25 |
15. [서비스 컴포넌트] (0) | 2022.03.24 |
14. [브로드캐스트 리시버 컴포넌트] (0) | 2022.03.23 |
13. [액티비티 컴포넌트] (0) | 2022.03.18 |