1page.title=アクティビティから結果を取得する
2page.tags=インテント
3helpoutsWidget=true
4
5trainingnavtop=true
6
7@jd:body
8
9<div id="tb-wrapper">
10  <div id="tb">
11
12<h2>このレッスンでの学習内容</h2>
13<ol>
14  <li><a href="#StartActivity">アクティビティを開始する</a></li>
15  <li><a href="#ReceiveResult">結果を受け取る</a></li>
16</ol>
17
18<h2>関連ドキュメント</h2>
19<ul>
20    <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li>
21    <li><a href="{@docRoot}training/secure-file-sharing/index.html">ファイルの共有</a>
22</ul>
23
24  </div>
25</div>
26
27<p>別のアクティビティを開始する場合、必ずしも一方向である必要はありません。別のアクティビティを開始して、結果を受け取ることもできます。
28結果を受け取るには、({@link android.app.Activity#startActivity
29startActivity()} ではなく) {@link android.app.Activity#startActivityForResult
30startActivityForResult()} を呼び出します。</p>
31
32<p>たとえば、自分のアプリでカメラアプリを起動し、結果として撮影した写真を受け取ることができます。または、ユーザーが連絡先を選択するケースにおいて、連絡帳アプリを起動し、結果として連絡先の詳細を受け取ることができます。
33
34</p>
35
36<p>もちろん、応答するアクティビティは結果を返すように設計されていなければなりません。その場合は、別の {@link android.content.Intent} オブジェクトとして結果を送信します。
37自分のアクティビティ側では、
38{@link android.app.Activity#onActivityResult onActivityResult()} コールバック内で結果を受け取ります。</p>
39
40<p class="note"><strong>注: </strong>
41{@link android.app.Activity#startActivityForResult startActivityForResult()} を呼び出す際は、明示的または暗黙的インテントを使用することができます。自分のアクティビティのいずれかを開始して結果を受け取ろうとする場合は、想定通りの結果を受け取れるようにするため、明示的なインテントを使用する必要があります。
42
43</p>
44
45
46<h2 id="StartActivity">アクティビティを開始する</h2>
47
48<p>結果を受け取るためにアクティビティを開始する際、使用する {@link android.content.Intent} オブジェクトに関して特に記すべき内容はありませんが、{@link
49android.app.Activity#startActivityForResult startActivityForResult()} メソッドに対して追加で整数の引数を渡す必要があります。
50</p>
51
52<p>整数の引数は、リクエストを識別する「要求コード」です。結果の
53{@link android.content.Intent} を受け取ると、アプリが正常に結果を識別し、その処理方法を決定することができるように、コールバックが同じ要求コードを提供します。
54</p>
55
56<p>たとえば、ユーザーが連絡先を選択できるようにするアクティビティの開始方法について、次に例を示します。</p>
57
58<pre>
59static final int PICK_CONTACT_REQUEST = 1;  // The request code
60...
61private void pickContact() {
62    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
63    pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
64    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
65}
66</pre>
67
68
69<h2 id="ReceiveResult">結果を受け取る</h2>
70
71<p>ユーザーが、その後のアクティビティを終えて復帰すると、システムは自分のアクティビティの
72{@link android.app.Activity#onActivityResult onActivityResult()} メソッドを呼び出します。このメソッドには、次の 3 つの引数が含まれます。
73</p>
74
75<ul>
76  <li>{@link
77android.app.Activity#startActivityForResult startActivityForResult()} に渡した要求コード。</li>
78  <li>第 2 のアクティビティによって指定された結果コード。これは、操作が成功した場合の {@link
79android.app.Activity#RESULT_OK} か、ユーザーがバックアウトしたり、何らかの理由で失敗したりした場合の {@link
80android.app.Activity#RESULT_CANCELED} か、いずれか一方です。
81</li>
82  <li>結果のデータを運ぶ {@link android.content.Intent}。</li>
83</ul>
84
85<p>たとえば、「連絡先を選ぶ」インテント用に結果を処理する方法について、次に例を示します。</p>
86
87<pre>
88&#64;Override
89protected void onActivityResult(int requestCode, int resultCode, Intent data) {
90    // Check which request we're responding to
91    if (requestCode == PICK_CONTACT_REQUEST) {
92        // Make sure the request was successful
93        if (resultCode == RESULT_OK) {
94            // The user picked a contact.
95            // The Intent's data Uri identifies which contact was selected.
96
97            // Do something with the contact here (bigger example below)
98        }
99    }
100}
101</pre>
102
103<p>この例では、Android の連絡先または連絡帳アプリから返される結果の {@link android.content.Intent} は、ユーザーが選択した連絡先を識別するコンテンツ {@link android.net.Uri} を提供します。
104
105</p>
106
107<p>正常に結果を処理するためには、結果の
108{@link android.content.Intent} の形式がどうなるかを理解する必要があります。これは、結果を返すアクティビティが自分のアクティビティの 1 つである場合には簡単です。
109Android プラットフォームに付属のアプリでは、特定の結果データに対して役立つ、独自の API を提供しています。
110たとえば、連絡帳アプリ(一部の古いバージョンでは連絡先アプリ)は常に選択した連絡先を識別するコンテンツ URI を含む結果を返し、カメラアプリは別に {@code "data"} で {@link android.graphics.Bitmap} を返します(<a href="{@docRoot}training/camera/index.html">写真を撮影する</a>のクラスを参照)。
111
112
113</p>
114
115
116<h4>ボーナス: 連絡先データを読み取る</h4>
117
118<p>連絡帳アプリから結果を取得する方法を示した上記のコードでは、実際に結果からデータを読み取る方法の詳細には触れていませんが、これは、<a href="{@docRoot}guide/topics/providers/content-providers.html">コンテンツプロバイダ</a>に関する高度な説明が必要であるためです。
119
120
121ここでは興味がある方向けに、結果データをクエリして、選択された連絡先から電話番号を取得する方法について、次にコード例を示します。
122</p>
123
124<pre>
125&#64;Override
126protected void onActivityResult(int requestCode, int resultCode, Intent data) {
127    // Check which request it is that we're responding to
128    if (requestCode == PICK_CONTACT_REQUEST) {
129        // Make sure the request was successful
130        if (resultCode == RESULT_OK) {
131            // Get the URI that points to the selected contact
132            Uri contactUri = data.getData();
133            // We only need the NUMBER column, because there will be only one row in the result
134            String[] projection = {Phone.NUMBER};
135
136            // Perform the query on the contact to get the NUMBER column
137            // We don't need a selection or sort order (there's only one result for the given URI)
138            // CAUTION: The query() method should be called from a separate thread to avoid blocking
139            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
140            // Consider using {@link android.content.CursorLoader} to perform the query.
141            Cursor cursor = getContentResolver()
142                    .query(contactUri, projection, null, null, null);
143            cursor.moveToFirst();
144
145            // Retrieve the phone number from the NUMBER column
146            int column = cursor.getColumnIndex(Phone.NUMBER);
147            String number = cursor.getString(column);
148
149            // Do something with the phone number...
150        }
151    }
152}
153</pre>
154
155<p class="note"><strong>注: </strong>Android 2.3(API レベル 9)以前では、
156{@link android.provider.ContactsContract.Contacts Contacts Provider} でクエリ(上記のような)を実行する場合、自分のアプリで {@link
157android.Manifest.permission#READ_CONTACTS} パーミッション(<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>を参照)を宣言することが必要です。
158ただし、Android 2.3 からは連絡先または連絡帳アプリにより、結果を返すときに連絡先プロバイダから読み取るための一時的パーミッションが付与されます。
159
160一時的パーミッションは要求された特定の連絡先にのみ適用されるため、{@link
161android.Manifest.permission#READ_CONTACTS} パーミッションを宣言した場合を除き、インテントの {@link android.net.Uri} で指定したもの以外の連絡先はクエリできません。
162
163</p>
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179