[Android] 안드로이드 URL, URI 정의
URL은 웹 브라우저 주소창에 입력하는 사이트 주소 혹은 특정 파일의 경로 등과 같이 생각했는데, 안드로이드 프로그래밍을 시작하면서 정의가 모호해지기 시작했다. 이 와중에 안드로이드 프로그래밍에서 자주 등장하는 URI는 정확히 무엇인지 둘 다 이번 기회에 확실히 정리해보기로 했다.
URI
Uniform Resource Identifier, 리소스를 구분하는 식별자.
안드로이드에서 URI의 역할은 리소스(외부 앱, 이미지, 텍스트 등)에 접근할 수 있는 식별자 역할.
무언가를 사용하기 위해 가져오거나 실행하기 위한 식별 정보
// 1. URL
var uri = Uri.parse("http://google.com")
// 2. URI 상수
var uri2 = Uri.parse(ContactsContract.CommonDataKinds.Phone.CONTENT_URI) // var uri2 = Uri.parse("content://com.android.contacts/data/phones")
// 3. 안드로이드 URI 형식
var uri3 = Uri.parse("tel:02-120")
URL
Uniform Resource Locator, 리소스가 있는 경로(Location)에 대한 식별자.
웹 브라우저에서 사용하는 웹 주소가 URL로써, 컴퓨터 네트워크 상에 리소스가 어디있는지 알려주기 위한 규약이다.
URL은 URI에 포함되는 개념이다. (URL ⊂ URI)
안드로이드에서는 이러한 URL 말고도 모바일 기기에서 지원하는 URI 형식도 사용할 수 있다.
<scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
- scheme(protocol) : 사용할 프로토콜. (ex: http, https, ftp 등)
= 애플리케이션 계층 통신 규약. - host : 접근할 대상의 도메인 이름 또는 IP Address, 애플리케이션 패키지명.
- port : 메시지를 받아야 하는 프로세스가 있는 위치.
- path(query) : 호스트 주소 내에서 디렉터리 경로(path)를 표시하거나, 쿼리 조건을 명시.
Uri 객체
URI를 나타내는 타입이며, Uri.parse() 함수로 직접 지정해도 되고 다른 클래스에 정의된 상수를 이용해도 된다.
반환 타입 | 메서드명 | 설명 |
Uri | parse(String uriString) | String 문자열을 Uri 객체로 변환 |
String | toString() | Uri 객체를 String 문자열로 변환 |
Uri | fromFile(File file) | 파일로부터 Uri 생성 |
String | getScheme() | URI의 스키마(scheme) 반환 = scheme |
String | getHost() | URI의 호스트(host) 반환 = host |
String | getPort() | URI의 포트(port) 반환 = port |
String | getPath() | URI의 경로(path) 반환 = path |
Uri 객체가 매개변수나 반환값으로 사용되는 예
1. Intent 객체의 data 프로퍼티
Intent는 실행할 컴포넌트 정보를 담아서 시스템에 전달하는 객체로, Intent객체에서 getData() 메서드로 얻는 data 속성이 Uri 타입이다. Intent 객체가 어떤 데이터를 갖고 있는지, 어느 컴포넌트로 연결 될지에 대한 정보를 나타낸다.
ex) 기본 웹 브라우저로 Google 사이트에 접속하는 Intent의 data 프로퍼티 값 출력
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("http://google.com")
Log.d("test", "Uri : ${intent.data}")
getContent.launch(intent)
> Uri : http://google.com
안드로이드 기본 앱 중 하나인 연락처 앱을 실행하는 Intent의 data 프로퍼티 값 출력
val intent = Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI)
Log.d("test", "Uri : ${intent.data}") // data 값 확인용
getContent.launch(intent)
> Uri : content://com.android.contacts/data/phones
2. ContentProvider 사용
ContentResolver 객체를 사용해 시스템에 등록된 콘텐츠 프로바이드를 사용할 때 delete(), insert(), query() 등 함수의 매개변수로 Uri 객체가 사용된다.
public final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
getContent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == RESULT_OK) {
val cursor = contentResolver.query(
it.data!!.data!!,
arrayOf<String>(
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
),
null,
null,
null
)
// ...
}
}
인텐트를 통해 실행된 연락처 앱에서 연락처를 선택하면 메인 액티비티로 돌아오면서 결과콜백 함수(위 코드의 registerForActivityResult 함수의 두번째 매개변수 람다식)에 ActivityResult 객체를 반환하게 되는데, ActivityResult.data 프로퍼티가 Intent 타입이고, 위에서 설명했든 Intent객체는 data 프로퍼티로 Uri 객체를 가지고 있다. 디버깅에서 이 값을 찾아보면 "content://com.android.contacts/data/3" 과 같이 되어 있다.
- 프로토콜(scheme) : content
- 호스트(host) : com.android.contacts
- 경로(path) : /data/3
- = 연락처 앱(PackageName : com.android.contacts)의 data 테이블에서 3으로 식별되는 데이터를 가져왔다는 뜻.
URL과 URI가 함께 언급되는 이유
예를 들어 시스템에 등록된 콘텐츠 프로바이더를 사용할 때 쓰는 ContentResolver 객체에는 아래와 같은 메서드가 있다.
public final int delete(Uri url, String where, String[] selectionArgs)
public final Uri insert(Uri url, ContentValues values) {}
public final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
public final int updata(Uri uri, ContentValues values, String where, String[] selectionArgs)
다른 매개변수는 볼 필요없이 각 메서드들에 선언된 Uri 타입의 매개변수만 봤을 때, 모두 같은 Uri 타입이지만 어떤 매개변수명은 url로 기재되어 있는 한편 어떤 건 uri로 기재되어있다. 이 두 개념이 함께 사용되는 이유는 URI라는 개념안에 URL이 포함되어 있기 때문이다. ( URL ⊂ URI )
URI는 리소스를 식별할 수 있는 방식이며, URL은 그 중에서 경로를 사용해 리소스를 식별하는 걸 말한다.
참고자료
- Android Developers Uri, https://developer.android.com/reference/android/net/Uri
- URI, URL, URN 의 차이 한 번에 정리하기, https://kotlinworld.com/96#URI%EC%--%--%--URL%-C%--URN%EC%-D%--%--%EA%B-%--%EA%B-%--