앞번에 Intent 와 Intent Filter 에 관한 개념에 대한 설명을 했습니다. 


이번에는 앞서 언급한 명시적 인텐트 와 암시적 인텐트의 사용 예를 보여 드리겠습니다. 


■ 명시적 인텐트 예제


명시적 인텐트는 시작할 구성 요소(호출될 Activity)의 이름을 지정 하는 것입니다. 

아래는 ActivityA 에서 ActivityB를 명시적으로 호출 하는 예제 입니다. 


activity_a.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorial.james.androidtutorialtest.MainActivity"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity A 입니다."/>

<Button
android:id="@+id/btn_goto_activityb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity B 로 이동"/>

</LinearLayout>

</LinearLayout>

Activity A 화면이라는 내용의 TextView 를 제공하고 바로 아래에 Button 컴포넌트를 두어 Activity B 로 이동 하는 이벤트를 걸도록 하겠습니다. 


ActivityA.java

package com.tutorial.james.androidtutorialtest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class ActivityA extends AppCompatActivity {

Intent intent;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);

intent = new Intent(this, ActivityB.class);
(findViewById(R.id.btn_goto_activityb)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
intent.putExtra("messageStr", "Activity B 에 전송하는 문자 메세지입니다.");
intent.putExtra("messageInt", 7);
startActivity(intent);
}
});
}

}

btn_goto_activityb 라는 id 값을 가진 컴포넌트가 클릭 될 경우 intent 에 putExtra 를 이용하여 ActivityB 로 전달하고 싶은 내용을 추가 했습니다. 

messageStr 이라는 key 값에는 string 형태로 전달하고, messageInt 라는 Key 값에는 inter 형태로 전달 했습니다. 

이 값들을 Activity B 에서 사용 하는 방법도 아래에서 보여 드리겠습니다. 


activity_b.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorial.james.androidtutorialtest.MainActivity"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity B 입니다."/>

<TextView
android:id="@+id/tv_getintent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

</LinearLayout>

Activity B 화면임을 알려 주고 바로 아래 tv_getintent 라는 id 값의 TextView 를 제공하여 여기에 앞에서 전달흔 값들을 셋팅해 보겠습니다. 


ActivityB.java

package com.tutorial.james.androidtutorialtest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

public class ActivityB extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);

if(getIntent().getExtras() != null){
String str = "Activity A 에서 전달한 Int 값 = "+getIntent().getExtras().getInt("messageInt")
+"\nActivity A 에서 전달한 string 값 = "+ getIntent().getExtras().getString("messageStr");
((TextView)(findViewById(R.id.tv_getintent))).setText(str);
}

}
}

getIntent().getExtra() 값이 null 이 아닌 경우 이전 Activity 에서 intent 에 데이터를 전달 했다는 것을 알 수 있습니다. 

putExtra 할 때 int 값을 던졌으면 getIntent().getExtra().getInt("키값") 으로 받아야 하고, 만약 string 값을 던졌으면 getIntent().getExtra().getString("키값") 으로 받으면 됩니다. 


참고로 이 getIntent().getExtra() 는 데이터를 포함하는 Intent 의 Bundle 객체를 반환합니다. 


이를 실행 해보면 아래와 같은 결과를 얻으실 수 있습니다. 


Activity A 화면으로 Activity B 로 이동하는 버튼을 제공하고 있습니다. 


위 ActivityB.java 파일에서 getIntent().getExtra() 한 값들을 문자열로 조합하여 찍어 낸 결과 입니다. 


명시적 인텐트는 아주 간단하지만 또 한편으로는 데이터 전달 방식이 생각보다 종류가 많아 잘 봐두셔야 합니다. 

실제로 앱 개발중 Intent 를 활용하여 데이터를 쉬지 않고 나르고 받아 오는 작업을 할 겁니다. 



■ 암시적 인텐트 예제

암시적 인텐트는 호출될 Activity 명을 참조하는 명시적 인텐트와 달리 수행될 액션과 수신 Activity 에 의해 처리되는 데이터 타입을 지정하여 호출 될 Activity 를 식별합니다. 


아래는 email 를 보내는 기능을 하는 Activity를 검색하여 실행 하는 예제입니다. 


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorial.james.androidtutorialtest.MainActivity"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>

<Button
android:id="@+id/btn_send_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_send_email"
/>

</LinearLayout>

</LinearLayout>

레이아웃에 버튼 하나만 배치 했습니다. 

id 값을 btn_send_email 로 설정 하였습니다. 

text 값은 string.xml 파일의 btn_sent_email 이라는 값을 참조 하도록 했으며 이 값은 아래와 같습니다. 

<string name="btn_send_email">Send email</string>



IntentActivity.java

package com.tutorial.james.androidtutorialtest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

/**
* Created by James on 2017-08-09.
*/

public class IntentActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

(findViewById(R.id.btn_send_email)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/html");
intent.putExtra(Intent.EXTRA_EMAIL, "beardog78@gmail.com");
intent.putExtra(Intent.EXTRA_SUBJECT, "제목");
intent.putExtra(Intent.EXTRA_TEXT, "메일 내용 입력");
startActivity(Intent.createChooser(intent, "Send Email"));
}
});


}
}

IntentActivity 의 레이아웃은 activity_main.xml 이라고 설정 했습니다. 

이메일을 전송하기 위해서는  Intent.ACTION_SEND 값을 전달해야 합니다. 

btn_send_email 이라는 id 값을 가지는 컴포넌트를 찾아 View.OnClickListener 를 붙여 클릭 이벤트가 발생 할 경우 이메일을 전송합니다. 


위 소스를 실행 시 아래와 같은 결과를 확인 할 수 있습니다. 


SEND EMAIL 이라는 텍스트 있는 버튼을 클릭 시 아래와 같이 현재 단말에서 ACTION_SEND 를 할 수 있는 모든 애플리케이션 목록이 아래와 같이 나타납니다. 사용자는 이중 본인이 원하는 애플리케이션을 사용하여 이메일 전송을 할 수 있습니다. 




지금까지 명시적 인텐트 및 암시적 인텐트의 사용 예제를 살펴 봤습니다. 


Gooooooooooooooooooood Bye :)


블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

안드로이드 인텐트와 인텐트 필터 (Android Intent & Intent Filter)

 

Intent ?

 

Android App 하나 이상의 Activity 구성되어 있습니다. 두개 이상의 Activity 있는 App 경우 하나의 액티비티가 다른 액티비티를 론칭할때 사용하는 것이 Intent 입니다.

Intent 사전적 의미는 명사로서 의지,의향, 목적, 계획 등이 있습니다.

여기서 의지라는 단어가 Intent 가장 설명해주는 단어 입니다.

1 액티비티가 2 액티비티를 호출 할때 어떤 의지(요청 데이터) 담아서 호출 하는가 하는 것이 Intent 담기는 것입니다.

 

Intent 수신 액티비티에게 데이터를 전달 하기만 수도 있지만 요청된 작업이 완료되면 작업 결과 데이터를 반환하도록 구성 수도 있습니다.

 

Intent Filter ?

앱의 AndroidManifest.xml파일에 정의 되는 표현으로 해당 구성요소가 수신하고자 하는 Intent 유형을 나타냅니다.

 

 

Intent 이용한 호출 종류

 

    • 액티비티(Activity) 시작

시작할 Activity 필수 데이터를 담아 startActivity() 함수를 통해 전달 합니다.

Activity에게 요청한 작업의 결과를 수신하려면 startActivityForResult() 호출하면 됩니다. 결과 값은 onActivityResult()콜백함수에 별도의 Intent 객체로 수신됩니다.

 

    • 서비스(Service) 시작

Service 사용자 인터페이스 없이 백그라운드에서 작업을 수행하는 구성 요소로 서비스를 시작하여 작업을 수행하도록 하려면 Intent startService() 전달하면 됩니다.

다른 구성 요소로부터 서비스에 바인드하려면 Intent bindService() 전달하면 됩니다.

서비스에 관한 내용은 아래 링크를를 참조하세요

[Android강좌_007] Android Service (1회)

[Android강좌_008] Android Service (2회)

 

    • 브로드캐스트(Broadcast) 전달

브로드캐스트는 모든 앱이 수신할 있는 메시지로 시스템은 여러 시스템 이벤트에 대해 다양한 브로드캐스트를 전달 합니다. 다른 앱에 브로드캐스트를 전달 하려면 Intent sendBroadcast(), sendOrderedBroadcast() 또는 sendStickyBroadcast() 전달하면 됩니다.

 

 

Intent 유형

인텐트에는 두가지 유형이 있습니다.


    • 명시적 인텐트

시작할 구성 요소를 이름을 지정합니다.

일반적으로 본인의 안에서 구성 요소를 시작할 씁니다. 시작하고자 하는 Activity 또는 Service class명을 알고 있기 때문에 직접 호출이 가능합니다.

사용자가 Activity 시작하거나 백그라운드에서 파일을 다운로드하기 위해 Service 시작하는 등이 여기에 해당합니다.


    • 암시적 인텐트

특정 구성 요소의 명을 사용하지 않고 수행할 일반적인 작업을 선언하여 다른 앱의 구성 요소가 이를 처리 있도록 해주는 것을 의미합니다.

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

 

암시적 인텐트를 생성하면 Android 시스템이 시작시킬 적절한 구성 요소를 찿습니다.

각각의 앱들은 모두 AndroidManifest.xml 파일을 가지고 있으며 여기에 Intent Filter 정의해 두고 있습니다.

Intent Filter 비교하여 일치하는 인텐트가 있으면 Android 시스템이 해당 구성요소를 시작하고 이에 Intent 객체를 전달합니다.

호환되는 인텐트 필터가 여러 개인 경우, 시스템은 대화상자를 표시하여 사용자가 실행할 앱을 직접 선택하게 있게 합니다.

예를 들어 작성한 글을 SNS 통하여 공유하고자 할때 암시적 인텐트를 사용하여 모바일에 설치 되어 있는 해당 인텐트를 받아주는 모든 SNS 뿐만 아니라 기타 다른 앱들도 선택 대상 목록으로 나타나게 됩니다.

 

만약 Activity 대한 인텐트 필터를 선언할 경우 다른 여러 앱들이 동일 인텐트를 가지고 해당 앱을 호출 있습니다.

반대로 Activity 대한 인텐트 필터를 선언하지 않을 경우 명시적 인텐트로만 Activity 시작할 있습니다



암시적 인텐트가 시스템을 통해 전달되어 다른 액티비티를 시작하는 방법을 보여주는 그림.

[1] Aactivity A 가 startActivity()를 통해 Intent를 전달

[2] Android System이 해당 인텐트와 일치하는 인텐트 필터를 찾아 모든 앱을 검색하고 일치하는 항목을 찾으면

[3] 시스템이 일치하는 Activity를 시작하기 위해 Activity B의 onCreate() 함수를 호출하여 Intent 를 전달


앱의 보안을 보장하려면 Service 를 시작할 때엔느 항상 명시적 인텐트만 사용하고 서비스에 대한 인텐트 필터는 선언하지 않는 것이 좋습니다. 암시적 인텐트를 사용하여 서비스를 시작하면 보안 위험을 초래 합니다. 

위 그림에서는 Activity 를 기준으로 설명 되어 있으나 Service 도 동일합니다. 

인텐트에 어느 서비스가 응답할 것인지 확신할 수 없고, 사용자가 어느 서비스가 시작되는지 볼 수 없기 때문입니다. Android 5.0 (API 레벨 21)부터 시스템은 개발자가 암시적 인텐트로 bindService()를 호출하면 예외를 발생 시킵니다. 하지만 이전 버전에서 호환성을 생각 한다면 암시적 인텐트 사용은 자제 하는 것이 좋습니다. 









블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,