• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=コンテンツ プロバイダの基本
2@jd:body
3<div id="qv-wrapper">
4<div id="qv">
5<!-- In this document -->
6<h2>本書の内容</h2>
7<ol>
8    <li>
9        <a href="#Basics">概要</a>
10        <ol>
11            <li>
12                <a href="#ClientProvider">プロバイダにアクセスする</a>
13            </li>
14            <li>
15                <a href="#ContentURIs">コンテンツ URI</a>
16            </li>
17        </ol>
18    </li>
19    <li>
20        <a href="#SimpleQuery">プロバイダからデータを取得する</a>
21        <ol>
22            <li>
23                <a href="#RequestPermissions">読み取りアクセス パーミッションを要求する</a>
24            </li>
25            <li>
26                <a href="#Query">クエリを作成する</a>
27            </li>
28            <li>
29                <a href="#DisplayResults">クエリ結果を表示する</a>
30            </li>
31            <li>
32                <a href="#GettingResults">クエリ結果を取得する</a>
33            </li>
34        </ol>
35    </li>
36    <li>
37        <a href="#Permissions">コンテンツ プロバイダ パーミッション</a>
38    </li>
39    <li>
40        <a href="#Modifications">データを挿入、更新、削除する</a>
41        <ol>
42            <li>
43                <a href="#Inserting">データを挿入する</a>
44            </li>
45            <li>
46                <a href="#Updating">データを更新する</a>
47            </li>
48            <li>
49                <a href="#Deleting">データを削除する</a>
50            </li>
51        </ol>
52    </li>
53    <li>
54        <a href="#DataTypes">プロバイダ データタイプ</a>
55    </li>
56    <li>
57        <a href="#AltForms">プロバイダ アクセスの別の形式</a>
58        <ol>
59            <li>
60                <a href="#Batch">バッチアクセス</a>
61            </li>
62            <li>
63                <a href="#Intents">インテント経由のデータアクセス</a>
64            </li>
65        </ol>
66    </li>
67    <li>
68        <a href="#ContractClasses">コントラクト クラス</a>
69    </li>
70    <li>
71        <a href="#MIMETypeReference">MIME タイプ リファレンス</a>
72    </li>
73</ol>
74
75    <!-- Key Classes -->
76<h2>キークラス</h2>
77    <ol>
78        <li>
79            {@link android.content.ContentProvider}
80        </li>
81        <li>
82            {@link android.content.ContentResolver}
83        </li>
84        <li>
85            {@link android.database.Cursor}
86        </li>
87        <li>
88            {@link android.net.Uri}
89        </li>
90    </ol>
91
92    <!-- Related Samples -->
93<h2>関連サンプル</h2>
94    <ol>
95        <li>
96        <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
97        Cursor (People)</a>
98        </li>
99        <li>
100        <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
101        Cursor (Phones)</a>
102        </li>
103    </ol>
104
105    <!-- See also -->
106<h2>関連ドキュメント</h2>
107    <ol>
108        <li>
109            <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
110            コンテンツ プロバイダの作成</a>
111        </li>
112        <li>
113            <a href="{@docRoot}guide/topics/providers/calendar-provider.html">
114            カレンダー プロバイダ</a>
115        </li>
116    </ol>
117</div>
118</div>
119
120    <!-- Intro paragraphs -->
121<p>
122    コンテンツ プロバイダは、データの中央リポジトリへのアクセスを管理します。プロバイダは Android アプリケーションの一部であり、通常、データを処理するための独自の UI を備えています。
123
124ただし、コンテンツ プロバイダは主に他のアプリケーションでの使用を意図したものです。アプリケーションはプロバイダ クライアント オブジェクトを使用してプロバイダにアクセスします。
125さらに、プロバイダとプロバイダ クライアントにはデータを扱うための一貫性のある標準のインターフェースが備わっており、プロセス間の通信や安全なデータ アクセスを処理します。
126
127
128</p>
129<p>
130    このトピックでは、次の項目に関する基本的な内容を説明します。
131</p>
132    <ul>
133        <li>コンテンツ プロバイダの仕組み。</li>
134        <li>コンテンツ プロバイダからのデータの取得に使用する API。</li>
135        <li>コンテンツ プロバイダへのデータの挿入、データの更新や削除に使用する API。</li>
136        <li>プロバイダでの作業に役立つその他の API 機能。</li>
137    </ul>
138
139    <!-- Basics -->
140<h2 id="Basics">概要</h2>
141<p>
142    外部アプリケーションでは、コンテンツ プロバイダのデータは、リレーショナル データベースで使用する表と同様に、1 つ以上の表として表示されます。
143行はプロバイダが収集するデータの何らかのタイプのインスタンスを表しており、行内のそれぞれの列はインスタンスに対して収集した個々のデータを表しています。
144
145
146</p>
147<p>
148    たとえば、Android プラットフォームに組み込まれているプロバイダの 1 つに単語リストがありますが、ここにはユーザーが保存しておく標準以外の単語のスペリングが格納されます
149表 1 は、このプロバイダの表にデータがどのように格納されているのかを表しています。
150
151</p>
152<p class="table-caption">
153    <strong>表 1:</strong> サンプルの単語リスト表。
154</p>
155<table id="table1" style="width: 50%;">
156    <tr>
157        <th style="width:20%" align="center" scope="col">word</th>
158        <th style="width:20%" align="center" scope="col">app id</th>
159        <th style="width:20%" align="center" scope="col">frequency</th>
160        <th style="width:20%" align="center" scope="col">locale</th>
161        <th style="width:20%" align="center" scope="col">_ID</th>
162    </tr>
163    <tr>
164        <td align="center" scope="row">mapreduce</td>
165        <td align="center">user1</td>
166        <td align="center">100</td>
167        <td align="center">en_US</td>
168        <td align="center">1</td>
169    </tr>
170    <tr>
171        <td align="center" scope="row">precompiler</td>
172        <td align="center">user14</td>
173        <td align="center">200</td>
174        <td align="center">fr_FR</td>
175        <td align="center">2</td>
176    </tr>
177    <tr>
178        <td align="center" scope="row">applet</td>
179        <td align="center">user2</td>
180        <td align="center">225</td>
181        <td align="center">fr_CA</td>
182        <td align="center">3</td>
183    </tr>
184    <tr>
185        <td align="center" scope="row">const</td>
186        <td align="center">user1</td>
187        <td align="center">255</td>
188        <td align="center">pt_BR</td>
189        <td align="center">4</td>
190    </tr>
191    <tr>
192        <td align="center" scope="row">int</td>
193        <td align="center">user5</td>
194        <td align="center">100</td>
195        <td align="center">en_UK</td>
196        <td align="center">5</td>
197    </tr>
198</table>
199<p>
200    表 1 の各行は、標準の辞書には含まれていない単語のインスタンスを表しています。
201各列は、該当する単語のデータの一部(その単語が最初に見つかったロケールなど)を表しています。
202列の見出しは、プロバイダに格納される列の名前です。
203行のロケールを調べるには、<code>locale</code> 列を参照します。このプロバイダの場合、<code>_ID</code> 列が「プライマリキー」の列の役割を果たし、プロバイダはこの列を自動的に保持します。
204
205
206</p>
207<p class="note">
208    <strong>注:</strong> プロバイダはプライマリキーを持つ必要がなく、プライマリキーがある場合は <code>_ID</code> をプライマリキーの列名として使用する必要はありません。
209ただし、プロバイダのデータを {@link android.widget.ListView} にバインドする場合は、いずれかの列の名前を <code>_ID</code> とする必要があります。
210
211この要件についての詳細は、<a href="#DisplayResults">クエリ結果を表示する</a>セクションをご覧ください。
212
213</p>
214<h3 id="ClientProvider">プロバイダにアクセスする</h3>
215<p>
216    アプリケーションは、{@link android.content.ContentResolver} クライアント オブジェクトを使用して、コンテンツ プロバイダのデータにアクセスします。
217このオブジェクトには、プロバイダ オブジェクトの同名のメソッドを呼び出すメソッドが備わっています。これは、{@link android.content.ContentProvider} の具体的なサブクラスのインスタンスのいずれかになります。
218
219{@link android.content.ContentResolver} メソッドには、永続ストレージの基本的な「CRUD」(作成、取得、更新、削除)機能が備わっています。
220
221
222</p>
223<p>
224    クライアント アプリケーションのプロセスにおける {@link android.content.ContentResolver} オブジェクトと、プロバイダを所有するアプリケーションの {@link android.content.ContentProvider} オブジェクトが、プロセス間の通信を自動的に処理します。さらに、{@link android.content.ContentProvider} は、データのリポジトリと、外部に表形式で表示されるデータの間の抽象化レイヤーとして機能します。
225
226
227
228
229</p>
230<p class="note">
231    <strong>注:</strong> 通常、アプリケーションがプロバイダにアクセスする場合、そのマニフェスト ファイルで特定のパーミッションを要求する必要があります。
232詳細は、<a href="#Permissions">コンテンツ プロバイダ パーミッション</a>セクションをご覧ください。
233
234</p>
235<p>
236    たとえば、単語リスト プロバイダから単語とそのロケールの一覧を取得するには、{@link android.content.ContentResolver#query ContentResolver.query()} を呼び出します。
237
238    {@link android.content.ContentResolver#query query()} メソッドによって、単語リスト プロバイダが定義する{@link android.content.ContentProvider#query ContentProvider.query()} メソッドが呼び出されます。
239
240コードの次の行は、{@link android.content.ContentResolver#query ContentResolver.query()} 呼び出しを表しています。
241
242<p>
243<pre>
244// Queries the user dictionary and returns results
245mCursor = getContentResolver().query(
246    UserDictionary.Words.CONTENT_URI,   // The content URI of the words table
247    mProjection,                        // The columns to return for each row
248    mSelectionClause                    // Selection criteria
249    mSelectionArgs,                     // Selection criteria
250    mSortOrder);                        // The sort order for the returned rows
251</pre>
252<p>
253    表 2 は、query(Uri,projection,selection,selectionArgs,sortOrder)} の引数が SQL SELECT 文にどのように一致しているかを示しています。
254
255
256</p>
257<p class="table-caption">
258    <strong>表 2:</strong> SQL クエリと比較した Query()。
259</p>
260<table id="table2" style="width: 75%;">
261    <tr>
262        <th style="width:25%" align="center" scope="col">query() 引数</th>
263        <th style="width:25%" align="center" scope="col">SELECT キーワード / パラメータ</th>
264        <th style="width:50%" align="center" scope="col">注</th>
265    </tr>
266    <tr>
267        <td align="center"><code>Uri</code></td>
268        <td align="center"><code>FROM <em>table_name</em></code></td>
269        <td><code>Uri</code> は、<em>table_name</em> という名前のプロバイダの表にマッピングされます。</td>
270    </tr>
271    <tr>
272        <td align="center"><code>projection</code></td>
273        <td align="center"><code><em>col,col,col,...</em></code></td>
274        <td>
275            <code>projection</code> は、取得するそれぞれの行に含まれる列の配列です。
276
277        </td>
278    </tr>
279    <tr>
280        <td align="center"><code>selection</code></td>
281        <td align="center"><code>WHERE <em>col</em> = <em>value</em></code></td>
282        <td><code>selection</code> は、行を選択する際の基準を指定します。</td>
283    </tr>
284    <tr>
285        <td align="center"><code>selectionArgs</code></td>
286        <td align="center">
287            (正確に一致するものはありません。選択句では、<code>?</code> プレースホルダーが選択引数に置き換わります)
288
289        </td>
290    </tr>
291    <tr>
292        <td align="center"><code>sortOrder</code></td>
293        <td align="center"><code>ORDER BY <em>col,col,...</em></code></td>
294        <td>
295            <code>sortOrder</code> は、返される {@link android.database.Cursor} 内で行が表示される順番を指定します。
296
297        </td>
298    </tr>
299</table>
300<h3 id="ContentURIs">コンテンツ URI</h3>
301<p>
302    <strong>コンテンツ URI</strong> は、プロバイダのデータを特定する URI です。コンテンツ URI には、プロバイダ全体の識別名(<strong>認証局</strong>)と表をポイントする名前(<strong>パス</strong>)が含まれます。
303
304プロバイダの表にアクセスするためのクライアント メソッドを呼び出す場合、その引数の 1 つがコンテンツ URI になります。
305
306
307</p>
308<p>
309    コードの前半の行では、定数 {@link android.provider.UserDictionary.Words#CONTENT_URI} に、単語リストの「words」表のコンテンツ URI が入ります。
310
311{@link android.content.ContentResolver} オブジェクトは URI の認証局をパースし、認証局を既知のプロバイダのシステム表と比較して、プロバイダを「解決」します。
312
313その後、{@link android.content.ContentResolver} は、クエリ引数を正しいプロバイダに送信できます。
314
315
316</p>
317<p>
318    {@link android.content.ContentProvider} は、アクセスする表を選択するのに、コンテンツ URI のパス部分を使用します。
319通常、プロバイダは公開する各表の<strong>パス</strong>を持ちます。
320</p>
321<p>
322    コードの前半の行では、「words」表の完全な URI は次のようになります。
323</p>
324<pre>
325content://user_dictionary/words
326</pre>
327<p>
328    ここで、<code>user_dictionary</code> 文字列はプロバイダの認証局になり、<code>words</code> 文字列は表のパスになります。
329文字列 <code>content://</code>(<strong>スキーム</strong>)は常に存在し、これがコンテンツ URI であることを示します。
330
331
332</p>
333<p>
334    多くのプログラムでは、URI の末尾に ID 値を付加することで、表内の 1 つの行にアクセスできます。たとえば、<code>_ID</code> が <code>4</code> の行を単語リストから取得するには、次のコンテンツ URI を使用します。
335
336
337</p>
338<pre>
339Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
340</pre>
341<p>
342    通常は、一連の行を取得してからいずれかの行を更新、削除するような場合に ID 値を使用します。
343
344</p>
345<p class="note">
346    <strong>注:</strong> {@link android.net.Uri} クラスと {@link android.net.Uri.Builder} クラスには、正しい形式の URI オブジェクトを文字列から作成するための、便利なメソッドが用意されています。
347{@link android.content.ContentUris} には、URI に ID 値を付加するための便利なメソッドが用意されています。前述のスニペットは {@link android.content.ContentUris#withAppendedId
348    withAppendedId()} を使用して、UserDictionary コンテンツ URI に ID を付加しています。
349
350
351</p>
352
353
354    <!-- Retrieving Data from the Provider -->
355<h2 id="SimpleQuery">プロバイダからデータを取得する</h2>
356<p>
357    このセクションでは、単語リスト プロバイダの例を使い、プロバイダからデータを取得する方法を説明します。
358
359</p>
360<p class="note">
361    わかりやすくするために、このセクションのコード スニペットは「UI スレッド」の {@link android.content.ContentResolver#query ContentResolver.query()} を呼び出しています。
362ただし、実際のコードでは、個別のスレッドで非同期にクエリを実行する必要があります。
363この操作は、{@link android.content.CursorLoader} クラスを使用して行うこともできます。このクラスについての詳細は、「<a href="{@docRoot}guide/components/loaders.html">ローダ</a>」に関するガイドをご覧ください。
364
365
366さらに、コードの行はスニペットのみであり、完全なアプリケーションにはなっていません。
367
368</p>
369<p>
370    プロバイダからデータを取得するには、次の基本的な手順に従います。
371</p>
372<ol>
373   <li>
374        プロバイダの読み取りアクセスを要求します。
375   </li>
376   <li>
377        プロバイダにクエリを送信するコードを定義します。
378   </li>
379</ol>
380<h3 id="RequestPermissions">読み取りアクセス パーミッションを要求する</h3>
381<p>
382    プロバイダからデータを取得するには、アプリケーションからプロバイダの読み取りアクセスを要求します。
383実行時にはこのパーミッションを要求できません。その代わりに、<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code> 要素とプロバイダで定義した正確なパーミッション名を使用して、このパーミッションを必要としていることをマニフェストで指定する必要があります。
384
385
386
387この要素をマニフェストで指定すると、実際に、このパーミッションをアプリケーションに「要求」することになります。
388ユーザーがアプリケーションをインストールすると、この要求が暗黙的に付与されることになります。
389
390</p>
391<p>
392    使用する読み取りアクセス パーミッションの正確な名前と、プロバイダが使用するその他のアクセス パーミッションの名前については、プロバイダのドキュメントをご覧ください。
393
394
395</p>
396<p>
397    プロバイダにアクセスする際のパーミッションのロールの詳細は、<a href="#Permissions">コンテンツ プロバイダ パーミッション</a>セクションをご覧ください。
398
399</p>
400<p>
401    単語リスト プロバイダはパーミッション <code>android.permission.READ_USER_DICTIONARY</code> をマニフェスト ファイルで定義するため、プロバイダからの読み取りを行うアプリケーションはこのパーミッションを要求する必要があります。
402
403
404</p>
405<!-- Constructing the query -->
406<h3 id="Query">クエリを作成する</h3>
407<p>
408    プロバイダからのデータの取得の次の手順では、クエリを作成します。最初のスニペットで、単語リスト プロバイダにアクセスするための変数をいくつか定義します。
409
410</p>
411<pre class="prettyprint">
412
413// A "projection" defines the columns that will be returned for each row
414String[] mProjection =
415{
416    UserDictionary.Words._ID,    // Contract class constant for the _ID column name
417    UserDictionary.Words.WORD,   // Contract class constant for the word column name
418    UserDictionary.Words.LOCALE  // Contract class constant for the locale column name
419};
420
421// Defines a string to contain the selection clause
422String mSelectionClause = null;
423
424// Initializes an array to contain selection arguments
425String[] mSelectionArgs = {""};
426
427</pre>
428<p>
429    次のスニペットでは、単語リスト プロバイダの例を使って、{@link android.content.ContentResolver#query ContentResolver.query()} を使用する方法を示しています。
430
431プロバイダ クライアント クエリは SQL クエリに似たものであり、戻り値となる一連の列、一連の選択基準、並べ替えの順番を含みます。
432
433</p>
434<p>
435    クエリの戻り値となる一連の列は、<strong>投影</strong>(変数 <code>mProjection</code>)と呼ばれます。
436
437</p>
438<p>
439    取得する行を指定する式は、選択句と選択引数に分割されます。
440選択句は論理式やブール式、列名、値(変数 <code>mSelectionClause</code>)の組み合わせになります。
441値の代わりに置き換え可能パラメータ <code>?</code> を指定すると、クエリ メソッドによって、選択引数の配列(変数 <code>mSelectionArgs</code>)から値が取得されます。
442
443
444</p>
445<p>
446    次のスニペットでは、ユーザーが単語を入力しない場合、選択句が <code>null</code> に設定され、クエリによってプロバイダのすべての単語が返されます。
447ユーザーが単語を入力すると、選択句が <code>UserDictionary.Words.WORD + " = ?"</code> に設定され、選択引数の配列の最初の要素が、ユーザーが入力した単語に設定されます。
448
449
450</p>
451<pre class="prettyprint">
452/*
453 * This defines a one-element String array to contain the selection argument.
454 */
455String[] mSelectionArgs = {""};
456
457// Gets a word from the UI
458mSearchString = mSearchWord.getText().toString();
459
460// Remember to insert code here to check for invalid or malicious input.
461
462// If the word is the empty string, gets everything
463if (TextUtils.isEmpty(mSearchString)) {
464    // Setting the selection clause to null will return all words
465    mSelectionClause = null;
466    mSelectionArgs[0] = "";
467
468} else {
469    // Constructs a selection clause that matches the word that the user entered.
470    mSelectionClause = UserDictionary.Words.WORD + " = ?";
471
472    // Moves the user's input string to the selection arguments.
473    mSelectionArgs[0] = mSearchString;
474
475}
476
477// Does a query against the table and returns a Cursor object
478mCursor = getContentResolver().query(
479    UserDictionary.Words.CONTENT_URI,  // The content URI of the words table
480    mProjection,                       // The columns to return for each row
481    mSelectionClause                   // Either null, or the word the user entered
482    mSelectionArgs,                    // Either empty, or the string the user entered
483    mSortOrder);                       // The sort order for the returned rows
484
485// Some providers return null if an error occurs, others throw an exception
486if (null == mCursor) {
487    /*
488     * Insert code here to handle the error. Be sure not to use the cursor! You may want to
489     * call android.util.Log.e() to log this error.
490     *
491     */
492// If the Cursor is empty, the provider found no matches
493} else if (mCursor.getCount() &lt; 1) {
494
495    /*
496     * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily
497     * an error. You may want to offer the user the option to insert a new row, or re-type the
498     * search term.
499     */
500
501} else {
502    // Insert code here to do something with the results
503
504}
505</pre>
506<p>
507    このクエリは、 SQL 文に似ています。
508</p>
509<pre>
510SELECT _ID, word, locale FROM words WHERE word = &lt;userinput&gt; ORDER BY word ASC;
511</pre>
512<p>
513    この SQL 文では、コントラクト クラスの定数ではなく、実際の列の名前が使用されます。
514</p>
515<h4 id="Injection">悪意のある入力から保護する</h4>
516<p>
517    コンテンツ プロバイダが管理するデータが SQL データベース内にある場合、外部の信頼されていないデータを未処理の SQL 文に含めると SQL インジェクションが発生することがあります。
518
519</p>
520<p>
521    次のような選択句を考えてみます。
522</p>
523<pre>
524// Constructs a selection clause by concatenating the user's input to the column name
525String mSelectionClause =  "var = " + mUserInput;
526</pre>
527<p>
528    このようにすれば、ユーザーが悪意のある SQL を SQL 文に連結できるようになります。
529    たとえば、ユーザーが <code>mUserInput</code> に「nothing; DROP TABLE *;」と入力すると、選択句は <code>var = nothing; DROP TABLE *;</code> となります。
530選択句は SQL 文として処理されるため、この場合、基本的な SQLite データベースのすべての表が消去されることがあります(プロバイダに <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL インジェクション</a>の試みの検出が設定されていない場合)。
531
532
533
534</p>
535<p>
536    この問題を回避するには、<code>?</code> を置き換え可能パラメータとして使う選択句と、選択引数の個別の配列を使用します。
537そうすることで、ユーザー入力は、SQL 文の一部として解釈されずに、クエリに直接バインドされます。
538
539    SQL として扱われないため、ユーザー入力によって悪意のある SQL が挿入されることはありません。ユーザー入力を含める際に連結を使用しないで、次の選択句を使用します。
540
541</p>
542<pre>
543// Constructs a selection clause with a replaceable parameter
544String mSelectionClause =  "var = ?";
545</pre>
546<p>
547    選択引数の配列を次のように設定します。
548</p>
549<pre>
550// Defines an array to contain the selection arguments
551String[] selectionArgs = {""};
552</pre>
553<p>
554    選択引数の配列に次のように値を格納します。
555</p>
556<pre>
557// Sets the selection argument to the user's input
558selectionArgs[0] = mUserInput;
559</pre>
560<p>
561    プロバイダが SQL データベースに基づいたものではない場合でも、選択内容を指定する場合は、<code>?</code> を置き換え可能パラメータとして使う選択句と、選択引数の配列を使用することをお勧めします。
562
563
564</p>
565<!-- Displaying the results -->
566<h3 id="DisplayResults">クエリ結果を表示する</h3>
567<p>
568    {@link android.content.ContentResolver#query ContentResolver.query()} クライアント メソッドは、常に {@link android.database.Cursor} を返します。これには、クエリの選択基準に一致する、行へのクエリの投影によって指定される列が含まれます。
569
570{@link android.database.Cursor} オブジェクトは、含まれる行と列へのランダム読み取りアクセスを提供します。
571
572{@link android.database.Cursor} メソッドを使用すると、結果の行の繰り返し、各列のデータタイプの識別、列からのデータの取得、結果のその他のプロパティの確認といった操作が可能となります。
573
574一部の {@link android.database.Cursor} を実装すると、プロバイダのデータが変更された場合にオブジェクトが自動的に送信されたり、{@link android.database.Cursor} が変更された場合にオブザーバ オブジェクトのメソッドがトリガーされたり、その両方が実行されたりします。
575
576
577</p>
578<p class="note">
579    <strong>注:</strong> クエリを作成するオブジェクトの特性に基づいて、プロバイダによって列へのアクセスが制限されることがあります。
580たとえば、連絡先プロバイダにより同期アダプタは一部の列へのアクセスが制限されるため、その場合はアクティビティやサービスを返しません。
581
582</p>
583<p>
584    選択基準に一致する行がない場合は、{@link android.database.Cursor#getCount Cursor.getCount()} が 0(空のカーソル)の {@link android.database.Cursor} オブジェクトを返します。
585
586
587</p>
588<p>
589    内部エラーが発生した場合、クエリの結果はプロバイダによって異なります。<code>null</code> が返されることもあれば、{@link java.lang.Exception} がスローされることもあります。
590
591</p>
592<p>
593    {@link android.database.Cursor} は行の「一覧」であることから、{@link android.database.Cursor} のコンテンツを表示する場合は、{@link android.widget.SimpleCursorAdapter} 経由で {@link android.widget.ListView} にリンクすることをお勧めします。
594
595
596</p>
597<p>
598    次のスニペットは前のスニペットのコードの続きです。クエリによって取得する {@link android.database.Cursor} を含む {@link android.widget.SimpleCursorAdapter} オブジェクトを作成し、このオブジェクトを {@link android.widget.ListView} のアダプタに設定します。
599
600
601
602</p>
603<pre class="prettyprint">
604// Defines a list of columns to retrieve from the Cursor and load into an output row
605String[] mWordListColumns =
606{
607    UserDictionary.Words.WORD,   // Contract class constant containing the word column name
608    UserDictionary.Words.LOCALE  // Contract class constant containing the locale column name
609};
610
611// Defines a list of View IDs that will receive the Cursor columns for each row
612int[] mWordListItems = { R.id.dictWord, R.id.locale};
613
614// Creates a new SimpleCursorAdapter
615mCursorAdapter = new SimpleCursorAdapter(
616    getApplicationContext(),               // The application's Context object
617    R.layout.wordlistrow,                  // A layout in XML for one row in the ListView
618    mCursor,                               // The result from the query
619    mWordListColumns,                      // A string array of column names in the cursor
620    mWordListItems,                        // An integer array of view IDs in the row layout
621    0);                                    // Flags (usually none are needed)
622
623// Sets the adapter for the ListView
624mWordList.setAdapter(mCursorAdapter);
625</pre>
626<p class="note">
627    <strong>注:</strong> {@link android.database.Cursor} によって {@link android.widget.ListView} を戻すには、カーソルに <code>_ID</code> という名前の列を含める必要があります。
628
629    そのため、{@link android.widget.ListView} には表示されまませんが、前述のクエリは「words」表に <code>_ID</code> 列を取得します。
630
631    また、このような制限があることから、大部分のプロバイダがそれぞれの表に <code>_ID</code> 列を持ちます。
632
633</p>
634
635        <!-- Getting data from query results -->
636<h3 id="GettingResults">クエリ結果を取得する</h3>
637<p>
638    クエリ結果を単に表示するだけでなく、他のタスクに使用することもできます。たとえば、単語リストからスペリングを取得して、それを他のプロバイダで検索するといった操作も可能です。
639
640そのためには、次のように {@link android.database.Cursor} の行に操作を繰り返します。
641</p>
642<pre class="prettyprint">
643
644// Determine the column index of the column named "word"
645int index = mCursor.getColumnIndex(UserDictionary.Words.WORD);
646
647/*
648 * Only executes if the cursor is valid. The User Dictionary Provider returns null if
649 * an internal error occurs. Other providers may throw an Exception instead of returning null.
650 */
651
652if (mCursor != null) {
653    /*
654     * Moves to the next row in the cursor. Before the first movement in the cursor, the
655     * "row pointer" is -1, and if you try to retrieve data at that position you will get an
656     * exception.
657     */
658    while (mCursor.moveToNext()) {
659
660        // Gets the value from the column.
661        newWord = mCursor.getString(index);
662
663        // Insert code here to process the retrieved word.
664
665        ...
666
667        // end of while loop
668    }
669} else {
670
671    // Insert code here to report an error if the cursor is null or the provider threw an exception.
672}
673</pre>
674<p>
675    {@link android.database.Cursor} の実装には「取得」メソッドがいくつか備わっており、オブジェクトからさまざまなタイプのデータを取得できます。
676たとえば、前述のスニペットは {@link android.database.Cursor#getString getString()} を使用しています。
677さらに、列のデータタイプを示す値を返す {@link android.database.Cursor#getType getType()} メソッドも使用しています。
678
679
680</p>
681
682
683    <!-- Requesting permissions -->
684<h2 id="Permissions">コンテンツ プロバイダ パーミッション</h2>
685<p>
686    プロバイダのアプリケーションでは、他のアプリケーションがプロバイダのデータにアクセスするのに必要なパーミッションを指定できます。
687これらのパーミッションを設定しておけば、ユーザーはアプリケーションがアクセスしようとしているデータの種類を把握できます。
688他のアプリケーションは、プロバイダの要件に基づき、そのプロバイダにアクセスするのに必要なパーミッションを要求します。
689エンドユーザーがアプリケーションをインストールする際には、要求されたパーミッションを確認できます。
690
691</p>
692<p>
693    プロバイダのアプリケーションでパーミッションを指定していない場合は、他のアプリケーションはプロバイダのデータにアクセスできません。
694ただし、指定したパーミッションに関係なく、プロバイダのアプリケーションのコンポーネントには完全な読み取り権限と書き込み権限を常に付与する必要があります。
695
696</p>
697<p>
698    前述のとおり、単語リスト プロバイダには、データを取得するための <code>android.permission.READ_USER_DICTIONARY</code> パーミッションが必要です。
699
700    プロバイダには、データの挿入、更新、削除に対してそれぞれ個別の <code>android.permission.WRITE_USER_DICTIONARY</code> パーミッションがあります。
701
702</p>
703<p>
704    プロバイダにアクセスするのに必要なパーミッションを取得するには、アプリケーションのマニフェスト ファイルの <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code> 要素を使用してパーミッションを要求する必要があります。
705
706Android Package Manager でアプリケーションをインストールする場合は、ユーザーがアプリケーションが要求するすべてのパーミッションを承認する必要があります。
707ユーザーがすべてのパーミッションを承認すると、Package Manager がインストールを続行します。ユーザーが承認しない場合は、Package Manager がインストールを中止します。
708
709
710</p>
711<p>
712    次の <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code> 要素は、単語リスト プロバイダへの読み取りアクセスを要求します。
713
714
715</p>
716<pre>
717    &lt;uses-permission android:name="android.permission.READ_USER_DICTIONARY"&gt;
718</pre>
719<p>
720    プロバイダ アクセスへのパーミッションの影響については、<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>に関するガイドをご覧ください。
721
722</p>
723
724
725<!-- Inserting, Updating, and Deleting Data -->
726<h2 id="Modifications">データを挿入、更新、削除する</h2>
727<p>
728    データを収集するには、プロバイダからデータを取得するのと同様に、プロバイダ クライアントとプロバイダの {@link android.content.ContentProvider} 間で操作を行います。
729
730    対応する {@link android.content.ContentProvider} のメソッドに渡した引数を使用して、{@link android.content.ContentResolver} のメソッドを呼び出します。
731プロバイダとプロバイダ クライアントが、セキュリティとプロセス間の通信を自動的に処理します。
732
733</p>
734<h3 id="Inserting">データを挿入する</h3>
735<p>
736    プロバイダにデータを挿入するには、{@link android.content.ContentResolver#insert ContentResolver.insert()} メソッドを呼び出します。
737
738このメソッドはプロバイダに新しい行を挿入し、その行のコンテンツ URI を返します。
739    このスニペットは、単語リスト プロバイダに新しい単語を挿入する方法を示しています。
740</p>
741<pre class="prettyprint">
742// Defines a new Uri object that receives the result of the insertion
743Uri mNewUri;
744
745...
746
747// Defines an object to contain the new values to insert
748ContentValues mNewValues = new ContentValues();
749
750/*
751 * Sets the values of each column and inserts the word. The arguments to the "put"
752 * method are "column name" and "value"
753 */
754mNewValues.put(UserDictionary.Words.APP_ID, "example.user");
755mNewValues.put(UserDictionary.Words.LOCALE, "en_US");
756mNewValues.put(UserDictionary.Words.WORD, "insert");
757mNewValues.put(UserDictionary.Words.FREQUENCY, "100");
758
759mNewUri = getContentResolver().insert(
760    UserDictionary.Word.CONTENT_URI,   // the user dictionary content URI
761    mNewValues                          // the values to insert
762);
763</pre>
764<p>
765    新しい行のデータは 1 つの {@link android.content.ContentValues} オブジェクトに入ります。これは 1 行カーソルの形式に似ています。
766このオブジェクト内の列は同じデータタイプを持つ必要はなく、値をまったく指定しない場合は、{@link android.content.ContentValues#putNull ContentValues.putNull()} を使用して列を <code>null</code> に設定できます。
767
768
769</p>
770<p>
771    この列は自動的に保持されるため、スニペットは <code>_ID</code> 列を追加しません。
772プロバイダは、追加するそれぞれの行に、<code>_ID</code> の一意の値を割り当てます。
773通常、プロバイダはこの値を表のプライマリキーとして使用します。
774</p>
775<p>
776    <code>newUri</code> で返されるコンテンツ URI は、新たに追加された行を特定するものであり、次の形式となります。
777
778</p>
779<pre>
780content://user_dictionary/words/&lt;id_value&gt;
781</pre>
782<p>
783    <code>&lt;id_value&gt;</code> は、新しい行の <code>_ID</code> のコンテンツです。
784    ほとんどのプロバイダではコンテンツ URI のこの形式を自動的に検出し、特定の行で要求された操作を実行します。
785
786</p>
787<p>
788    返された {@link android.net.Uri} から <code>_ID</code> の値を取得するには、{@link android.content.ContentUris#parseId ContentUris.parseId()} を呼び出します。
789
790</p>
791<h3 id="Updating">データを更新する</h3>
792<p>
793    行を更新するには、挿入操作と同じように、値を更新した {@link android.content.ContentValues} オブジェクトと、クエリ操作のときと同じように選択基準を使用します。
794
795    使用するクライアント メソッドは {@link android.content.ContentResolver#update ContentResolver.update()} です。
796更新する列の {@link android.content.ContentValues} オブジェクトに値を追加する操作のみが必要になります。
797列のコンテンツを消去する場合は、値を <code>null</code> に設定します。
798
799</p>
800<p>
801    次のスニペットは、ロケール言語が「en」となっているすべての行のロケールを <code>null</code> に変更します。
802戻り値は、更新された行の数となります。
803</p>
804<pre>
805// Defines an object to contain the updated values
806ContentValues mUpdateValues = new ContentValues();
807
808// Defines selection criteria for the rows you want to update
809String mSelectionClause = UserDictionary.Words.LOCALE +  "LIKE ?";
810String[] mSelectionArgs = {"en_%"};
811
812// Defines a variable to contain the number of updated rows
813int mRowsUpdated = 0;
814
815...
816
817/*
818 * Sets the updated value and updates the selected words.
819 */
820mUpdateValues.putNull(UserDictionary.Words.LOCALE);
821
822mRowsUpdated = getContentResolver().update(
823    UserDictionary.Words.CONTENT_URI,   // the user dictionary content URI
824    mUpdateValues                       // the columns to update
825    mSelectionClause                    // the column to select on
826    mSelectionArgs                      // the value to compare to
827);
828</pre>
829<p>
830    また、{@link android.content.ContentResolver#update ContentResolver.update()} を呼び出すときには、ユーザー入力をサニタイズする必要があります。
831詳細は、<a href="#Injection">悪意のある入力から保護する</a>セクションをご覧ください。
832
833</p>
834<h3 id="Deleting">データを削除する</h3>
835<p>
836    行の削除は行データの取得と似た操作になります。削除する行の選択基準を指定することで、クライアント メソッドが削除した行の数を返します。
837
838    次のスニペットは appid が「user」となっている行を削除します。メソッドによって削除された行の数が返されます。
839
840</p>
841<pre>
842
843// Defines selection criteria for the rows you want to delete
844String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
845String[] mSelectionArgs = {"user"};
846
847// Defines a variable to contain the number of rows deleted
848int mRowsDeleted = 0;
849
850...
851
852// Deletes the words that match the selection criteria
853mRowsDeleted = getContentResolver().delete(
854    UserDictionary.Words.CONTENT_URI,   // the user dictionary content URI
855    mSelectionClause                    // the column to select on
856    mSelectionArgs                      // the value to compare to
857);
858</pre>
859<p>
860    また、{@link android.content.ContentResolver#delete ContentResolver.delete()} を呼び出すときには、ユーザー入力をサニタイズする必要があります。
861詳細は、<a href="#Injection">悪意のある入力から保護する</a>セクションをご覧ください。
862
863</p>
864<!-- Provider Data Types -->
865<h2 id="DataTypes">プロバイダ データタイプ</h2>
866<p>
867    コンテンツ プロバイダではさまざまなデータタイプを利用できます。単語リスト プロバイダで提供できるのはテキストのみですが、次のような形式を提供できます。
868
869</p>
870    <ul>
871        <li>
872            整数
873        </li>
874        <li>
875            long 整数(long)
876        </li>
877        <li>
878            浮動小数点
879        </li>
880        <li>
881            long 浮動小数点(double)
882        </li>
883    </ul>
884<p>
885    それ以外にも、プロバイダでは 64KB バイト配列として実装されるバイナリ ラージ オブジェクト(BLOB)もよく使用されます。
886利用可能なデータタイプについては、{@link android.database.Cursor} クラスの「get」メソッドをご覧ください。
887
888</p>
889<p>
890    プロバイダの各列のデータタイプは、通常、そのドキュメントに一覧が記載されています。
891    単語リスト プロバイダのデータタイプは、コントラクト クラス {@link android.provider.UserDictionary.Words} のリファレンスに一覧が記載されています(コントラクト クラスの詳細は、<a href="#ContractClasses">コントラクト クラス</a>セクションをご覧ください)。
892
893
894    さらに、{@link android.database.Cursor#getType
895    Cursor.getType()} を呼び出すことで、データタイプを判断することもできます。
896</p>
897<p>
898    プロバイダは、プロバイダによって定義される各コンテンツ URI の MIME データタイプも保持します。MIME タイプ情報を使用すると、プロバイダが提供するデータをアプリケーションが処理できるかを判断したり、MIME タイプに基づいて処理のタイプを選択したりできます。
899
900通常は、複雑なデータ構造やファイルを持つプロバイダで作業をする際に MIME タイプが必要になります。
901
902たとえば、連絡先プロバイダの {@link android.provider.ContactsContract.Data} 表は MIME タイプを使用して、それぞれの行に格納される連絡先データのタイプをラベル付けします。
903
904コンテンツ URI に対応する MIME タイプを取得するには、{@link android.content.ContentResolver#getType ContentResolver.getType()} を呼び出します。
905
906</p>
907<p>
908    「<a href="#MIMETypeReference">MIME タイプ リファレンス</a>」セクションでは、標準とカスタムの両方の MIME タイプについて説明しています。
909
910</p>
911
912
913<!-- Alternative Forms of Provider Access -->
914<h2 id="AltForms">プロバイダ アクセスの別の形式</h2>
915<p>
916    アプリケーションの開発では、次に示すプロバイダ アクセスの別の 3 つの形式が重要になります。
917</p>
918<ul>
919    <li>
920        <a href="#Batch">バッチアクセス</a>: {@link android.content.ContentProviderOperation} クラスのメソッドを使用したアクセス呼び出しのバッチを作成し、{@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()} に適用できます。
921
922
923    </li>
924    <li>
925        非同期クエリ: クエリは個別のスレッドで実行する必要があります。この操作は、{@link android.content.CursorLoader} オブジェクトを使用して行うこともできます。
926「<a href="{@docRoot}guide/components/loaders.html">ローダ</a>」のガイドには、この操作の例が記載されています。
927
928
929    </li>
930    <li>
931        <a href="#Intents">インテント経由のデータアクセス</a>: インテントをプロバイダに直接送信できませんが、プロバイダのアプリケーションにはインテントを送信できます。通常、プロバイダのデータの修正に最適な機能を備えたアプリケーションになります。
932
933
934    </li>
935</ul>
936<p>
937    バッチアクセスとインテント経由の修正については、次のセクションで説明しています。
938</p>
939<h3 id="Batch">バッチアクセス</h3>
940<p>
941    多数の行を挿入する場合や、同じメソッド呼び出しで複数の表に行を挿入する場合は、プロバイダへのバッチアクセスを使用すると便利です。また、一般的には、境界をまたいでプロセス全体にトランザクションとして一連の操作を実行する場合にもバッチアクセスが便利です。
942
943
944</p>
945<p>
946    「バッチモード」でプロバイダにアクセスするには、{@link android.content.ContentProviderOperation} オブジェクトの配列を作成してから、{@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()} を使用してそれらのオブジェクトをコンテンツ プロバイダに送信します。
947
948
949このメソッドには、特定のコンテンツ URI ではなく、コンテンツ プロバイダの<em>認証局</em>を渡します。そうすることで、配列内のそれぞれの {@link android.content.ContentProviderOperation} オブジェクトを別々の表に対して機能するようになります。
950
951
952{@link android.content.ContentResolver#applyBatch
953    ContentResolver.applyBatch()} への呼び出しでは、結果の配列が返されます。
954</p>
955<p>
956    {@link android.provider.ContactsContract.RawContacts} コントラクト クラスの説明には、バッチ挿入を示したコード スニペットが記載されています。
957<a href="{@docRoot}resources/samples/ContactManager/index.html">Contact Manager</a> のサンプル アプリケーションでは、<code>ContactAdder.java</code> ソースファイルでのバッチアクセスの例が紹介されています。
958
959
960
961</p>
962<div class="sidebox-wrapper">
963<div class="sidebox">
964<h2>ヘルパーアプリでデータを表示する</h2>
965<p>
966    アプリケーションにアクセス パーミッションが<em>付与されている</em>場合でも、インテントを使用して別のアプリケーションにデータを表示できます。
967たとえば、カレンダー アプリケーションは {@link android.content.Intent#ACTION_VIEW} インテントにアクセスしますが、このインテントは特定の日付やイベントを表示するものです。
968
969    これにより、独自の UI を作成しなくても、カレンダー情報を表示できます。この機能の詳細は、「<a href="{@docRoot}guide/topics/providers/calendar-provider.html">カレンダー プロバイダ</a>」のガイドをご覧ください。
970
971
972</p>
973<p>
974    インテントの送信先アプリケーションは、必ずしもプロバイダに関連付けられたアプリケーションである必要はありません。
975たとえば、連絡先プロバイダから連絡先を取得してから、連絡先の画像のコンテンツ URI を含む {@link android.content.Intent#ACTION_VIEW} インテントを画像ビューワに送信するといった操作が可能です。
976
977
978</p>
979</div>
980</div>
981<h3 id="Intents">インテント経由のデータアクセス</h3>
982<p>
983    インテントを使用すれば、コンテンツ プロバイダに間接的にアクセスできます。アプリケーションにアクセス パーミッションがない場合でも、パーミッションを持つアプリケーションから結果のインテントを取得したり、パーミッションを持つアプリケーションをアクティベートしてそのアプリケーションをユーザーに使用させたりすることで、ユーザーがプロバイダのデータにアクセスできるようになります。
984
985
986
987</p>
988<h4>一時的なパーミッションによりアクセスを取得する</h4>
989<p>
990    適切なアクセス パーミッションがない場合でも、パーミッションを持つアプリケーションにインテントを送信し、「URI」パーミッションを含む結果のインテントを受け取ることで、コンテンツ プロバイダのデータにアクセスできます。
991
992
993    これらのパーミッションは特定のコンテンツ URI のパーミッションであり、パーミッションを受け取ったアクティビティが終了するまで効力を持ちます。
994永続的なパーミッションを持つアプリケーションは、次のように結果のインテントにフラグを設定し、一時的なパーミッションを付与します。
995
996</p>
997<ul>
998    <li>
999        <strong>読み取りパーミッション:</strong> {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}
1000
1001    </li>
1002    <li>
1003        <strong>書き込みパーミッション:</strong> {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}
1004
1005    </li>
1006</ul>
1007<p class="note">
1008    <strong>注:</strong> これらのフラグは、認証局がコンテンツ URI に含まれるプロバイダへの全般的な読み取りと書き込みアクセスを付与するものではありません。アクセスは URI 自身に限定されます。
1009
1010</p>
1011<p>
1012    プロバイダは、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">android:grantUriPermission</a></code> 属性や、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code> 子要素を使用して、コンテンツ URI の URI パーミッションを自身のマニフェストで定義します。
1013
1014
1015
1016
1017
1018
1019
1020URI パーミッションのメカニズムについての詳細は、URI パーミッション セクションの<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>に関するガイドをご覧ください。
1021
1022
1023</p>
1024<p>
1025    たとえば、{@link android.Manifest.permission#READ_CONTACTS} パーミッションを持たない場合でも、連絡先プロバイダの連絡先のデータを取得できます。
1026連絡先の誕生日にグリーティング カードをオンラインで送信するアプリケーションなどにこのメカニズムを利用できます。
1027ユーザーのすべての連絡先やそのすべての情報へのアクセス件を付与する {@link android.Manifest.permission#READ_CONTACTS} を要求する代わりに、アプリケーションで使用する連絡先をユーザーが制御できるように設定することもできます。
1028
1029
1030そのためには、次の手順を使用します。
1031</p>
1032<ol>
1033    <li>
1034        アプリケーションが、メソッド {@link android.app.Activity#startActivityForResult
1035        startActivityForResult()} を使用して、アクション {@link android.content.Intent#ACTION_PICK} と「連絡先」MIME タイプ {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} を含むインテントを送信します。
1036
1037
1038
1039    </li>
1040    <li>
1041        このインテントは連絡帳アプリの「selection」アクティビティのインテント フィルタに一致するため、アクティビティがフォアグラウンドに移動します。
1042
1043    </li>
1044    <li>
1045        selection アクティビティでは、更新する連絡先をユーザーが選択します。
1046この操作が行われると、selection が {@link android.app.Activity#setResult setResult(resultcode, intent)} を呼び出し、アプリケーションに戻すインテントを設定します。
1047
1048インテントには、ユーザーが選択した連絡先のコンテンツ URI と、「エクストラ」フラグ {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} が含まれます。
1049
1050これらのフラグがあることで、コンテンツ URI がポイントする連絡先のデータを読み取るための URI パーミッションがアプリに付与されます。その後、selection アクティビティによって、アプリケーションに制御を返すための {@link android.app.Activity#finish()} が呼び出されます。
1051
1052
1053
1054    </li>
1055    <li>
1056        アクティビティがフォアグラウンドに戻り、システムがアクティビティの {@link android.app.Activity#onActivityResult onActivityResult()} メソッドを呼び出します。
1057
1058このメソッドは、連絡帳アプリの selection アクティビティによって作成された結果のインテントを受け取ります。
1059
1060    </li>
1061    <li>
1062        結果のインテントのコンテンツ URI を使用すれば、マニフェストで永続的なアクセス パーミッションをプロバイダに要求していなくても、連絡先プロバイダから連絡先のデータを読み取ることができます。
1063
1064その後、連絡先の誕生日情報やメールアドレスを取得し、グリーティング カードをオンラインで送信できます。
1065
1066    </li>
1067</ol>
1068<h4>別のアプリケーションを使用する</h4>
1069<p>
1070    パーミッションを持つアプリケーションをアクティベートし、そのアプリケーションをユーザーが使用すれば、アクセス パーミッションを持たないデータをユーザーが修正できるようになります。
1071
1072</p>
1073<p>
1074    たとえば、アプリケーションの挿入 UI をアクティベートできる {@link android.content.Intent#ACTION_INSERT} インテントをカレンダー アプリケーションが受け入れるとします。このインテントに「エクストラ」データを渡すことで、アプリケーションがそのデータを使用して、事前に入力された UI を作成します。繰り返し発生するイベントは複雑な構文を持つため、カレンダー プロバイダにイベントを挿入する場合は、{@link android.content.Intent#ACTION_INSERT} でカレンダー アプリをアクティベートしてから、ユーザーにイベントを挿入してもらうことをお勧めします。
1075
1076
1077
1078
1079
1080</p>
1081<!-- Contract Classes -->
1082<h2 id="ContractClasses">コントラクト クラス</h2>
1083<p>
1084    コントラクト クラスは、アプリケーションがコンテンツ URI、列名、インテント アクション、コンテンツのその他の機能で作業する際に役立つ定数を定義します。
1085プロバイダでコントラクト クラスが自動的に含まれることはありません。プロバイダのデベロッパーはコントラクト クラスを定義して、その他のデベロッパーが使用できるようにする必要があります。
1086
1087Android プラットフォームに含まれる多くのプロバイダは、パッケージ {@link android.provider} 内に対応するコントラクト クラスを持ちます。
1088
1089</p>
1090<p>
1091    たとえば、単語リスト プロバイダは、コンテンツ URI と列名の定数を含む、コントラクト クラス {@link android.provider.UserDictionary} を持つとします。
1092「words」表のコンテンツ URI は、定数 {@link android.provider.UserDictionary.Words#CONTENT_URI UserDictionary.Words.CONTENT_URI} で定義されます。
1093
1094
1095    さらに、{@link android.provider.UserDictionary.Words} クラスは、このガイドのサンプルのスニペットで使用される、列名の定数を持ちます。
1096たとえば、クエリの投影は次のように定義できます。
1097
1098</p>
1099<pre>
1100String[] mProjection =
1101{
1102    UserDictionary.Words._ID,
1103    UserDictionary.Words.WORD,
1104    UserDictionary.Words.LOCALE
1105};
1106</pre>
1107<p>
1108    もう一方のコントラクト クラスは、連絡先プロバイダのクラス {@link android.provider.ContactsContract} です。
1109    このクラスのリファレンスには、サンプルのコード スニペットが記載されています。サブクラスの 1 つである {@link android.provider.ContactsContract.Intents.Insert} は、インテントとインテント データの定数を含むコントラクト クラスです。
1110
1111
1112</p>
1113
1114
1115<!-- MIME Type Reference -->
1116<h2 id="MIMETypeReference">MIME タイプ リファレンス</h2>
1117<p>
1118    コンテンツ プロバイダは、標準の MIME メディア タイプかカスタムの MIME タイプ文字列、またはその両方を返すことができます。
1119</p>
1120<p>
1121    MIME タイプは次の形式となります
1122</p>
1123<pre>
1124<em>type</em>/<em>subtype</em>
1125</pre>
1126<p>
1127    たとえば、よく利用される MIME タイプ <code>text/html</code> は、<code>text</code> タイプと <code>html</code> サブタイプを持ちます。
1128プロバイダから URI に対してこのタイプが返される場合、その URI を使用するクエリは HTML タグを含むテキストを返すことになります。
1129
1130</p>
1131<p>
1132    「ベンダー固有の」MIME タイプとも呼ばれるカスタムの MIME タイプ文字列には、より複雑な <em>type</em> と <em>subtype</em> の値が含まれます。
1133複数行の場合、<em>type</em> 値は常に
1134</p>
1135<pre>
1136vnd.android.cursor.<strong>dir</strong>
1137</pre>
1138<p>
1139    となり、1 つの行の場合は
1140</p>
1141<pre>
1142vnd.android.cursor.<strong>item</strong>
1143</pre>
1144<p>
1145    となります。
1146</p>
1147<p>
1148    <em>subtype</em> はプロバイダ固有の値になります。通常、Android 組み込みプロバイダは単純な subtype を使用します。
1149たとえば、連絡先アプリケーションが電話番号の行を作成すると、行には次のように MIME タイプが設定されます。
1150
1151</p>
1152<pre>
1153vnd.android.cursor.item/phone_v2
1154</pre>
1155<p>
1156    subtype の値は単純に <code>phone_v2</code> となっていることがわかります。
1157</p>
1158<p>
1159    他のプロバイダ デベロッパーは、プロバイダの認証局と表明に基づいて独自のパターンの subtype を作成できます。
1160たとえば、列車の時刻表を含むプロバイダについて考えてみます。
1161    プロバイダの認証局は <code>com.example.trains</code> であり、表 Line1、Line2、Line3 を持ちます。
1162表 Line1 のコンテンツ URI
1163</p>
1164<p>
1165<pre>
1166content://com.example.trains/Line1
1167</pre>
1168<p>
1169    に対しては、プロバイダは次の MIME タイプを返します
1170</p>
1171<pre>
1172vnd.android.cursor.<strong>dir</strong>/vnd.example.line1
1173</pre>
1174<p>
1175     表 Line2 の行 5 のコンテンツ URI
1176</p>
1177<pre>
1178content://com.example.trains/Line2/5
1179</pre>
1180<p>
1181    に対しては、プロバイダは次の MIME タイプを返します
1182</p>
1183<pre>
1184vnd.android.cursor.<strong>item</strong>/vnd.example.line2
1185</pre>
1186<p>
1187    ほとんどのコンテンツ プロバイダが、使用する MIME タイプに対してコントラクト クラス定数を定義します。たとえば、連絡先プロバイダのコントラクト クラス {@link android.provider.ContactsContract.RawContacts} は、1 つの未加工連絡先行の MIME タイプに、定数 {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} を定義します。
1188
1189
1190
1191
1192</p>
1193<p>
1194    1 つの行のコンテンツ URI については、<a href="#ContentURIs">コンテンツ URI</a> セクションをご覧ください。
1195
1196</p>
1197