[7] 다른 앱과 연동하기 [1] 유저를 다른 앱으로 보내기

Sending the User to Another App

THIS LESSON TEACHES YOU TO

  1. Build an Implicit Intent
  2. Verify There is an App to Receive the Intent
  3. Start an Activity with the Intent
  4. Show an App Chooser

YOU SHOULD ALSO READ


One of Android’s most important features is an app’s ability to send the user to another app based on an “action” it would like to perform. For example, if your app has the address of a business that you’d like to show on a map, you don’t have to build an activity in your app that shows a map. Instead, you can create a request to view the address using an Intent. The Android system then starts an app that’s able to show the address on a map.

안드로이드의 중요한 기능중 하나입니다. 앱이 유저를 다른 앱으로 보낼 수 있는 능력이지요. 수행하려는 “action”에 근거한 다른 앱입니다. 예를 들어, 우리의 앱이 사무실의 주소를 지도에 보이고 싶다면, 우리는 액티비에 맵을 띄울 필요가 없이, 요청을 하나 만들면 됩니다. 그 주소를 Intent 에 담아 보여주도록 말이지요. 그렇게 하면 안드로이드 시스템은 앱을 시작하는데요, 그 맵을 실행할 수 있는 어플을 고르게 됩니다. (동영상 같은거 클릭하면 여러 개의 실행 앱이 있으면 고르라고 하는 그 메커니즘 같네요)

As explained in the first class, Building Your First App, you must use intents to navigate between activities in your own app. You generally do so with an explicit intent, which defines the exact class name of the component you want to start. However, when you want to have a separate app perform an action, such as “view a map,” you must use an implicit intent.

첫 시간에 설명했던 것 처럼, 우리는 반드시 인텐트를 액티비티간 이동할 때 사용해야 합니다. 일반적으로 명시적인 인텐트를 사용합니다.  명시적 인텐트는 정확하게 클래스 이름을 지정해 주는 것이지요. 우리가 어떤 것을 실행할 것인지 직접 지정해 주는 것입니다. 반면, 우리 앱이 아닌 다른 앱을 실행시키려면 (예를 들어 지도 보기), 우리는 반드시 암시적 intent 를 사용해야 합니다. 의도를 담아 안드로이드 시스템에 전달하자는 것이지요.

This lesson shows you how to create an implicit intent for a particular action, and how to use it to start an activity that performs the action in another app.

이번 시간에는 어떻게 암시적인 인텐트를 생성하고, 다른 앱에서 액션을 수행하는 액티비티를 시작하기 위해서 어떻게 이 것을 사용할 수 있을지 알아봅니다

Build an Implicit Intent


Implicit intents do not declare the class name of the component to start, but instead declare an action to perform. The action specifies the thing you want to do, such as view, edit, send, or get something. Intents often also include data associated with the action, such as the address you want to view, or the email message you want to send. Depending on the intent you want to create, the data might be a Uri, one of several other data types, or the intent might not need data at all.

암시적인 인텐트들은 시작할 컴포넌트의 클래스 이름을 선언하지 않습니다. 대신에 행동할 액션을 선언합니다. 그 액션에는 우리가 원하는 행동을 명시해 줍니다. 예를 들어 무언가를 view나 edit, send, get 한다는 것이지요. 또한 인텐트들은 종종 데이터를 갖고 있습니다. 액션에 관련된 데이터인데요, 우리가 보고 싶은 주소, 보내고 싶은 email 메시지 등등이 있지요. 우리아 만드려고 하는 인텐트에 따라서, 데이터는 Uri, 데이터 타입들이거나 또는, 아예 데이터가 없을 수도 있을거에요

If your data is a Uri, there’s a simple Intent() constructor you can use define the action and data.

데이터가 Uri 라면, 간단하게 Intent() 생성자를 쓰면 됩니다. 액션과 데이터를 이 것으로 정해 줄 수 있습니다.

For example, here’s how to create an intent to initiate a phone call using the Uri data to specify the telephone number:

예를 들어, 다음과 같이 인텐트를 생성할 수 있습니다. 전화 걸기를 초기화 할 수 있는데요, Uri 데이터를 통해 특정 폰번호를 정해 줄 수 있습니다.

Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

When your app invokes this intent by calling startActivity(), the Phone app initiates a call to the given phone number.

startActivity()를 호출함으로써 우리의 앱은 이 인텐트를 인보크할 수 있습니다. 폰 앱은 이 번호로 전화걸기를 세팅하지요.

Here are a couple other intents and their action and Uri data pairs:

인텐트 – 액션 – Uri 데이터 쌍을 예는 다음과 같습니다.

  • View a map:
    // Map point based on address
    Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
    // Or map point based on latitude/longitude
    // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
    Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
  • View a web page:
    Uri webpage = Uri.parse("http://www.android.com");
    Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

Other kinds of implicit intents require “extra” data that provide different data types, such as a string. You can add one or more pieces of extra data using the various putExtra() methods.

암시적인 인텐트의 다른 종류는 “extra” 데이터를 필요로 합니다. 이 것은 다른 데이터 타입을 제공하지요. 예를 들어 string 같은 것들입니다. 우리는 하나 또는 여러 개의 엑스트라 데이터를 더해 줄 수 있습니다. 다양한 putExtra 메소드를 이용하지요.

By default, the system determines the appropriate MIME type required by an intent based on the Uri data that’s included. If you don’t include a Uri in the intent, you should usually use setType() to specify the type of data associated with the intent. Setting the MIME type further specifies which kinds of activities should receive the intent.

기본적으로, 시스템은 정당한 MINE 타입을 알아냅니다. 이 것은 인텐트에 의해서 요청되는데요, 이 것에 포함된 Uri 데이터에 따라서 달라집니다. 우리가 만약 Uri를 인텐트에 포함하지 않는다면, setType() 을 사용해야 합니다. 데이터의 타입을 명시하기 위해서이죠. MINE 타입을 정의하는 것은 더 정의하는 것입니다. 어떤 종류의 액티비티가 이 인텐트를 받을 지 구체적으로 정의하는 것인 것 같아요

Here are some more intents that add extra data to specify the desired action:

다음은 엑스트라 데이터를 추가한 인텐트가 있습니다. 이는 우리가 원하는 액션을 좀 더 명시한 것이지요.

  • Send an email with an attachment:
    Intent emailIntent = new Intent(Intent.ACTION_SEND);
    // The intent does not have a URI, so declare the "text/plain" MIME type
    emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
    emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
    emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
    emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
    // You can also attach multiple items by passing an ArrayList of Uris
  • Create a calendar event:
    Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
    Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
    Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
    calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
    calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
    calendarIntent.putExtra(Events.TITLE, "Ninja class");
    calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");

    Note: This intent for a calendar event is supported only with API level 14 and higher.
    일정 이벤트는 API 14 이상에서 지원됩니다.

Note: It’s important that you define your Intent to be as specific as possible. For example, if you want to display an image using the ACTION_VIEW intent, you should specify a MIME type of image/*. This prevents apps that can “view” other types of data (like a map app) from being triggered by the intent.

노트: 우리가 인텐트를 가능한 한 상세하게 하는 것이 좋습니다. 예를 들어, 우리가 이미지를 ACTION_VIEW  인텐트를 이용해서 보여주고 싶다면, 우리는 image/* 의 MIME 타입을 명시해야만 합니다.  이렇게 해야 앱이 “보여”줄 수 있습니다. 다른 데이터 타입을 인텐트를 시작하는 것으로부터 말이지요. (이건 또 무슨 말이지요 : 추후 탈고하겠습니다.)

Verify There is an App to Receive the Intent


Although the Android platform guarantees that certain intents will resolve to one of the built-in apps (such as the Phone, Email, or Calendar app), you should always include a verification step before invoking an intent.

아무리 안드로이드 플랫폼이 특정한 인텐트가 빌트인 앱중 하나로 해결할 것을 보장한다고 하더라도, 우리는 언제나 확인하는 단계를 인텐트를 던져주기 전에 포함해 줘야 합니다.

Caution: If you invoke an intent and there is no app available on the device that can handle the intent, your app will crash.

주의 : 인텐트를 부르는데, 어떠한 앱도 이 것을 실행시킬 수 없다면, 우리의 앱은 죽어버립니다.

To verify there is an activity available that can respond to the intent, call queryIntentActivities() to get a list of activities capable of handling your Intent. If the returned List is not empty, you can safely use the intent. For example:

우리가 던져 준 인텐트를 수행가능한 액티비티가 있는지 확인하기 위해, queryIntentActivities()를 호출해야 합니다. 이 것은 리스트를 받는데요, 우리의 인텐트를 다룰 수 있는지 확인합니다. 리턴된 리스트가 비어있지 않다면, 안전한 것이지요

PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent,
        PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;

If isIntentSafe is true, then at least one app will respond to the intent. If it is false, then there aren’t any apps to handle the intent.

위의 isIntentSafe 가 true 라면, 적어도 한 개의 앱은 우리의 인텐트에 반응 할 것입니다. 만약 false라면, 어떠한 앱도 없다는 것이지요.

Note: You should perform this check when your activity first starts in case you need to disable the feature that uses the intent before the user attempts to use it. If you know of a specific app that can handle the intent, you can also provide a link for the user to download the app (see how to link to your product on Google Play).

노트: 우리의 액티비티를 처음 시작할 때 이 체크를 수행해야 합니다. 우리의 기능 중 어떠한 것들을 사용불가능 하게 할 것인지 정해야 하기 때문입니다. 우리의 앱이 사용불가한 외부 앱 호출을 시도하기 전에 막아야겠지요. 만약 특정한 앱이 우리가 정한 인텐트를 소화할 수 있다는 것을 알고 있다면, 우리는 그 앱에 대한 링크를 제공해야 합니다. (어떻게 해야 하는지는 link to your product on Google Play 를 참고하세요)

Start an Activity with the Intent


Figure 1. Example of the selection dialog that appears when more than one app can handle an intent.

그림 1. 1 개 이사의 앱이 인텐트를다루는 게 가능할 때 나타나는 선택 창의 예

Once you have created your Intent and set the extra info, call startActivity() to send it to the system. If the system identifies more than one activity that can handle the intent, it displays a dialog for the user to select which app to use, as shown in figure 1. If there is only one activity that handles the intent, the system immediately starts it.

일단 인텐트를 만들고 extra 정보를 세팅했다면, 이 것을 시스템에 건네주기 위해서 startActivity()를 호출하세요. 만약 시스템이 한 개 이상의 액티비티가 이 인텐트를 처리할 수 있다는 것을 확인했다면, 우리에게 위와 같은 다이얼로그 창을 띄워줄 것입니다. 그리고 우리는 어떤 앱을 사용할 지 정하면 되지요. 만약 단 한 개 밖에 없다면 시스템은 그것을 바로 실행할 것입니다.

startActivity(intent);

Here’s a complete example that shows how to create an intent to view a map, verify that an app exists to handle the intent, then start it:

여기에 완성된 예제가 있습니다. 이 것은 어떻게 인텐트를 생성하는지 보여줍니다. 지도를 표시하는 뷰를 생성하지요. 앱이 그 인텐트를 다룰 수 있다는 것을 확인하고 나서, 그 것을 실행합니다.

// Build the intent
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

// Verify it resolves
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
boolean isIntentSafe = activities.size() > 0;

// Start an activity if it's safe
if (isIntentSafe) {
    startActivity(mapIntent);
}

Show an App Chooser


Figure 2. A chooser dialog.

Notice that when you start an activity by passing your Intent to startActivity()and there is more than one app that responds to the intent, the user can select which app to use by default (by selecting a checkbox at the bottom of the dialog; see figure 1). This is nice when performing an action for which the user generally wants to use the same app every time, such as when opening a web page (users likely use just one web browser) or taking a photo (users likely prefer one camera).

우리의 인텐트를 startActivity()에 넘겨줌으로써 액티비티를 실행할 때를 알아차리고, 한 개 이상이 인텐트에 대해서 반응할 때, 사용자는 어떠한 앱을 기본 실행 앱으로 선택할 수 있다는 것을 인지하시길 바랍니다. 같은 상황에서 같은 앱을 계속 실행하고 싶다는 것을 의미하지요.

However, if the action to be performed could be handled by multiple apps and the user might prefer a different app each time—such as a “share” action, for which users might have several apps through which they might share an item—you should explicitly show a chooser dialog as shown in figure 2. The chooser dialog forces the user to select which app to use for the action every time (the user cannot select a default app for the action).

하지만, 수행되는 액션이 다양한 앱에서 수행될 수 있고 사용자가 매 번 다른 앱을 실행시키고 싶을 수도 있습니다. 예를 들어 share 버튼같은 경우겠지요. 우리는 명시적으로 어떤 것을 고를지 보여줘야 합니다.

To show the chooser, create an Intent using createChooser() and pass it tostartActivity(). For example:

선택창을 보여주기 위해서, 인텐트를 createChooser()를 이용해서 생성하고 startActivity()로 넘겨줍니다.

Intent intent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);

// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

This displays a dialog with a list of apps that respond to the intent passed to the createChooser() method and uses the supplied text as the dialog title.


답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중