- 하나의 앱 안에 있는 여러 액티비티간에 데이터 교환을 위해서는 Intent, startActivity() 등을 사용 : explicit intent
- Intent는 서로 다른 앱간의 interaction을 위해서도 사용 가능 : implicit intent
1. 다른 앱으로의 전환 및 데이터 송신 : Implicit intent
1) Implicit Intent 생성
- 시작할 컴포넌트의 이름이 아닌 수행할 액션 및 그 액션과 관계된 데이터를 선언. 안드로이드 시스템이 사용자로 하여금 해당 액션을 받아서 처리할 수 있는 앱으로 등록된 앱들중 하나를 선택하게 함.
- 데이터가 Uri라면 Intent 컨스트럭터로 액션과 데이터 정의 가능
Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
위 인텐트를 startActivity()로 invoke하면 위 번호로 폰 앱이 시작됨
- putExtra() : 다른 데이터를 추가하기 위해 사용
- setType() : Uri를 Intent에 사용하지 않는다면, 데이터 타입이 무엇인지를 명확하게 하기 위해 사용
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"});
emailIntent.putExtra(Intext.EXTRA_SUBJECT, "Email subject");
emailIntent.putExtra(Intext.EXTRA_TEXT, "Email text");
emailIntent.putExtra(Intext.EXTRA_STREAM, Uri.parse("context://path/to/email/attachment"));
2) Intent를 수신할 앱을 확인
- 수신할 앱이 없다면 app이 crash되므로 반드시 확인
- PackageManager#queryIntentActivities() : 생성한 Intent를 핸들링할 수 있는 앱의 리스트를 리턴
PackageManager pMgr = getPackageManager();
List<ResolveInfo> activities = pMgr.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
3) Intent를 이용한 새로운 앱의 시작
- startActivity(intent);
- 해당 Intent를 사용 가능한 복수개의 앱이 있다면 시스템은 다이얼로그를 통해 선택하도록 함
- 전체 예제
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
PackageManager pMgr = getPackageManager();
List<ResolveInfo> activities = pMgr.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) {
startActivity(mapIntent);
}
- createChooser() : 여러개의 앱을 선택 가능할 경우 디폴트 앱을 정하면 다음부터는 그 앱만 실행되나, 디폴트 앱을 지정하지 않고 매번 선택을 하도록 할 때 사용
String title = getResources().getText(R.string.chooser_title); // 선택창의 타이틀 지정 가능
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser);
2. 다른 앱으로부터 결과 얻기
- 다른 앱으로 전환한 뒤, 해당 앱이 종료되면 그 결과를 얻어오도록 할 수 있음. startActivityForResult(), onActivityResult() 사용
- 다른 앱은 당연히 결과를 리턴하도록 설계되어있어야 함
1) 액티비티 시작
- 액티비티 전환시 리턴받았을때 확인할 request code를 인자로 준다는것 외에는 일반적인 전환과 동일
static final int PICK_CONTACT_REQUEST = 1;
...
startActivityForResult(intent, PICK_CONTACT_REQUEST);
2) 결과 수신
- 결과가 리턴되면 시스템은 onActivityResult() 메소드를 콜. 3개의 인자가 있음
1) 전환시 보냈던 requset code
2) 실행결과코드 : RESULT_OK 또는 RESULT_CANCELED
3) 결과 데이터가 있는 Intent
protected void onActivityResult(int reqCode, int resCode, Intent data) {
if (reqCode == PICK_CONTACT_REQUEST) {
if (resCode == RESULT_OK) {
...
}
}
}
- 결과 Intent는 많은 표준 프로그램의 API에 정의되어 있음. 개별 프로그램 각자 알아내야 함
- 전화번호 얻기 예제
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
Uri contactUri = data.getData();
// We only need the NUMBER column, because there will be only one row in the result
String[] projection = {Phone.NUMBER};
// query() 메소드는 blocking을 막기 위해 앱이 UI 쓰레드와 다른 별도의 쓰레드에서 수행해야 함. 여기선 그냥
Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
cursor.moveToFirst();
int column = cursor.getColumnIndex(Phone.NUMBER);
String number = cursor.getString(column);
}
}
}
3. 다른 앱이 내 앱을 실행하게 하기
- manifest 파일의 <activity> 요소에 <intent-filter> 요소를 추가 -> 설치 시 시스템이 이것을 보고 internal catalog에 추가함
1) Intent filter 추가
- 최대한 상세해야 함
- 아래 세가지 요건이 정의되어야 함
1) Action : 수행할 액션 이름. 보통 ACTION_SEND 또는 ACTION_VIEW. <action> 요소로 추가
2) Data : intent와 연관된 데이터. <data> 요소로 추가. MIME type, URI prefix, URI scheme의 조합이 될 수 있음. URI 외의 데이터를 쓰려면 android:mimeType 애트리뷰트에 앱에서 다룰 데이터 타입을 선언해야 함(text/plain 등)
3) Category : 액티비티의 종류를 뜻함. 여러가지가 있는데 implicit intent를 수신하기 위해선 CATEGORY_DEFAULT를 사용
- ACTION_SEND intent를 텍스트나 이미지 데이터와 함께 사용할 앱의 예제
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="image/-"/>
</intent-filter>
</activity>
- 각 <intent-filter>안에 복수개의 <action>, <data>, <catgory> 쌍 존재 가능. 상호 배타적인 쌍이라면 다른 필터로 지정해야함
- 아래 예제의 경우, ACTION_SEND와 ACTION_SENDTO에 모두 이미지/텍스트를 사용하나, ACTION_SENDTO의 경우 URI를 사용해야만 하므로 서로 다른 필터로 지정
<activity android:name="ShareActivity">
<!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
<intent-filter>
<action android:name="android.intent.action.SENDTO"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="sms" />
<data android:scheme="smsto" />
</intent-filter>
<!-- filter for sending text or images; accepts SEND action and text or image data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/-"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
2) Intent 사용
- getIntent() 메소드로 intent를 얻어와 사용
- onCreate() 또는 onStart() 콜백에서 사용해야 함 : 인텐트 수신은 앱이 foreground로 나오면서 이루어지므로
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = getIntent();
Uri data = intent.getData();
// intent type에 따라 실행
if (intent.getType().indexOf("image/") != -1) {
// Handle intents with image data ...
} else if (intent.getType().equals("text/plain")) {
// Handle intents with text ...
}
}
3) 결과 송신
- 내 앱을 invoke한 앱에 결과를 보내려면 setResult()로 결과 코드 설정 후 finish() 메소드를 콜
- 결과 코드 기본값은 RESULT_CANCELED. 0 보다 큰 특정 정수값을 임의로 보낼 수 있음
- 결과를 받는 앱, 즉 지금 앱을 invoke한 앱에서 결과값이 필요없다면 알아서 무시하므로 내 앱을 startActivity()로 불렀는지, startActivityForResult() 불렀는지는 중요하지 않음
* 출처 : http://developer.android.com/training/basics/intents/index.html
- Intent는 서로 다른 앱간의 interaction을 위해서도 사용 가능 : implicit intent
1. 다른 앱으로의 전환 및 데이터 송신 : Implicit intent
1) Implicit Intent 생성
- 시작할 컴포넌트의 이름이 아닌 수행할 액션 및 그 액션과 관계된 데이터를 선언. 안드로이드 시스템이 사용자로 하여금 해당 액션을 받아서 처리할 수 있는 앱으로 등록된 앱들중 하나를 선택하게 함.
- 데이터가 Uri라면 Intent 컨스트럭터로 액션과 데이터 정의 가능
Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
위 인텐트를 startActivity()로 invoke하면 위 번호로 폰 앱이 시작됨
- putExtra() : 다른 데이터를 추가하기 위해 사용
- setType() : Uri를 Intent에 사용하지 않는다면, 데이터 타입이 무엇인지를 명확하게 하기 위해 사용
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"});
emailIntent.putExtra(Intext.EXTRA_SUBJECT, "Email subject");
emailIntent.putExtra(Intext.EXTRA_TEXT, "Email text");
emailIntent.putExtra(Intext.EXTRA_STREAM, Uri.parse("context://path/to/email/attachment"));
2) Intent를 수신할 앱을 확인
- 수신할 앱이 없다면 app이 crash되므로 반드시 확인
- PackageManager#queryIntentActivities() : 생성한 Intent를 핸들링할 수 있는 앱의 리스트를 리턴
PackageManager pMgr = getPackageManager();
List<ResolveInfo> activities = pMgr.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
3) Intent를 이용한 새로운 앱의 시작
- startActivity(intent);
- 해당 Intent를 사용 가능한 복수개의 앱이 있다면 시스템은 다이얼로그를 통해 선택하도록 함
- 전체 예제
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
PackageManager pMgr = getPackageManager();
List<ResolveInfo> activities = pMgr.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) {
startActivity(mapIntent);
}
- createChooser() : 여러개의 앱을 선택 가능할 경우 디폴트 앱을 정하면 다음부터는 그 앱만 실행되나, 디폴트 앱을 지정하지 않고 매번 선택을 하도록 할 때 사용
String title = getResources().getText(R.string.chooser_title); // 선택창의 타이틀 지정 가능
Intent chooser = Intent.createChooser(intent, title); startActivity(chooser);
2. 다른 앱으로부터 결과 얻기
- 다른 앱으로 전환한 뒤, 해당 앱이 종료되면 그 결과를 얻어오도록 할 수 있음. startActivityForResult(), onActivityResult() 사용
- 다른 앱은 당연히 결과를 리턴하도록 설계되어있어야 함
1) 액티비티 시작
- 액티비티 전환시 리턴받았을때 확인할 request code를 인자로 준다는것 외에는 일반적인 전환과 동일
static final int PICK_CONTACT_REQUEST = 1;
...
startActivityForResult(intent, PICK_CONTACT_REQUEST);
2) 결과 수신
- 결과가 리턴되면 시스템은 onActivityResult() 메소드를 콜. 3개의 인자가 있음
1) 전환시 보냈던 requset code
2) 실행결과코드 : RESULT_OK 또는 RESULT_CANCELED
3) 결과 데이터가 있는 Intent
protected void onActivityResult(int reqCode, int resCode, Intent data) {
if (reqCode == PICK_CONTACT_REQUEST) {
if (resCode == RESULT_OK) {
...
}
}
}
- 결과 Intent는 많은 표준 프로그램의 API에 정의되어 있음. 개별 프로그램 각자 알아내야 함
- 전화번호 얻기 예제
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
Uri contactUri = data.getData();
// We only need the NUMBER column, because there will be only one row in the result
String[] projection = {Phone.NUMBER};
// query() 메소드는 blocking을 막기 위해 앱이 UI 쓰레드와 다른 별도의 쓰레드에서 수행해야 함. 여기선 그냥
Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
cursor.moveToFirst();
int column = cursor.getColumnIndex(Phone.NUMBER);
String number = cursor.getString(column);
}
}
}
3. 다른 앱이 내 앱을 실행하게 하기
- manifest 파일의 <activity> 요소에 <intent-filter> 요소를 추가 -> 설치 시 시스템이 이것을 보고 internal catalog에 추가함
1) Intent filter 추가
- 최대한 상세해야 함
- 아래 세가지 요건이 정의되어야 함
1) Action : 수행할 액션 이름. 보통 ACTION_SEND 또는 ACTION_VIEW. <action> 요소로 추가
2) Data : intent와 연관된 데이터. <data> 요소로 추가. MIME type, URI prefix, URI scheme의 조합이 될 수 있음. URI 외의 데이터를 쓰려면 android:mimeType 애트리뷰트에 앱에서 다룰 데이터 타입을 선언해야 함(text/plain 등)
3) Category : 액티비티의 종류를 뜻함. 여러가지가 있는데 implicit intent를 수신하기 위해선 CATEGORY_DEFAULT를 사용
- ACTION_SEND intent를 텍스트나 이미지 데이터와 함께 사용할 앱의 예제
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="image/-"/>
</intent-filter>
</activity>
- 각 <intent-filter>안에 복수개의 <action>, <data>, <catgory> 쌍 존재 가능. 상호 배타적인 쌍이라면 다른 필터로 지정해야함
- 아래 예제의 경우, ACTION_SEND와 ACTION_SENDTO에 모두 이미지/텍스트를 사용하나, ACTION_SENDTO의 경우 URI를 사용해야만 하므로 서로 다른 필터로 지정
<activity android:name="ShareActivity">
<!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
<intent-filter>
<action android:name="android.intent.action.SENDTO"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="sms" />
<data android:scheme="smsto" />
</intent-filter>
<!-- filter for sending text or images; accepts SEND action and text or image data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/-"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
2) Intent 사용
- getIntent() 메소드로 intent를 얻어와 사용
- onCreate() 또는 onStart() 콜백에서 사용해야 함 : 인텐트 수신은 앱이 foreground로 나오면서 이루어지므로
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = getIntent();
Uri data = intent.getData();
// intent type에 따라 실행
if (intent.getType().indexOf("image/") != -1) {
// Handle intents with image data ...
} else if (intent.getType().equals("text/plain")) {
// Handle intents with text ...
}
}
3) 결과 송신
- 내 앱을 invoke한 앱에 결과를 보내려면 setResult()로 결과 코드 설정 후 finish() 메소드를 콜
- 결과 코드 기본값은 RESULT_CANCELED. 0 보다 큰 특정 정수값을 임의로 보낼 수 있음
- 결과를 받는 앱, 즉 지금 앱을 invoke한 앱에서 결과값이 필요없다면 알아서 무시하므로 내 앱을 startActivity()로 불렀는지, startActivityForResult() 불렀는지는 중요하지 않음
* 출처 : http://developer.android.com/training/basics/intents/index.html
최근 덧글