- 앱들간의 콘텐츠 송수신은 Intent API와 ActionProvider 오브젝트를 이용
1. 콘텐츠 송신
- Intent를 만들 때 그 Intent가 어떤 action을 유발(trigger)할 지를 결정
- ACTION_SEND : 다른 앱에 데이터를 전달하기 위한 Intent를 선언
- 송신 : 데이터, 데이터형을 명시하면 시스템이 대상 앱의 목록을 띄우거나, 대상 앱으로 바로 송신(대상 앱이 하나일 경우)
- 수신 : manifest 파일에 수신받을 수 있는 데이터형 명시
1) 텍스트 콘텐츠 송신
- 예제
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "my text");
sendIntent.setType("text/plain");
startActivity(sendIntent);
- Intent.createChooser() : 기본 연결 앱을 정하더라도 항상 chooser를 실행. 맞는 앱 없으면 시스템메시지 출력. 제목 출력가능
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "my text");
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to));
- 몇몇 표준 엑스트라들(EXTRA_EMAIL, EXTRA_CC, EXTRA_SUBJECT 등)을 set할 수도 있지만, 수신 앱이 해당 엑스트라를 수신하지 않으면 의미가 없음
2) 바이너리 콘텐츠 송신
- 적절한 MIME 타입, URI, 그리고 EXTRA_STREAM 엑스트라를 이용하여 바이너리 데이터 송신. 보통 이미지에 사용
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to));
- MIME 타입 "*-*"는 generic data stream 만을 수신하는 앱에서만 사용 가능
- 콘텐츠 수신 앱은 해당 Uri에 대한 퍼미션 필요. 해결방법은,
1) external/shared 스토리지에 파일로 쓰고 Uri.fromFile()로 Uri 생성.
2) MODE_WORLD_READABLE 모드로 openFileOutput()으로 얻어온 앱 디렉토리에 getFileStreamPath()로 얻어온 File사용
Uri.fromFile()로 Uri 생성
3) 그림 등 미디어 파일은 시스템의 MediaStore에 scanFile()을 이용해서 저장되고 읽을 수 있다.
onScanCompleted()로 Uri 생성
4) 이미지는 insertImage()로 시스템의 MediaStore에 저장될 수 있고, 이 메소드는 uri를 리턴
5) 앱 고유의 ContentProvider에 데이터를 저장. 퍼미션 확인해야 함
3) 복수개의 콘텐츠 송신
- ACTION_SEND_MULTIPLE 액션, Intent#putParcelableArrayListExtra() 메소드 이용
- 콘텐츠들의 종류에 따라 MIME 타입을 잘 설정해야 함
ArrayList<Uri> imageUris = new ArrayList<Uri>();
imageUris.add(imageUri1);
imageUris.add(imageUri2);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/-");
startActivity(Intent.createChooser(shareIntent, "share images to..."));
2. 콘텐츠 수신
1) Manifest 수정
- <intent-filter> 엘리먼트로 어떤 콘텐츠를 수신할 지 설정
<activity android:name=".ui.MyActivity">
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<ata android:mimeType="image/-" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<ata android:mimeType="text/plain" />
</intent-filter>
</activity>
2) 수신 컨텐츠의 사용
- getIntent() 메소드로 Intent 오브젝트 수신
- onCreate()는 다른 앱 뿐만 아니라 런처에 의해 호출될 수도 있으므로 intent 사용전에 확인할 것
void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent);
} else if (type.startsWith("image/")) {
handleSendImage(intent);
}
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
if (type.startsWith("image/") {
handleSendMultipleImages(intent);
}
}
}
void handleSendText(Intent intent) {
String text = intent.getStringExtra(Intent.EXTRA_TEXT);
...
}
3. Share Action 추가
- 안드로이드 4.0(API leven 14)에서부터 ActionProvider를 통한 ActionBar에 앱을 추가하는 기능을 구현
- ShareActionProvider : 공유 intent만 제공하면 이것이 알아서 나머지를 다 수행함
1) 메뉴 선언 업데이트
- ShareActionProviders를 이용하려면, menu resource 파일의 <item>에 android:actionProviderClass 애트리뷰트를 추가
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@id/menu_item_share"
android:showAsAction="ifRoom"
android:title="Share"
android:actionProviderClass="android.widget.ShareActionProvider"" />
</menu>
- 아이템의 표시 및 기능은 ShareActionProvider에 위임하지만, 무엇을 share하고자 하는지는 provider에 알려줘야 함
2) Share Intent 선언
- ShareActionProvider에 무엇을 share 할 지 알려주어야 함
1) MenuItem에서 관련된 아이템을 찾음
2) MenuItem.getActionProvider() 메소드를 콜하여 ShareActionProvider 인스턴스를 얻음
3) share intent를 업데이트 하기 위해 ShareActionProvider#setShareIntent() 메소드를 콜
private ShareActionProvider mShareActionProvider;
...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate menu resource file.
getMenuInflater().inflate(R.menu.share_menu, menu);
// Locate MenuItem with ShareActionProvider
MenuItem item = menu.findItem(R.id.menu_item_share);
// Fetch and store ShareActionProvider
mShareActionProvider = (ShareActionProvider) item.getActionProvider();
// Return true to display menu
return true;
}
// Call to update the share intent
private void setShareIntent(Intent shareIntent) {
if (mShareActionProvider != null) {
mShareActionProvider.setShareIntent(shareIntent);
}
}
* 출처 : http://developer.android.com/training/sharing/index.html
최근 덧글