[안드로이드스튜디오_문화][Intent && PendingIntent]

기말 지하기포·2023년 11월 7일
0

Intent

Intent AndroidDeveloper 링크

=> https://developer.android.com/guide/components/intents-filters?hl=ko

Intent 정의

-인텐트는 "현재 앱 또는 다른 앱"의 구성요소[Activity , Service , Broadcast Receiver , Content Provider]에게 작업을 요청하는데 사용하는 메시징 객체이다.

-즉, 인텐트는 A가 B에 일을 시킬 수 있도록 메시지를 전달하는 기능을 한다고 생각하면 좋다.

Intent 유형

명시적 Intent

-명시적 Intent는 해당 인텐트 메시징 객체에 작성된 명령서를 전달하고자 하는 Component를 정확하게 지정해주는 것을 의미한다.

Activity 시작

-특정 액티비티를 시작하려면 Intent(context , 이동하고 싶은 Activity::class.java)를 사용 하면된다.

  • 예시코드(1)
Intent(applicationContext , SecondActivity::class.java)
	.also { startActivity(it) }

-

Service 시작

-Service 글 참고

Broadcast Receiver 시작

-Broadcast Receiver 글 참고

특정 애플리케이션 시작

-특정 애플리케이션을 시작하기 위해서는 해당 애플리케이션의 package 이름을 알아낸 후 startActivity의 parameter에 들어갈 intent의 package 속성에 넣어주면 된다.

  • 유튜브 앱 여는 예시코드(1)
1. terminal에 abd shell 입력 2. pm list packages | grep youtube 입력
Intent(Intent.ACTION_MAIN).also {
	it.`package` = "com.google.android.youtube"
	try {
		startActivity(it)
	} catch (e: ActivityNotFoundException) {
		println("앱 설치 패이지로 넘어가는 작업")
	}
}

-

암시적 Intent

-암시적 Intent는 해당 인텐트 메시징 객체가 전달할 수 있는 "Component의AndroidManifest.xml의 Intent Filter에 있는 정보"를 작성해주면 , Intent Filter에 대한 정보와 일치하는 컴포넌트를 AndroidSystem에서 찾아서 실행하게 되는 것을 의미한다.

-어떤 앱을 실행할지는 사용자가 결정할 수 있게 해준다.

Intent-Filter(only implicit intent)

-안드로이드 시스템이 암시적 인텐트를 수신하면 , 안드로이드 시스템은 해당 인텐트에 대해서 최선의 액티비티를 찾기위해서 AndroidManifest.xml에 설정되어있는 intent-filter와 수신받은 암시적 인텐트를 비교한다.

-그렇다면 수신받은 implicit-intent와 자신의 intent-filter와 비교를 할 때 무엇을 기준으로 하는 것일까? 바로 action / category / data 태그를 기준으로 비교한다.

-각각의 태그들은 자신만의 고유한 특성을 지니며 필요하지 않다는 판단이 든다면 태그를 선언하지 않아도 괜찮다.

action

-action 태그는 implicit-intent가 수행하려고 하는 구체적인 작업을 정의하는 태그이다. 문자열로서 사용자가 정의하는 것도 가능하다.

-action 태그에 있는 작업의 종류과 implicit-intent에 지정된 작업들 중 하나 이상 일치해야만 intent-filter를 통과 할 수 있다. 일치하는 작업이 없다면 intent-filter를 통과하지 못하므로 해당 intent는 실행되지 않는다.

-implicit-intent에 지정된 작업이 없을 때, intent-filter에 하나 이상의 action이 정의되어 있다면 해당 intent는 intent-filter를 통과 할 수 없어서 intent가 실행되지 않는다.

-implicit-intent에 지정된 작업이 없을 때, intent-filter에도 지정된 작업이 없다면 해당 intent는 intent-filter를 통과 할 수 있다.

  • 예시코드(1)
<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

category

-category 태그는 implicit-intent가 작업(action태그)을 보완하는 역할을 해서 인텐트 필터기능을 강화하며, 해당 인텐트를 처리할 수 있는 컴포넌트의 범윌르 action 태그보다 더 정확하게 정의해준다.

-implicit intent에 category를 설정해주지 않으면 자동으로 DEFAULT를 추가해준다.

-implicit-intent가 category 테스트를 통과하기 위해서는 implicit-intent의 모든 카테고리가 intent-filter 내부의 카테고리에 포함되어야 한다. implicit-intent의 카테코리 설정 중 하나라도 intent-filter 내부의 카테고리에 포함되지 않으면 통과 할 수 없다.

  • 예시코드(1)
<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

data

-data 태그는 implicit-intent가 포함해야하는 데이터 유형(MIME 미디어 유형)과 URI 구조를 나타내는 태그입니다.

-MIME 미디어 유형은 "큰범위/작은한개" 이런 식으로 작성되면 작은한개는 너무 많기 때무에 링크를 첨부하였고 큰범위는 [Image/],[audio/],[application/],[text/],[video/] 이렇게 5개의 데이터 유형이 존재한다.

-URI 구조는 [scheme : ]://[host : ]:[port : ]:[path : ] 이렇게 이루어져 있고, 예시 URI는 아래 있다. 보통 배포된 사이트는 port 번호가 없기 때문에 굳이 신경쓰지 않아도 될 듯 하다.

https://naver.com:8080/mnews/article/015/0004946062?sid=101

intent-filter에 scheme이 지정되지 않으면 host가 무시되고 , host가 지정되지 않으면 port가 무시되고 , scheme과 host가 둘 다 지정되지 않으면 path가 무시된다.

-1. URI와 MIME 유형 없는 인텐트 : intent-filter에 data 태그가 없는 경우에만 테스트를 통과한다.

-2. URI만 있는 인텐트 : 인텐트의 URI가 intent-filter의 URI 패턴과 일치하고, 필터에 MIME 유형이 지정되지 않은 경우에만 테스트를 통과한다.

-3. MIME 유형만 있는 인텐트: 인텐트의 MIME 유형이 intent-filter의 MIME 유형과 일치하고, intent-filter에 URI 패턴이 지정되지 않은 경우에 테스트를 통과한다.

-4. URI와 MIME 유형이 있는 인텐트: implicit-intent의 URI 패턴이 intent-filter의 MIME 유형과 일치하고, implicit-intent의 MIME 유형과 intent-filter의 MIME 유형과도 일치하는 경우에 테스트를 통과한다.

  • 예시코드(1)
<intent-filter>
    <data android:mimeType="image/*" />
</intent-filter>
  • 예시코드(2)
<intent-filter>
    <data android:scheme="http" android:mimeType="video/*" />
</intent-filter>
  • 예시코드(3)
<intent-filter>
	<data android:scheme="https" />
	<data android:host="geonnuyasha.com" />
</intent-filter>
  • 예시코드(4)
<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
</intent-filter>




PendingIntent

PendingIntent 정의

-Intent를 바로 실행하지 않고 특정 시점 즉, 사용자가 원하는 시점에 Intent를 실행 할 수 있게 도와주는 것이다.

-PendingIntent는 Intent개념과 지연의 개념을 합친 것으로 볼 수 있다.

-Intent에 실행 예약을 걸어두는 것이라고 생각하면 좋다.

-즉, A가 B에게 일을 시킬 때 '특정 시간'에 일을 시작하라고 예약을 걸어두은 메시지를 보낸다고 생각하면 된다.

PendingIntent AndroidDeveloper 링크

=>https://developer.android.com/reference/kotlin/android/app/PendingIntent

PendingIntent 생성

getActivity

-내가 원하는 시점에 해당 Activity를 실행 할 수 있게 해준다.

getBroadcast

-내가 원하는 시점에 해당 BroadcastReceiver를 실행 할 수 있게 해준다.

-PendingIntent.getBroadcast(context , requestCode , intent , flags)로 알림을 받아 올 수 있다. 각 parameter에 대한 설명은 아래에 있다.

-requestCode는 PendingIntent를 구별하는 역할을 한다.

-intent는 어디로 가서 무엇을 할 지에 대한 정보를 가지고 있다.

-flags는 PendingIntent에 대한 여러 설정을 해준다.

-

getService

-내가 원하는 시점에 해당 Service를 실행 할 수 있게 해준다.

PendingIntent FLAG 종류

-flags라는 변수에 PendingIntent의 FLAG를 설정한 것을 넣어주면 된다. API31 이상에서는 FLAG_IMMUTABLE 또는 FLAG_MUTABLE 둘 중 하나는 반드시 Flag에 넣어줘야 한다.

FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT

-PendingIntent가 implicit-intent를 사용 할 수 있도록 허용한다. 해당 플래그를 사용하지 않고 implicit-intent를 사용하면 예외가 발생한다.

FLAG_CANCEL_CURRENT

-이전에 생성한 PendingIntent를 취소하고 새로운 PendingIntent를 생성한다.

FLAG_IMMUTABLE

-생성할 PendingIntent를 수정 할 수 없는 PendingIntent로서 설정한다.

FLAG_MUTABLE

-생성할 PendingIntent를 수정 할 수 있는 PendingIntent로 설정한다.

FLAG_NO_CREATE

-PendingIntent가 이미 존재 할 경우에만 PendingIntent를 반환하고 없으면 null을 반환하도록 설정한다. 즉, 새로운 PendingIntent를 만들지 않는다.

FLAG_ONE_SHOT

-해당 PendingIntent는 한 번만 사용 될 수 있고 , 한 번 실행된 이후에는 더 이상 사용 할 수 없게 설정한다.

FLAG_UPDATE_CURRENT

-이미 존재하는 PendingIntent가 있을 때 , 해당 PendingIntent의 내용을 업데이트 해서 재사용 할 수 있게 한다. 즉, PendingIntent를 새로 생성하지 않고 기존의 것을 업데이트 해서 사용 할 수 있다.

-아래는 Flag를 사용해서 PendingIntent를 설정해주는 예시코드이다.

  • 예시코드(1)
val intent = Intent(context, AlarmService::class.java)

val flags = PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT

val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, flags)
profile
포기하지 말기

0개의 댓글