1) 안드로이드의 4대 컴포넌트
인텐트를 설명하기 앞서, 안드로이드의 4대 컴포넌트를 먼저 소개하려고 한다. 안드로이드의 4대 컴포넌트는 액티비티, 서비스, 브로드캐스트 리시버, 콘텐트 프로바이더이다.
액티비티란?
액티비티(Activity)는 화면을 구성하는 가장 기본적인 컴포넌트이다.
서비스란?
서비스(Service)는 눈에 보이는 화면(액티비티)과 상관없이 백그라운드에서 동작하는 컴포넌트이다. 백신 프로그램과 같이 눈에는 보이지 않지만 계속 동작하고 있다. 로컬에서 동작하는 서비스는
서비스 생성 -> 서비스 시작 -> 서비스 종료의 세 단계를 거친다.
브로드캐스트 리시버란?
안드로이드는 여러 응용 프로그램이나 장치에 메시지를 전달하기 위해 방송(broadcasting) 메시지를 사용한다. 안드로이드는 문자 메시지 도착, 배터리 방전, SD 카드 탈부착, 네트워크 환경 변화 등이 발생하면 전체 응용 프로그램이 들을 수 있도록 방송신호를 보낸다. 그리고 브로드캐스트 리시버는 이러한 방송 메시지가 발생하면 반응한다. 배터리 잔량이 얼마 남지 않았을 때 경고 문자나 소리를 발생시키는 기능 등을 구현할 수 있다.
콘텐트 프로바이더란?
콘텐트 프로바이더(Content Provider)는 응용 프로그램 사이에 데이터를 공유하기 위한 컴포넌트이다. 안드로이드 응용 프로그램은 데이터에 자신만 접근할 수 있으므로 자신의 데이터를 외부에 공개하려면 콘텐트 프로바이더를 만들어야 한다. 콘텐트 프로바이더의 정보를 제공하는 방법으로는 URL이 있다. 콘텐트 프로바이더에서 처리된 데이터는 일반적으로 데이터베이스 또는 파일로 저장된다.
2. Intent란?
안드로이드 앱을 사용해보면, 버튼과 같은 위젯을 클릭 시 화면이 바뀌는 것을 본 적이 있을 것이다. 안드로이드에서 액티비티 간 화면 전환에 이용되는 것이 인텐트이다. 인텐트는 안드로이드의 4대 컴포넌트가 서로 데이터를 주고받기 위한 메시지 객체이다. 명시적 인텐트와 암시적 인텐트로 구분할 수 있다.
3. 명시적 인텐트(Explicit Intent)란?
명시적 인텐트는 다른 액티비티의 이름을 명확히 지정할 때 사용하는 방법이다. 명시적 인텐트를 사용할 때는 요청을 보내는 클래스와 요청을 받는 클래스를 명시해주어야 한다.
Intent i = new Intent(IntentActivity.this, IntentSubActivity.class);
startActivity(i);
위의 코드처럼 요청을 보내는 클래스인 IntentActivity와 요청을 받는 클래스인 IntentSubActivity를 명시하여 코드를 작성해주고, startActivity(i)를 실행하게 되면 화면 전환이 이루어진다.
3. 암시적 인텐트(Implicit Intent)란?
암시적 인텐트는 명시적 인텐트처럼 두 액티비티를 사용자가 직접 생성하고 코딩하는 것과는 반대로, 약속된 액션을 지정하여 안드로이드에서 제공하는 기존 응용 프로그램을 실행하는 것이다. 예를 들면, 안드로이드의 기본 앱인 전화화면으로 이동한다거나, 갤러리로 이동하는 등의 행위들이다.
간단하게 인텐트를 활용한 예제를 만들어 보았다. 사용자가 각 버튼을 클릭하면 전화, 메시지, 카메라, 갤러리, 링크, 다음 페이지로 넘어가는 예제이다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".IntentActivity"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="call"
android:id="@+id/btn_call"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="sms"
android:id="@+id/btn_sms"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="camera"
android:id="@+id/btn_camera"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="gallery"
android:id="@+id/btn_gallery"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="link"
android:id="@+id/btn_link"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="next"
android:id="@+id/btn_next"
/>
</LinearLayout>
레이아웃은 리니어 레이아웃을 통해 간단하게 작성하였다.
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
public class IntentActivity extends AppCompatActivity {
Button btn_sms, btn_camera, btn_link, btn_call, btn_gallery, btn_next;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intent);
btn_call = findViewById(R.id.btn_call);
btn_sms = findViewById(R.id.btn_sms);
btn_camera = findViewById(R.id.btn_camera);
btn_link = findViewById(R.id.btn_link);
btn_gallery = findViewById(R.id.btn_gallery);
btn_next = findViewById(R.id.btn_next);
btn_call.setOnClickListener(click);
btn_sms.setOnClickListener(click);
btn_camera.setOnClickListener(click);
btn_link.setOnClickListener(click);
btn_gallery.setOnClickListener(click);
btn_next.setOnClickListener(click);
}
View.OnClickListener click = new View.OnClickListener() {
@Override
public void onClick(View view) {
//화면전환을 위해 반드시 필요한 클래스
Intent i = null;
switch (view.getId()) {
case R.id.btn_call:
//Dial은 전화패드로 연결 , CALL은 즉시 걸어줌
i = new Intent(Intent.ACTION_CALL);
i.setData(Uri.parse("tel:010-1111-1111"));
startActivity(i);
break;
case R.id.btn_sms:
i = new Intent(Intent.ACTION_SENDTO);
i.setData(Uri.parse("smsto:010-2222-2222"));
//putExtra를 사용하면 내용을 지정해줄 수 있다.
//key값은 sms_body로 고정
i.putExtra("sms_body","안녕~");
startActivity(i);
break;
case R.id.btn_camera:
//내장 카메라로 연결
i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(i);
//동영상 연결
i = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivity(i);
break;
case R.id.btn_link:
//i = new Intent(Intent.ACTION_VIEW);
//i.setData(Uri.parse("https://naver.com"));
//startActivity(i);
//플레이스토어로 이동
i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("market://details?id=com.pys.ex_0718"));
startActivity(i);
break;
case R.id.btn_gallery:
//naver 이동
i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("*/*");
break;
case R.id.btn_next:
i = new Intent(IntentActivity.this, IntentSubActivity.class);
startActivity(i);
break;
}
}
};
}
주석으로 필요한 설명을 작성해두었으므로 설명은 생략하고, 위의 예제는 앞에 설명했던 명시적 인텐트와 암시적 인텐트를 모두 활용한 간단한 예제이다. 꼭 버튼이 아니더라도 실제 앱처럼 이미지와 같은 요소를 활용하여 다양하게 활용할 수 있다.