안드로이드 전체

2.Intent

강용민 2021. 8. 15. 16:29

아래 모든 내용은 https://developer.android.com/guide/components/intents-filters?hl=ko에서 가져왔으며, 이해를 하기위해 적어놓은 것이다.

Intent는 메시징 객체로, 다른 앱 구성 요소로부터 작업을 요청하는 데 사용할 수 있다.


인텐트가 구성 요소 사이의 통신을 촉진하는 데는 여러 가지 방식이 있지만 기본적인 사용 사례는 크게 세 가지로 나눌 수 있다.

액티비티 시작

Activity는 앱 안의 단일 화면을 나타낸다. Activity의 새 인스턴스를 시작하려면 Intent를 startActivity()로 전달하면 된다. Intent는 시작할 액티비티를 설명하고 모든 필수 데이터를 담는다.

액티비티가 완료되었을 때 결과를 수신하려면, startActivityForResult()를 호출한다.

액티비티는 해당 결과를 이 액티비티의 onActivityResult 콜백에서 별도의 Intent 객체로 수신한다.

서비스 시작

Service는 사용자 인터페이스 없이 백그라운드에서 작업을 수행하는 구성 요소이다.

Android 5.0(API 레벨 21) 이상부터는 JobScheduler로 서비스를 시작할 수 있다.

서비스가 클라이언트-서버 인터페이스로 디자인된 경우, 다른 구성 요소로부터 서비스에 바인딩하려면 Intent를 bindService()에 전달하면 된다.

Android 5.0(API 레벨 21) 이하 버전은 Service 클래스의 메서드를 사용하면 서비스를 시작할 수 있다.

서비스를 시작하여 일회성 작업을 수행하도록 하려면(예: 파일 다운로드) Intent를 startService에 전달하면 된다.

(startService로 하면 Singleton이라 일회성에 적합한 것으로 보인다.)

Intent는 시작할 서비스를 설명하고 모든 필수 데이터를 담고 있다.

브로드캐스트 전달

브로드캐스트는 모든 앱이 수신할 수 있는 메시지이다. 시스템은 시스템이 부팅될 때 또는 기기가 충전을 시작할 때 등 시스템 이벤트에 대한 다양한 브로드캐스트를 전달한다.

Intent를 sendBroadcast() 또는 sendOrderedBroadcast()에 전달하면 다른 앱에 브로드캐스트를 전달할 수 있다.


인텐트 유형

명시적 인텐트는 인텐트를 충족하는 애플리케이션이 무엇인지 지정합니다. 이를 위해 대상 앱의 패키지 이름 또는 완전히 자격을 갖춘 구성 요소 클래스 이름을 제공한다.

명시적 인텐트는 일반적으로 앱 안에서 구성 요소를 시작할 때 쓴다. 시작하고자 하는 액티비티 또는 서비스의 클래스 이름을 알고 있기 때문이다.

예를 들어, 사용자 작업에 응답하여 새로운 액티비티를 시작하거나 백그라운드에서 파일을 다운로드하기 위해 서비스를 시작하는 것 등이 여기에 해당됩니다.

암시적 인텐트는 특정 구성 요소의 이름을 대지 않지만, 그 대신 수행할 일반적인 작업을 선언하여 다른 앱의 구성 요소가 이를 처리할 수 있도록 해준다.

예를 들어 사용자에게 지도에 있는 한 위치를 표시하고자 하는 경우, 암시적 인텐트를 사용하여 해당 기능을 갖춘 다른 앱이 지정된 위치를 지도에 표시하도록 요청할 수 있다.

 

그림 1은 액티비티를 시작할 때 인텐트를 사용하는 법을 나타낸 것이다. Intent 객체가 특정 액티비티 구성 요소를 명시적으로 지정하면 시스템이 해당 구성 요소를 즉시 시작한다.

그림 1. 암시적 인텐트가 시스템을 통해 전달되어 다른 액티비티를 시작하는 방법  [1] 액티비티 A 가 작업 설명이 있는  Intent 를 생성하여 이를  startActivity() 에 전달합니다.  [2]  Android 시스템이 모든 앱에서 해당 인텐트와 일치하는 인텐트 필터를 검색합니다. 일치하는 항목을 찾으면,  [3]  시스템이 해당 액티비티의  onCreate()  메서드를 호출하여 이를  Intent 에 전달하고, 일치하는 액티비티( 액티비티 B )를 시작합니다.

암시적 인텐트를 사용하면 Android 시스템에서 시작할 적절한 구성 요소를 찾습니다. 이때 인텐트의 내용을 기기에 있는 다른 여러 앱의 매니페스트 파일에서 선언된 인텐트 필터와 비교하는 방법을 사용한다.

해당 인텐트와 일치하는 인텐트 필터가 있으면 시스템에서 해당 구성 요소를 시작하고 이를 Intent 객체를 전달한다.

호환되는 인텐트 필터가 여러 개인 경우, 시스템에서 대화상자를 표시하여 사용자가 어느 앱을 사용할지 직접 선택할 수 있게 한다.

인텐트 필터란 앱의 매니페스트 파일에 들어 있는 표현으로, 해당 구성 요소가 수신하고자 하는 인텐트의 유형을 나타낸다.

예를 들어 액티비티에 대한 인텐트 필터를 선언하면 다른 여러 앱이 특정한 종류의 인텐트를 가지고 액티비티를 직접 시작할 수 있다. 마찬가지로 액티비티에 대한 인텐트 필터를 선언하지 않는 경우, 이것은 명시적인 인텐트로만 시작할 수 있다.

더보기

주의 :

앱의 보안을 보장하려면 Service를 시작할 때에는 항상 명시적 인텐트만 사용하고 서비스에 대한 인텐트 필터는 선언하지 말아야 한다.

암시적 인텐트를 사용하여 서비스를 시작하면 보안 위험을 초래합니다. 인텐트에 어느 서비스가 응답할지 확실할 수 없고, 사용자는 어느 서비스가 시작되는지 볼 수 없기 때문이다.Android 5.0(API 레벨 21)부터 시스템은 개발자가 암시적 인텐트로 bindService()를 호출하면 예외를 발생시킨다.


인텐트 빌드

Intent 객체에는 Android 시스템이 어느 구성 요소를 시작할지 판별하는 데 사용하는 정보가 담겨 있다.

또한 수신자 구성 요소가 작업을 적절히 수행하기 위해 사용할 정보(예: 수행할 작업 및 조치를 취할 데이터 위치)도 이 안에 담겨 있다.

Intent에 포함된 기본 사항은 다음과 같다.

 

구성 요소 이름

시작할 구성 요소의 이름이다.

이것은 선택 항목이지만, 인텐트를 명시적인 것으로 만들어주는 중요한 정보이다. 다시 말해 이 인텐트는 구성 요소 이름이 정의한 앱 구성 요소에만 전달되어야 한다는 뜻이다.

구성 요소 이름이 없으면 해당 인텐트는 암시적이며, 인텐트를 수신해야 하는 구성 요소는 다른 인텐트 정보를 기반으로 시스템이 결정한다.예를 들어 Service를 시작하는 경우, 항상 구성 요소 이름을 지정해야한다. 그렇지 않으면 인텐트에 어느 서비스가 응답할지 확신 할 수 없고, 사용자도 어느 서비스가 시작되는지 볼 수 없게 된다.

앱에서 특정한 구성 요소를 시작해야 하는 경우에는 구성 요소 이름을 지정해야 한다.

Intent의 필드는 ComponentName 객체로 이것을 지정하려면 대상 구성 요소의 완전히 정규화된 클래스 이름(앱의 패키지 이름 포함)을 사용해야 한다.예를 들어 com.example.ExampleActivity를 쓰면된다. 구성 요소 이름을 설정하려면 setComponent(), setClass(), setClassName()을 사용하거나 또는 Intent 생성자를 사용한다.

작업

수행할 일반적인 작업을 나타내는 문자열이다.

BroadCast Intent의 경우,  이미 실행되어 보고되는 작업이다. 이 작업은 대체로 나머지 인텐트의 구조를 결정한다. 특히, 데이터와 엑스트라에 포함되는 정보가 결정된다.

본인의 앱 내에 있는 인텐트가 사용할 작업(또는 다른 앱이 사용하여 본인의 앱 안의 구성 요소를 호출하게 할 작업) 을 직접 지정할 수도 있지만, 보통은 Intent 클래스나 다른 프레임워크 클래스가 정의한 작업 상수를 지정해야 한다.

 

다음은 액티비티를 시작하는 데 쓰이는 보편적인 작업이다.

  • ACTION_VIEW
    액티비티가 사용자에게 표시할 수 있는 어떤 정보를 가지고 있을 때, startActivity()가 이쓴 인텐트에서 사용한다.
  • ACTION_SEND
    공유 인텐트라고도 하며, 사용자가 다른 앱을 통해 공유할 수 있는 데이터를 가지고 있을 때 startActivity()가 있는 인텐트에서 사용해야 한다.

자세한 작업업 내용은 Intent 클래스에 있다.

인텐트에 대한 작업을 지정하려면 setAction() 또는 Intent 생성자를 사용하면 된다.

데이터(이해안됨)

작업을 수행할 데이터 및 해당 데이터의 MIME 유형을 참조하는 URI이다.

제공된 데이터의 유형을 나타내는 것을 일반적으로 인텐트의 작업이다. 예를 들어 인텐트가 ACTION_EDIT인 경우, 데이터에 편집할 문서의 URI가 들어 있어야 한다.

인텐트를 생성할 때는 URI 외에 데이터유형(데이터의 MIME 유형)을 지정하는 것이 중요한 경우가 많다.예를 들어 이미지를 표시할 수 있는 액티비티라면 오디오 파일은 재생하지 못할 것이다.데이터의 MIME 유형을 지정하면 Android 시스템이 인텐트를 수신하기 가장 좋은 구성 요소를 찾는 데 도움이 된다.

다만 때로는 MIME 유형을 URI를 통해 추론할 수 있다. 특히 데이터가 content: URI일 때 추론하기 쉽ㄴ다.

content: URI는 데이터가 기기에 위치하고 ContentProvider가 제어한다는 것을 의미하며, 따라서 데이터 MIME유형이 시스템에 표시된다.

나중에 이해되면 더 씀.카테고리도 모르겠음

엑스트라

요청된 작업을 수행하는데 필요한 추가 정보가 담긴 키,값 쌍이다. 몇몇 작업이 특정한 종류 데이터 URI를 사용하는 것과 마찬가지로, 몇몇 작업은 특정한 엑스트라도 사용한다.

다양한 putExtra() 메서드로 엑스트라 데이터를 추가할 수 있다. 각 메서드는 키 이름과 값, 이렇게 두 개의 매개변수를 취한다.

또한 모든 엑스트라 데이터를 포함한 Bundle 객체를 만든 다음 Bundle을 Intent에 putExtra()로 삽입할 수도 있다.

예를 들어 ACTION_SEND로 이메일을 전송할 인텐트를 생성하는 경우 받는 사람 수신자를 지정할 때 EXTRA_EMAIL키를 사용한 다음, 제목은 EXTRA_SUBJECT키로 지정하면 된다.

Intent 클래스는 표준화된 데이터 유형에 대해 여러 가지 EXTRA_* 상수를 지정한다.

플래그

플래그는 Intent 클래스에서 정의되고, 인텐트에 대한 메타데이터와 같은 기능을 한다.

이런 플래그는 Android 시스템에 댁티비티를 시작할 방법에 대한 지침을 줄 수 있고(예를 들어 액티비티가 어느 작업에 소속되어야 하는지 등) 액티비티를 시작한 다음에 어떻게 처리해야 하는지도 알려줄 수 있다.(예를 들어 해당 액티비티가 최근 액티비티 목록에 소속되는지 여부)

자세한 내용은 setFlags() 메서드를 참조하세요.