Android developer site study
- Building Apps with Content Sharing
- Sharing Simple Data
- Sharing Files
- Sharing Files with NFC
간단한 Data 공유하기
Android app의 중요한 기능 중 하나는 다른 app과 통신할 수 있다는 것이다.
간단한 data를 다른 app으로 전송하기
Intent 생성 시 원하는 action을 명확히 해야 한다. Android는 몇 가지 action에 대해 정의하고 있다. ACTION_SEND
는 하나의 activity에서 다른 activity로 data를 보낼 때 사용된다. process 경계를 넘어갈 수도 있다.
Data를 다른 activity로 보내기 위해서는 data
와 type
을 지정하는 것이 전부이다. 그러면 시스템은 수신이 가능한 적당한 activity를 찾아 사용자에게 보여준다(여러가지 선택이 가능하다면). 아니면 바로 해당 activity를 시작한다(하나의 선택만 가능하다면).
이와 비슷하게, 개발자는 activity에서 사용 가능한 data
와 type
에 대해 manifest에 기술하여 다른 app들에게 알릴 수 있다.
Intetnt를 사용하여 app 사이에 data를 주고받는 것은 가장 일반적인 공유 방법이다. Intent는 쉽고 빠르게 정보를 주고 받을 수 있게 해준다.
Text 정보 전송하기
가장 간단하고 일반적인 사용법은 ACTION_SEND
action을 사용하여 text를 다른 activity로 전송하는 것이다.
예를 들어, 브라우저는 현재 보고있는 페이지의 URL 정보를 다른 app과 공유할 수 있다. 이는 글이나 웹사이트를 다른 사람과 공유하고 싶을 때 편하게 사용할 수 있는 방법이다.
|
ACTION_SEND
와 text/plane type에 맞는 filter가 존재한다면 Android 시스템은 해당 app을 구동시킬 것이다. 여러 개의 app을 발견한다면 시스템은 선택상자 (“chooser”)를 사용자에게 보여주고 선택하게 할 것이다.
하지만, Intent.createChooser()
를 호출할 때 intent를 전달할 경우 항상 chooser을 보여주게 된다. 이 방법에는 몇 가지 장점이 있다.
- 사용자가 해당 intent에 대해 default action을 지정해둔 경우에도 chooser를 보여준다.
- 알맞은 app이 없을 때에는 Android는 시스템 메시지를 보여준다.
- Chooser dialog의 Title을 정할 수 있다.
이를 반영한 코드는 아래와 같다.
|
실행 결과는 아래 그림과 같다.
선택적으로, 개발자는 몇 가지 기본 EXTRA들을 세팅할 수 있다: EXTRA_EMAIL
, EXTRA_CC
, EXTRA_BCC
, EXTRA_SUBJECT
. 만약, 수신하는 app이 이 EXTRA들을 지원하지 않는다면 간단히 무시된다.
Gmail 등의 몇몇 e-mail app에서는
EXTRA_EMAIL
,EXTRA_CC
등의 EXTRA를 사용할 때 String[] 을 기대하므로 이러한 EXTRA를 intent에 추가할 때에는 putExtra(String, String[])을 사용하도록 하라.
Binary 정보 전송하기
Binary 데이터는 적당한 MIME type을 설정하여 ACTION_SEND
를 사용하고 EXTRA_STREAM
내에 적절한 URI를 지정하여 공유할 수 있다.
일반적으로 image를 공유할 때 사용되지만 어떤 형태의 binary 데이터도 공유할 수 있다.
|
아래 사항들에 대해 주의하라.
- MIME type으로 “/“을 사용할 수 있지만 이는 generic data stream을 처리할 수 있는 activity만 이를 수신할 수 있다.
- 수신하는 app은 Uri가 가리키는 data에 접근할 수 있는 권한을 필요로 한다. 따라서 아래와 같은 방식을 추천한다.
- Data를
ContentProvider
에 저장한 후 다른 app이 내 app의 provider에 저장할 수 있는 permission이 있는지 확인한다. 추천하는 방법은per-URI permissions
를 사용하여 접근을 준비해두는 것이다. 이는 intent를 수신하는 app에게 임시로 permission을 부여한다. 쉬운 방법으로는FileProvider
helper class를 사용하여ContentProvider
를 생성하는 것이다. - 시스템의
MediaStore
를 사용하라.MEdiaStore
는 비디오, 오디오, 이미지 MIME type에 최적화 되어있다. 하지만 Android 3.0 (API level 11)부터 non-media type들도 저장할 수 있게 되었다(자세한 것은 MediaStore.Files를 참조하라.). 공유에 적합한 content:// 스타일의 Uri 을onScanCompleted()
에 통과시킨 후scanFile()
을 사용하여 파일들을MediaStore
에 저장할 수 있다. 한 번 시스템MediaStore
에 추가한 컨텐츠는 기기의 모든 app들이 접근할 수 있다는 사실을 반드시 기억하라.
- Data를
여러 개의 컨텐츠를 한 번에 보내기
여러 개의 컨텐츠를 한 번에 공유하기 위해서는 ACTION_SEND_MULTIPLE
action에 URI의 목록을 넣어서 보내면 된다.
MIME type은 공유하고자 하는 컨텐츠들에 따라 넣어준다.
예를 들어, 3개의 JPEG 이미지들은 “image/jpeg”로 한다. 이미지들을 섞어서 보낸다면 “iamge/*”로 보낸다.
만약 공유하고자 하는 type들이 광범위하게 다양할 때에는 “/“를 사용한다.
시작할 때 기술했던 것처럼 해당 데이터를 수신하는 것은 수신 app의 역량에 달려있다.
|
다른 app으로부터 간단한 데이터를 수신하기
Manifest 업데이트하기
Intent filter를 통해 이 app 컴포넌트가 어떤 intent에 접근하길 원하는지 시스템에 알려줄 수 있다.
Intent를 수신하기 위해 <intent-filter>
를 manifest에 정의해야 한다.
만약 app이 text, 하나의 image 또는 여러 개의 image들을 수신하길 원한다면 아래와 같이 작성하면 된다.
|
더 많은 정보는 Intents and Intent Filters 에서 확인할 수 있다.
다른 app이 이런 정보들을 담은 intent를 생성하고 startActivity()
를 통해 공유할 때 내 app이 intent chooser의 목록에 보이게 될 것이다.
만약 사용자가 내 app을 선택한다면 그에 해당하는 activity (여기서는 .ui.MyActivity)가 시작될 것이다.
이 때부터 전달된 정보를 통해 app 내에서 가공하여 사용할 수 있다.
수신한 컨텐츠를 다루기
Intent를 통해 전달된 컨텐츠를 다루기 위해 getIntent()
를 호출하여 Intent 객체를 얻어올 수 있다.
객체를 한 번 갖게 되면 컨텐츠의 내용을 살펴본 후 다음에 무엇을 할지 정하게 된다.
만약 이 activity가 launcher 등의 시스템의 다른 부분으로부터 시작이 가능한 것이라면 intent가 수신되었을 때 의도를 파악하는 것이 중요하다.
|
|
수신한 데이터를 처리할 때는 특별히 더 주의를 기해야 한다. 왜냐하면 어떤 app에서 어떤 데이터를 보낸 것인지 알 수 없기 때문이다. 예를 들어, 틀린 MIME type이 세팅되거나 엄청나게 큰 image 파일이 전송될 수도 있다.
마찬가지로, binary 데이터를 처리할 때에도 thread를 분리하여 main(UI) thread가 아닌 곳에서 처리하도록 하자.
간단한 공유 action을 추가해보기
효과적이고 사용자 친화적인 action을 처리 위해 ActionProvider
와 함께 ActionBar
를 사용한다면 좀 더 쉬운 구현이 가능하다.
Action bar에 한 번 메뉴 아이템이 추가되고 난 후 ActionProvider
는 해당 아이템의 외견과 행동 모두를 제어한다. ShareActionProvider
의 경우 개발자는 share intent를 준비하고 그것이 나머지를 수행한다.
ShareActionProvider
는 API level 14 이상에서 사용 가능하다.
메뉴 선언 업데이트하기
ShareActionProvider
와 함께 시작하기 위해 메뉴 리소스 파일 내의 <item>
에 android:actionProviderClass
를 정의해야 한다.
|
이 방법은 아이템의 외견 및 기능에 대한 권한을 ShareActionProvider
로 이관한다. 하지만, 개발자는 공유하고 싶은 내용을 provider에 전달해줘야 한다.
Share intent 설정하기
ShareActionProvider
가 기능을 수행하기 위해 개발자는 반드시 share intent를 준비해두어야 한다.
이 Share intent는 앞서 “간단한-data를-다른-app으로-전송하기”에서 본 것과 같이 ACTION_SEND
action과 추가 data인 EXTRA_TEXT
, EXTRA_STREAM
등을 포함하여 작성되어야 한다.
Share intent 할당을 위해 메뉴 리소스를 Activity나 Fragment에 inflating하는 동안 올바른 MenuItem을 찾아야 한다.
그 후, MenuItem.getActionProvider()
를 호출하여 ShareActionProvider
의 인스턴스를 찾아야 한다.
setShareIntent()
를 사용하여 action item과 연관된 share intent를 업데이트 한다.
|
|
Share intent는 메뉴를 생성할 때 한 번만 설정해두면 된다. 또는 UI 변경이 발생할 때 업데이트 할 수도 있다.
예를 들어, Gallery app에서 사진을 전체 화면으로 보면서 화면을 전환할 때, sharing intent가 변경된다.