2010. 7. 24. 06:06

[번역] 인텐트를 이용한 애플리케이션 통합


인텐트를 이용한 애플리케이션 통합

 

http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+blogspot/hsDu+(Android+Developers+Blog)

 

번역: SSKK (http://codemuri.tistory.com/)

 

인텐트를 이용한 애플리케이션 통합

 

2009 11 11일 오전 11 Justin Mattson 에 의해 포스팅됨

 

OpenTable, uLocate, 그리고 Mob.ly 는 안드로이드 상에서 훌륭한 사용자 경험을 만들기 위해 함께 동작한다. WHRER GoodFood 사용자들이 쉽고 매끄럽게 OpenTable 에서 예약할 수 있는 기회를 엿보았다. 이것은 모든 이가 Win 할 수 있는 상황이다 – OpenTable 은 많은 트래픽을 얻고, WHERE GoodFood 는 그들의 애플리케이션이 좀더 밀착되는 기능을 얻는다. 그리고 사용자들은 단지 몇 번의 손가락 탭 만으로 예약할 수 있게 된다. 안드로이드의 인텐트 매커니즘을 이용하여 애플리케이션 간에 이러한 통합이 가능하게 되었다. 인텐트는 안드로이드에서 가장 멋지고, 가장 유니크하고, 그리고 고마운 기능 중의 하나일 것이다. 각자가 가지고 있는 부분들로부터 어떻게 하나의 새로운 사용자 경험을 구성하는 지를 보여줄 것이다.

 

설계하기

 

첫 번째 단계는 인텐트 인터페이스 또는 API 를 설계하는 것이다. OpenTable 이 노출하는 공개 메인 인텐트는 RESERVE 인텐트이다. 이것은 특정 레스토랑에 대해 날짜, 시간 그리고 일행 수 등을 선택적으로 지정하여 예약을 할 수 있도록 한다.

 

RESERVE 인텐트를 이용하여 예약하는 방법에 대한 예제가 여기 있다.

 

startActivity(new Intent("com.opentable.action.RESERVE",
       
Uri.parse("reserve://opentable.com/2947?partySize=3")));

 

우리의 목적은 인텐트를 사용하는 개발자들에게 쉽고 명료하게 다가서도록 하는 것이었다. 그렇게 하기 위해 우리가 어떻게 결정하였을까?

 

먼저, 우리는 하나의 Action 이 필요했다. Intent.ACTION_VIEW 를 사용하는 것을 고려해 보았으나, 예약을 하는 것에는 잘 매치되지 않았고, 그래서 우리는 새로운 액션을 하나 만들기로 했다. 안드로이드 플랫폼의 컨벤션을 따라 (간단하게 <패키지명>.action.<액션명>), “com.opentable.action.RESERVE” 를 선택하였다. 액션은 그냥 단순한 문자열이기에, 액션에 네임스페이스를 주는 것은 중요하다. 모든 애플리케이션이 고유의 액션을 정의할 필요는 없다. 만일 무언가 특별한 걸 하지 않는다면 사실 Intent.ACTION_VIEW (“android.intent.action.VIEW” 라고도 알려진) 와 같은 일반 액션이 종종 더 나은 선택일 수 있다.

 

그 다음, 인텐트 내에서 데이터가 전송되는 방법을 결정해야 했다. 당신은 비록 인텐트의 데이터 Bundle 안에 아이템 컬렉션으로 데이터를 얻도록 할 수도 있지만, 우리는 URI 내에 인코딩된 데이터로 결정하였다. 일관성 있게 액션에 대해 “reserve:” 스키마를 사용하였다. 그 다음 요구되는 도메인 권한과 레스토랑 ID URI 경로에 두었다. 그리고 다른 모든 선택적인 입력은 URI 질의 파라미터로 이동시켰다.

 

노출하기

 

일단 인텐트가 어떻게 생긴지를 알았으므로, 시스템에 그 인텐트를 등록해야 했다. 그래야만 안드로이드가 OpenTable 애플리케이션을 시작하는 방법을 알 것이다. 이것은 AndroidManifest.xml 의 적절한 액티비티 선언에 인텐트 필터를 추가함으로써 이루어 진다.

 

<activity android:name=".activity.Splash" ... >
...
 
<intent-filter>
   
<action android:name="com.opentable.action.RESERVE"/>
   
<category android:name="android.intent.category.DEFAULT" />
   
<data android:scheme="reserve" android:host="opentable.com"/>
 
</intent-filter>
...
</activity>

 

우리의 경우, 사용자에게 식당 선택에 대한 상세 정보를 로딩하는 간단한 OpenTable 스플래쉬 화면을 보여주고자 했다. 그래서 스플래쉬 액티비티 정의 내에 그 인텐트 필터를 두었다. 카테고리는 DEFAULT 로 설정하였다. 이것은 다른 액티비티들이 이 액션에 대해 디폴트로 나열되어 있지 않는 한 사용자아게 어떤 애플리케이션을 사용할 지를 묻지 않고 바로 애플리케이션이 실행되도록 한다.

 

URI 질의 파라미터 (“partSize”)와 같은 것들은 인텐트 필터에 명시되지 않는ㄴ다는 것을 인지하라. 이것은 당신의 인텐트를 정의할 때 문서화의 핵심이다, 이에 대한 내용은 나중에 좀 더 살펴보자.

 

처리하기

 

이제 해야할 마지막 한가지는 인텐트를 처리하는 코드를 작성하는 것이다.

 

    protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
final Uri uri;
       
final int restaurantId;
       
try {
           uri
= getIntent().getData();
           restaurantId
= Integer.parseInt( uri.getPathSegments().get(0));
       
} catch(Exception e) {
           
// Restaurant ID is required
           
Log.e(e);
           startActivity
( FindTable.start(FindTablePublic.this));
           finish
();
           
return;
       
}
       
final String partySize = uri.getQueryParameter("partySize");
       
...
   
}

 

비록 완전한 코드는 아닐지라도, 당신은 아이디어를 얻을 수 있을 것이다. 여기에서 가장 어려운 부분은 에러 처리였다. OpenTable 은 파트너 애플리케이션에 의해 전송될 수 있는 잘못된 인텐트를 안전하게 다룰 수 있도록 하고 싶었다. 그래서 레스토랑 ID 를 분석하는 중 어떤 문제가 있다면, 레스토랑을 수동으로 찾을 수 있는 또 다른 액티비티를 사용자에게 보이도록 했다. 이건 마치 데스크탑이나 웹 애플리케이션에서 당신의 애플리케이션 또는 당신의 사용자들에게 해를 끼칠지도 모르는 인젝션 공격(injection attack)에 대항하는 것처럼 입력을 검증하는 것은 중요하다.

 

불확실 한 것들을 안전하게 호출하고 다루기

 

사실 요청자 범위 내에서 대상 애플리케이션을 호출하는 것은 매우 직선적이지만, 핸들링이 필요한 몇 가지 경우가 있다. OpenTable 이 설치되지 않았다면? WHERE 또는 GoodFood 가 레스토랑 ID 를 모른다면?

 

 

레스토랑 ID를 알고 있음

레스토랑 ID 를 모름

사용자가 OpenTable 을 가지고 있음

OpenTable 인텐트 호출

예약 버튼을 보여주지 않음

사용자가 OpenTable 이 없음

Market 인텐트 호출

예약 버튼을 보여주지 않음

 

만약 사용자가 대상 애플리케이션을 가지고 있지 않다면, 당신의 파트너가 어떻게 할 지를 결정하도록 하고 싶을지도 모른다. 이 경우에는, OpenTable 을 다운로드하기 위한 안드로이드 마켓을 사용자에 보여주도록 결정했다.

 

    public void showReserveButton() {
     
       
// setup the Intent to call OpenTable      
       
Uri reserveUri = Uri.parse(String.format( "reserve://opentable.com/%s?refId=5449",
               opentableId
));
       
Intent opentableIntent = new Intent("com.opentable.action.RESERVE", reserveUri);

       
// setup the Intent to deep link into Android Market
       
Uri marketUri = Uri.parse("market://search?q=pname:com.opentable");
       
Intent marketIntent = new Intent(Intent.ACTION_VIEW).setData(marketUri);
     
       opentableButton
.setVisibility(opentableId > 0 ? View.VISIBLE : View.GONE);
       opentableButton
.setOnClickListener(new Button.OnClickListener() {
           
public void onClick(View v) {
               
PackageManager pm = getPackageManager();
               startActivity
(pm.queryIntentActivities(opentableIntent, 0).size() == 0  ?
                       opentableIntent
: marketIntent);
           
}
       
});
   
}

 

레스토랑의 ID 를 사용할 수 없는 경우, 예약을 받지 않거나 OpenTable 네트워크의 일부가 아니기 때문에, 우리는 간단히 예약 버튼을 숨긴다.

 




인텐트 명세서 출판하기

 

기술적인 작업은 모두 하였으므로 이제 당신은 다른 개발자들이 당신의 인텐트 기반 API 를 사용하는 방법을 어떻게 얻도록 할 것인가? 정답은 간단하다: 웹사이트에 문서를 출판하는 것이다. 이것은 다른 애플리케이션이 당신의 기능에 링크하거나 당신이 이르지 못하는 좀더 큰 커뮤니티에 당신의 애플리케이션이 이용가능 하도록 만들어 줄 것이다.

 

출판된 정보가 없는 어떤 당신이 원하는 애플리케이션이 있다면, 그 개발자와 연락을 시도하라. 가끔 제 3자가 그들의 API 를 사용하려고 하는 것에 큰 흥미를 가질 수 있다. 그리고 만약 빈둥거리고 있는 API 가 이미 있다면, 그것에 대한 문서를 보다 쉽게 얻을 수 있다.

 

요약

 

정말 아주 간단하다. 이제 누구든 새로운 도시에 있든 바로 옆 근처에 있든 새로운 hot spot 이 어디인지를 쉽게 체크하고 즉시 이용가능한 테이블을 예약할 수 있다. 한 애플리케이션에서 어떤 식당을 찾을 필요 없이, 테이블이 있는지를 알기 위해 OpenTable 을 실행시켜라. 테이블이 없다는 것을 알았다면, 다시 처음 애플리케이션을 실행하라. 그리고 이것의 반복이다. 우리는 이 문서가 좀더 큰 안드로이드 커뮤니티에 공유할 것을 고려하고 있는 당신 고유의 공개 인텐트를 개발하는데 있어 도움이 되기를 바란다.

 

.