인텐트를 사용한 액티비티 간 이동
메인 액티비티에서 다른 액티비티로 이동하기
명시적 Intent를 사용합니다.
빈 액티비티를 추가하고 이름을 AddCourseActivity로 지정합니다. “레이아웃 파일 생성”에 체크합니다.
단, Launcher Activity 옵션은 체크하지 마세요.
Intent
Intent는 안드로이드 앱에서 각 컴포넌트 간에 상호작용하는 중요한 방법입니다.
현재 컴포넌트가 실행하려는 동작을 지정할 수도 있고, 서로 다른 컴포넌트 간에 데이터를 전달할 수도 있습니다.
Intent는 명시적 Intent와 암시적 Intent로 나뉩니다
여러 개의 생성자가 있습니다.
메인 액티비티의 버튼에서 Intent를 인스턴스화하여 메인 액티비티에서 두 번째 액티비티로 이동합니다.
// 먼저 Intent를 초기화하고 어디서 어디로 갈지 지정
Intent it = new Intent(FirstActivity.this, AddCourseActivity.class);
startActivity(it);Code language: JavaScript (javascript)
암시적 Intent 사용하기
명시적 Intent와 달리, 암시적 Intent는 어떤 액티비티를 시작할지 직접 지정할 필요가 없습니다. 대신 더 추상적인 action과 category를 지정합니다.
그러면 시스템이 이 Intent를 분석하여 시작할 수 있는 적절한 액티비티를 찾아줍니다.
AndroidManifest.xml을 수정합니다.
두 번째 액티비티에 action과 category를 추가합니다.
action은 이 액티비티가 해당 action에 응답할 수 있음을 나타냅니다.
<activity android:name=".AddCourseActivity">
<intent-filter>
<action android:name="com.foxdevelop.www.activitydemo.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>Code language: HTML, XML (xml)
Intent가 액티비티의 action과 category와 일치할 때만 해당 액티비티가 Intent에 응답할 수 있습니다.
// Intent를 초기화하여 AndroidManifest.xml의 해당 action과 일치시킴
Intent it = new Intent("com.foxdevelop.www.activitydemo.ACTION_START");
startActivity(it);Code language: JavaScript (javascript)
왜 category를 일치시킬 필요가 없을까요?
이 액티비티가 android.intent.category.DEFAULT를 사용하기 때문입니다.
이것은 기본값입니다.
startActivity를 호출하면 자동으로 DEFAULT가 전달됩니다.
각 Intent는 하나의 action만 지정할 수 있지만 여러 개의 category를 지정할 수 있습니다.
현재 DEFAULT이므로 따로 추가할 필요가 없습니다.
다른 category를 추가해야 하는 경우:
// Intent를 초기화하여 action과 일치시키고 category도 추가
Intent it = new Intent("com.foxdevelop.www.activitydemo.ACTION_START");
it.addCategory("com.foxdevelop.www.activitydemo.MY_CATEGORY");
it.addCategory("com.foxdevelop.www.activitydemo.MY_CATEGORY1111111");
startActivity(it);Code language: JavaScript (javascript)
“코스 추가” 메뉴를 클릭하니 앱이 크래시되었습니다.
원인은 intent에 category를 추가했는데, 두 번째 액티비티에는 해당 category가 선언되어 있지 않기 때문입니다.
따라서 이 category를 추가해야 합니다.
<activity android:name=".AddCourseActivity">
<intent-filter>
<action android:name="com.foxdevelop.www.activitydemo.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.foxdevelop.www.activitydemo.MY_CATEGORY" />
</intent-filter>
</activity>Code language: HTML, XML (xml)
주의:
Intent에 여러 개의 category가 있다면 하나만 일치한다고 해서 되는 것이 아니라, 모든 category가 일치해야 합니다.
<activity android:name=".AddCourseActivity">
<intent-filter>
<action android:name="com.foxdevelop.www.activitydemo.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.foxdevelop.www.activitydemo.MY_CATEGORY" />
</intent-filter>
</activity>Code language: HTML, XML (xml)
case R.id.add:
// Intent를 초기화하여 action과 일치시키고 category도 추가
Intent it = new Intent("com.foxdevelop.www.activitydemo.ACTION_START");
it.addCategory("com.foxdevelop.www.activitydemo.MY_CATEGORY2222222");
//it.addCategory("android.intent.category.DEFAULT");
startActivity(it);
break;Code language: JavaScript (javascript)
암시적 Intent로 웹 페이지 열기
암시적 Intent는 이 외에도 많은 기능을 할 수 있습니다.
같은 앱 내의 액티비티만 시작하는 것이 아니라 다른 앱의 액티비티도 시작할 수 있습니다.
이를 통해 여러 앱 간의 기능 공유가 가능해집니다.
예를 들어, 위챗 채팅 중 친구가 주소를 보내면 QQ 브라우저로 열 수 있습니다.
아래에서 시도해 보겠습니다:
Intent it = new Intent(Intent.ACTION_VIEW); // 시스템 내장 Action
it.setData(Uri.parse("http://www.foxdevelop.com")); // 웹사이트 열기
startActivity(it);Code language: JavaScript (javascript)
http://는 생략할 수 없습니다. 생략하면 오류가 발생합니다.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.foxdevelop.www.activitydemo, PID: 8917
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=www.foxdevelop.com }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1809)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1523)
at android.app.Activity.startActivityForResult(Activity.java:4224)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:68)Code language: PHP (php)
암시적 Intent로 전화 걸기
tel 프로토콜을 사용해 전화를 걸 수 있습니다
지난 시간에는 http 프로토콜을 사용해 도메인을 열었습니다.
예를 들어 아래에서 10010으로 전화를 걸어보겠습니다.

Intent it = new Intent(Intent.ACTION_DIAL); // 시스템 내장 Action
it.setData(Uri.parse("tel:10010")); // 이 번호로 전화 걸기(사용자 확인 필요)
startActivity(it);Code language: JavaScript (javascript)
액티비티 간 데이터 전달
Intent로 데이터를 전달할 수 있습니다
intent 영[ɪnˈtent] 미[ɪnˈtɛnt] 의도, 목적; 의미, 뜻.
putExtra 메서드를 사용하여 데이터를 전달합니다.
그리고 두 번째 액티비티에서 getStringExtra 메서드를 호출하여 전달된 데이터를 가져올 수 있습니다.
두 번째 액티비티에서는 getIntent 메서드를 호출하여 Intent를 가져옵니다.
물론 정수를 전달했다면 getIntExtra 메서드를 사용해 가져올 수 있습니다.
먼저 첫 번째 액티비티에서:
Intent it = new Intent(FirstActivity.this, AddCourseActivity.class);
it.putExtra("site", "www.foxdevelop.com");
it.putExtra("name", "FoxDevelop");
startActivity(it);Code language: JavaScript (javascript)
그다음 두 번째 액티비티에서 Intent 객체를 가져와 값을 얻습니다.
두 번째 액티비티의 onCreate 메서드 안에서:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_course_acticity);
Intent it = getIntent();
String site = it.getStringExtra("site");
String name = it.getStringExtra("name");
int version = it.getIntExtra("version", 1);
Log.e(TAG, site);
}Code language: JavaScript (javascript)
이전 액티비티에 데이터 반환하기
현재 액티비티를 종료할 때
액티비티에는 startActivityForResult 메서드가 있어, 액티비티가 소멸되기 전에 이전 액티비티로 결과를 반환할 수 있습니다.
이 메서드는 두 개의 매개변수를 받습니다. 첫 번째는 Intent이고, 두 번째는 요청 코드로, 나중에 콜백에서 데이터 출처를 판단하는 데 사용됩니다.
액티비티가 소멸되기 전에 setResult 메서드를 사용하여 이전 액티비티에 결과를 반환합니다. 일반적으로 RESULT_OK 또는 RESULT_CANCELED를 사용하며, 두 번째 매개변수는 데이터가 담긴 Intent를 전달합니다.
Intent에 putExtra를 사용해 값을 설정할 수 있습니다.
이전 액티비티에서 startActivityForResult를 사용해 두 번째 액티비티를 시작했기 때문에, 두 번째 액티비티가 소멸되면 첫 번째 액티비티의 onActivityResult 메서드가 호출됩니다. 여기서 Intent와 결과 코드를 가져올 수 있습니다.
사용자가 버튼을 눌러 돌아가는 것이 아니라 뒤로 가기 키를 사용하는 경우, 두 번째 액티비티에서 onBackPressed 메서드를 오버라이드해야 합니다.
1. 첫 번째 액티비티에서 Intent 시작 시
Intent it = new Intent(FirstActivity.this, AddCourseActivity.class);
it.putExtra("site", "www.foxdevelop.com");
it.putExtra("name", "FoxDevelop");
it.putExtra("version", 1);
startActivityForResult(it, 1);Code language: JavaScript (javascript)
2. 첫 번째 액티비티에서 오버라이드
public class FirstActivity extends AppCompatActivity {
private static final String TAG = "FirstActivity";
// 첫 번째 액티비티의 메서드를 오버라이드. 두 번째 액티비티가 종료되면 실행됨
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
String h = data.getStringExtra("hot");
Log.d(TAG, h);
}
super.onActivityResult(requestCode, resultCode, data);
}Code language: JavaScript (javascript)
3. 두 번째 액티비티에서
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_course_acticity);
// 이전 액티비티의 데이터 가져오기
Intent it = getIntent();
String site = it.getStringExtra("site");
String name = it.getStringExtra("name");
int version = it.getIntExtra("version", 1);
Log.e(TAG, site);
// 버튼에 뒤로 가기 이벤트 추가. 이벤트 내에서 Intent에 값 설정, 결과 코드 설정, 종료
Button b = findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent it = getIntent();
it.putExtra("hot", "인기 강좌");
setResult(RESULT_OK, it);
finish();
}
});
}Code language: JavaScript (javascript)
메인 액티비티로 돌아가면 이벤트가 발생하여 로그가 출력됩니다.
05-12 06:17:46.741 12960-12960/com.foxdevelop.www.activitydemo D/FirstActivity: 인기 강좌
뒤로 가기 키로도 데이터를 반환하고 싶다면
onBackPressed를 오버라이드해야 합니다.
두 번째 액티비티에서 오버라이드합니다:
// 이 메서드는 뒤로 가기 키를 눌렀을 때 호출됨
@Override
public void onBackPressed() {
Intent it = getIntent();
it.putExtra("hot", "최신 강좌");
setResult(RESULT_OK, it);
finish();
}Code language: JavaScript (javascript)
05-12 06:23:08.654 13209-13209/com.foxdevelop.www.activitydemo D/FirstActivity: 인기 강좌
05-12 06:23:16.405 13209-13209/com.foxdevelop.www.activitydemo D/FirstActivity: 최신 강좌
05-12 06:23:35.612 13209-13209/com.foxdevelop.www.activitydemo D/FirstActivity: 최신 강좌