티스토리 뷰
Intent에 의미를 부여하는 여섯 가지 정보이다.
(위 정보들이 Intent에 저장되어 전달될 수 있고, 이러한 정보들에 따라서 해당 Intent에 의미가 부여된다는 의미이다.)
인텐트 정보의 주 목적은 특정 컴포넌트에 대한 실행 정보를 넣어서 해당 컴포넌트를 실행하고, 실행되는 컴포넌트에 원하는 데이터를 전달하는 것이다.
명시적 인텐트
→ 실행할 액티비티 컴포넌트를 정확하게 명시하는 것.
( Package와 Class명을 정확하게 명시하는 것이다. )
* 명시적 인텐트는 보안상 자기 패키지 내부의 액티비티를 실행할 때만 사용한다.
즉, 내가 직접만든 액티비티 등의 컴포넌트로 전환할 때 사용한다는 말이다.
( 추가로 외부에서 우리앱을 실행하지 못하도록 막아줘야한다. )
→ android:exported="false"; (Default가 false)
→ 이건 AndroidManifest.xml 상에 activity에 대한 정보를 넣어줄 때 각각 추가해줘야 한다.
암시적 컴포넌트는 android:exported가 기본적으로 True로 설정된다. 암시전 컴포넌트의 경우 외부에 공개 목적으로 존재하는 컴포넌트이기 때문이다. (Broadcast Receiver, Service ..? )
외부 패키지에 있는 Activity를 활성화하기 위해 명시적 인텐트를 사용하는 경우가 거의 없다.
1. 외부 패키지의 정확한 패키지명, 컴포넌트명을 미리 알고 있는 경우가 드물다.
2. 알고 있더라도 해당 단말기에 실행될 앱이 설치되어 있지 않을 수 있다.
3. 외부 앱들도 보안상 자신의 액티비티를 외부에 공개하지 않는다.
자세한 내용은 아래 링크(이전 포스팅)을 참고하자.
ch4njun.tistory.com/82?category=720630
암시적 인텐트
앱 내에서 웹페이지를 보여주는 기능이 필요할 때, 해당기능이 없으면 ?
웹페이지를 보여줘야 하는 의도(인텐트)를 담아보내면 액티비티 매니저, 패키지 매니저는 그 기능을 수행할 수 있는 컴포넌트를 찾아서 실행한다. (의도라는 표현은 꼭 기억하자.)
(그 기능이 수행할 수 있는 컴포넌트가 여러개일 경우에는 선택창이 뜬다)
의도(Intent)에 저장되야하는 데이터들.
1. Action : 동작을 설명하는 미리 정의된(System) 문자열을 말한다.
ex) 문자전송, 메일을 보낸다, 전화를 건다 등등...
- ACTION_CALL, ACTIOIN_EDIT, ACTION_MAIN, ACTION_VIEW, ACTION_DIAL ...
- Service에 대한내용을 다룰때도 굉장히 중요하게 등장한다.
2. Category : 액티비티의 분류를 결정한다.
android.intent.category.LAUNCHER 를 가진 액티비티는 거의 대부분의 앱이 가진다.
(LAUNCHER는 최초 아이콘을 눌렀을때 실행되는 Activity)
- 카테고리는 하나의 Intent에 여러개가 추가될 수 있다. (HashSet의 자료형을 갖는다.
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_APP_CALCULATOR);
startActivity(intent);
3. 데이터 위치 : 실행할 컴포넌트가 특정 데이터를 필요로 한다면 추가해준다.
URL, Path 등의 정보를 URI 클래스를 사용해 제공해줄 수 있다.
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://m.naver.com"));
4. 데이터 타입 : 대개 자동으로 데이터 판별가능. 지정시 자동판별 X
MP3, WAV 등과 같은 다양한 포맷을 지정해줄 수 있다.
- text/html, video/mpeg, image/jpeg, audio/x-wav 등 WEB에서 사용하 는거랑 같은 MIME를 사용한다.
intent.setAction(Intent.ACTION_VIEW);
String audioPath = "file:///" + Environment.getExternalStorageDirectory() + "/sample_mp3.mp3";
intent.setDataAndType(Uri.parse(audioPath), "audio/*");
// 이것도 원래는 가능한 문법인데 재생이 안된다...?
intent.setData(Uri.parse(audioPath));
intent.setType("audio/*");
// Action과 Data위치에 따른 실행 예제
ACTION_VIEW : content://contacts/people/1
ACTION_DIAL : content://contacts/people/1
ACTION_VIEW : tel:01012341234
ACTION_DIAL : tel:01012341234
ACTION_EDIT : content://contacts/people/1
ACTION_VIEW : content://contacts/people
Action과 Category를 받아 실행 가능한 암시적 Activity 생성하기.
<activity
android:name="com.superdroid.test.activity.b.BActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="action.ACTION_IMAGE_VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.superdroid.test.activity.b.BActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="action.ACTION_VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http"
android:host="m.youtube.com" />
</intent-filter>
</activity>
두번째 예시코드의 경우 웹에서 http://m.youtube.com/ 으로 시작하는 링크를 클릭할시 해당 Component에 암시적 Intent가 전달될 수 있도록 작성한 코드입니다.
<activity
android:name="com.superdroid.test.activity.b.BActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="action.ACTION_SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mineType="text/plain" />
</intent-filter>
</activity>
세번재 예시코드의 경우 Device에서 공유 버튼을 클릭할 시 해당 Component에 암시적 Intent를 전달될 수 있도록 작성한 코드입니다. 공유 버튼을 누르면 여러 App을 선택할 수 있는 화면이 뜨는데 거기에 해당 App이 포함된다.
<activity
android:name="com.superdroid.test.activity.b.BActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="action.ACTION_VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>
네번째 예시코드는 웹 브라우저가 켜지는 링크 클릭시 해당 Component에 암시적 Intent를 전달될 수 있도록 작성한 코드입니다. mimeType="video/*" 를 추가하게 되면 비디오링크가 클릭된 경우에만 전달됩니다.
<activity
android:name="com.superdroid.test.activity.b.BActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="action.ACTION_IMAGE_VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http"
android:host="www.superdroid.com"
android:port="80"
android:path="/files/images/test.png"
android:mimeType="image/png" />
</intent-filter>
</activity>
이 예제는 Data에 세부적인 필터링을 추가한 예제코드입니다. 단 하나라도 일치하지 않으면 해당 Activity는 실행되지 않는것을 확인할 수 있다.
category에 "android.intent.category.DEFAULT"는 암시적 인텐트임을 명시하는 것이다. 이 category를 추가하지 않는다면 해당 intent-filter는 명시적 인텐트를 위해 사용된다.
Intent 사용시 DEFAULT Category는 생략이 가능하다. (startAcitivty에서 내부적으로 추가)
- 그렇기 때문에 DEFALUT를 추가하지 않으면 어떤 암시적 Intent도 받을 수 없는 것이다.
<intent-filter> 를 통해 통과시킬 Intent를 특정 짓는 것이다.
<action>, <category>, 데이터 위치, 데이터 타입 등으로 필터링 조건을 설정한다.
Action의 이름은 그냥 내가 이름으로 AndroidManifest.xml에 등록하면된다. startActivity할 때 Action의 이름만 동일하면 정상적으로 동작한다. (반드시 100% 동일해야한다.)
그에 비해 Category는 Intent에 포함된 Category가 존재만하면된다. 추가적으로 존재하는것에 대해서는 상관없다.
'Android > Concept' 카테고리의 다른 글
[Android] 액티비티의 생명주기 (0) | 2019.07.29 |
---|---|
[Android] Bundle (0) | 2019.07.29 |
[Android] Activity & Intent (feat. Package Manager, Activity Manager) (0) | 2019.07.29 |
[Android] 이벤트 별쾅쾅. (0) | 2019.07.19 |
[Android] View Attribute. (0) | 2019.07.16 |