diff options
author | Trevor Johns <trevorjohns@google.com> | 2016-04-05 19:43:35 -0700 |
---|---|---|
committer | Trevor Johns <trevorjohns@google.com> | 2016-04-05 20:32:07 -0700 |
commit | a5060ee80dbb48bd7fc545d2aeeeb657b79893ea (patch) | |
tree | 842bb82e198dccade4bfb3ceafcc01f96083cd34 /docs/html-intl/intl/ja | |
parent | ebf3261aa6d80ad4ca1df0fd0509961ff7a1914e (diff) | |
parent | 9577d31b10aa654d3ba63947e7733945a358395e (diff) |
Merge branch 'mnc-mr-docs' into mnc-ub-dev
Large merge to reconnect automerger for docs branch to mainline.
Conflicts:
docs/html-intl/intl/es/index.jd
docs/html-intl/intl/es/preview/download.jd
docs/html-intl/intl/es/preview/index.jd
docs/html-intl/intl/ja/index.jd
docs/html-intl/intl/ja/preview/download.jd
docs/html-intl/intl/ja/preview/index.jd
docs/html-intl/intl/ko/index.jd
docs/html-intl/intl/ko/preview/download.jd
docs/html-intl/intl/ko/preview/index.jd
docs/html-intl/intl/pt-br/index.jd
docs/html-intl/intl/pt-br/preview/download.jd
docs/html-intl/intl/pt-br/preview/index.jd
docs/html-intl/intl/ru/index.jd
docs/html-intl/intl/ru/preview/download.jd
docs/html-intl/intl/ru/preview/index.jd
docs/html-intl/intl/zh-cn/index.jd
docs/html-intl/intl/zh-cn/preview/download.jd
docs/html-intl/intl/zh-cn/preview/index.jd
docs/html-intl/intl/zh-tw/index.jd
docs/html-intl/intl/zh-tw/preview/download.jd
docs/html-intl/intl/zh-tw/preview/index.jd
docs/html/guide/topics/manifest/compatible-screens-element.jd
docs/html/guide/topics/manifest/uses-feature-element.jd
docs/html/preview/download.jd
docs/html/preview/features/runtime-permissions.jd
docs/html/sdk/index.jd
docs/html/tools/revisions/studio.jd
docs/html/tools/sdk/eclipse-adt.jd
docs/html/tools/support-library/features.jd
telephony/java/android/telephony/TelephonyManager.java
Bug: 28000173
Change-Id: Iacab0481175f1b32e0ac3bab98cde9e994100e94
Diffstat (limited to 'docs/html-intl/intl/ja')
61 files changed, 23187 insertions, 4519 deletions
diff --git a/docs/html-intl/intl/ja/design/get-started/principles.jd b/docs/html-intl/intl/ja/design/get-started/principles.jd index 8e4149da0011..dde44ffee42e 100644 --- a/docs/html-intl/intl/ja/design/get-started/principles.jd +++ b/docs/html-intl/intl/ja/design/get-started/principles.jd @@ -1,29 +1,29 @@ -page.title=Android デザイン指針 +page.title=Android デザインの原則 @jd:body -<p>このデザイン指針は、ユーザーがもっとも知りたいと思われることを中心に、Android User Experience Team により、またその活動を統一的なものにするために作成されたものです。Android デベロッパーとデザイナーに対しては各種端末向けのより詳細なデザイン ガイドラインがあります。 - +<p>このデザインの原則は、ユーザーがもっとも知りたいと思われることを中心に、Android User Experience Team により、またその活動を統一的なものにするために作成されたものです。 +Android デベロッパーとデザイナーに対しては各種端末向けのより詳細なデザイン ガイドラインがあります。 </p> <p> -ご自身の創造性やデザインについて考える際、この指針を考慮に入れてください。 +ご自身のクリエイティビティやデザインについて考える際、この原則を考慮に入れてください。 何を当てはめるかは目的に応じて調整してください。 </p> <h2 id="enchant-me">ユーザーを引きつける</h2> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> <h4 id="delight-me">サプライズで楽しませる</h4> -<p>美しい画面、考え抜かれて配置されたアニメーション、タイミングの良いサウンド エフェクトは、使っていて楽しくなります。 +<p>美しい画面、思慮深く配置されたアニメーション、タイミングの良いサウンド エフェクトは、使っていて楽しくなります。 わずかな効果でも、ユーザーを楽しませ、力を得たように感じてもらえます。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_delight.png"> @@ -32,15 +32,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> <h4 id="real-objects-more-fun">ボタンやメニューよりもリアルなオブジェクトでさらに楽しく</h4> -<p>ユーザーがアプリでオブジェクトを直接タップしたり操作したりできるようになります。タスクを実行するために必要な認知の労力が軽減され、感覚的な満足度も上がります。 +<p>アプリでオブジェクトを直接タップしたり操作したりできます。タスクを試行錯誤しながら実行する必要はなく、アプリの満足度も上がります。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_real_objects.png"> @@ -49,16 +49,16 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="make-it-mine">自分らしさを加える</h4> -<p>ユーザーは自分でカスタマイズすることを好みます。これにより、くつろいだ気分や自分の思いのままできる自由な気分を味わうことができます。デフォルトで実用的で美しいものを取りそろえ、それに加えてメイン タスクの妨げにならない、楽しいカスタマイズも任意で加えられます。 +<h4 id="make-it-mine">アプリに自分らしさをプラス</h4> +<p>誰もがアプリで自分らしさを出したいと思っています。好きなようにアプリを操作できるからです。実用的で美しい機能があらかじめ用意されており、それに加えてメイン タスクの邪魔にならない、楽しいカスタマイズもできます。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_make_it_mine.png"> @@ -67,31 +67,31 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="get-to-know-me">ユーザーについて知る</h4> -<p>徐々にユーザーの好みを学習していきます。同じ選択を繰り返す手間をかけず、前に選択したものをすぐに選べるようになります。 +<h4 id="get-to-know-me">ユーザーの好みを学習</h4> +<p>徐々にユーザーの好みを学習していきます。ユーザーに何度も同じ選択をさせるのではなく、前に選択したものをすぐに選べるようにします。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_get_to_know_me.png"> </div> </div> -<h2 id="simplify-my-life">よりシンプルに</h2> +<h2 id="simplify-my-life">生活をシンプルに</h2> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="keep-it-brief">常に簡潔に</h4> -<p>シンプルな言葉を並べた短いフレーズを用います。長い文章は好まれません。</p> +<h4 id="keep-it-brief">簡潔を心がける</h4> +<p>シンプルで短いフレーズを用います。長い文章は好まれません。</p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_keep_it_brief.png"> @@ -100,15 +100,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> <h4 id="pictures-faster-than-words">画像は言葉よりもわかりやすい</h4> -<p>画像を使ってアイデアを説明してみましょう。ユーザーの興味を引くことができ、言葉よりも効率的です。 +<p>画像を使ってアイデアを説明してみましょう。ユーザーの興味を引くことができ、言葉よりも効果的です。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_pictures.png"> @@ -117,15 +117,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> <h4 id="decide-for-me">選択は最小限に、最終決定はユーザーに</h4> -<p>最初からユーザーにすべて尋ねるのではなく、もっとも適切と思われる項目を提示します。選択肢や決定事項が多すぎると面倒に感じます。 -推測が間違っていた場合に備え、「やり直し」も可能にします。</p> +<p>最初からユーザーに選ばせるのではなく、適切と思われる項目を提示します。選択肢や決定事項が多すぎるとユーザーは面倒に感じます。 +間違った選択をしても、「やり直し」ができます。</p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_decide_for_me.png"> @@ -134,15 +134,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="only-show-when-i-need-it">必要なものを必要なときにだけ表示する</h4> +<h4 id="only-show-when-i-need-it">必要なものを必要なときに</h4> <p>一度に表示される内容が多すぎると疲れてしまいます。タスクや情報はいくつかに小さくまとめてわかりやすくします。 その時点で必要のないオプションは非表示にして、必要なときだけ表示します。</p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_information_when_need_it.png"> @@ -151,15 +151,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="always-know-where-i-am">全体像から現在の位置を示す</h4> -<p>ユーザーがはっきりと自分の現在の場所を把握できるようにします。アプリのどの場所にいるかを明示し、遷移して画面の関係を認識できるようにします。 -実行しているタスクに対して応答し続けます。</p> +<h4 id="always-know-where-i-am">現在位置を把握する</h4> +<p>ユーザーが現在アプリのどこにいるのかがすぐに分かります。アプリ内における現在位置を明示し、遷移を使用して画面間の関係を表示します。 +実行中のタスクにフィードバックを返します。</p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_navigation.png"> @@ -168,16 +168,16 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="never-lose-my-stuff">作成したものは失くさない</h4> -<p>ユーザーが時間をかけて作ったものは保存して、どこからでもアクセスできるようにします。設定、独自のカスタマイズ、電話、タブレット、コンピュータで作成したものを記録します。 -アップグレードも簡単になります。 +<h4 id="never-lose-my-stuff">作成物を失くさない</h4> +<p>ユーザーが時間をかけて作ったものは保存して、どこからでもアクセスできるようにします。設定、独自のカスタマイズ、および携帯端末、タブレット、コンピュータで作成したものを保存します。 +アップグレードも簡単にできます。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_never_lose_stuff.png"> @@ -186,15 +186,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="looks-same-should-act-same">見た目が同じ場合は機能も同じにする</h4> -<p>視覚的な違いを際立たせ、ユーザーが機能の違いをはっきり区別できるようにします。同じような外観、同じ入力で機能が異なるようなモードは避けます。 -</p> +<h4 id="looks-same-should-act-same">見た目が同じなら機能も同じ</h4> +<p>機能の違いがはっきり分かるように、特徴的なビジュアルにします。 +同じような外観、同じ入力方法なのに機能が異なるということのないようにします。</p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_looks_same.png"> @@ -203,15 +203,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="interrupt-only-if-important">割り込みは重要なときにだけ行う</h4> -<p>優秀な個人秘書のように、重要ではない些細なことでユーザーをわずらわせることのないよう配慮します。集中したいユーザーにとって、重要で一刻を争うようなものでない限り、割り込まれると面倒で不快に感じる可能性があります。 +<h4 id="interrupt-only-if-important">割り込みは必要な場合のみ</h4> +<p>優秀な個人秘書のように、ユーザーを些細なことでわずらわせないようにします。ユーザーは実行中の操作に専念したいと考えており、重要で一刻を争うようなものでない限り、割り込みは面倒で不快と感じます。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_important_interruption.png"> @@ -220,16 +220,16 @@ page.title=Android デザイン指針 <h2 id="make-me-amazing">操作を楽しく</h2> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="give-me-tricks">あらゆる場所に工夫を仕込む</h4> -<p>自分で理解すると嬉しく感じられます。Android アプリで広く使われている視覚や操作のパターンを生かし、アプリの操作をわかりやすいものにします。 -たとえばスワイプ操作は便利なナビゲーションのショートカットとして使えます。 +<h4 id="give-me-tricks">あらゆる場所に工夫を凝らす</h4> +<p>理解できれば楽しくなります。Android アプリで広く使われている視覚や操作のパターンを生かし、アプリの操作をわかりやすいものにします。 +たとえばスワイプ操作は、ナビゲーションのショートカットとして使えるので便利です。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_tricks.png"> @@ -238,16 +238,16 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="its-not-my-fault">解決は簡単に</h4> -<p>ユーザーに修正を促す場合はその方法に注意します。アプリではスマートに問題を解決できるようにします。うまくいかなかったときは解決方法を明確に示し、技術的な詳細を表示する必要はありません。自動的に修正できる問題はユーザーに通知する必要すらありません。 - -</p> +<h4 id="its-not-my-fault">ユーザーの責任にしない</h4> +<p>ユーザーに修正を促す場合はその方法に注意します。ユーザーはアプリをスマートに使いこなしたいと考えています。 +うまくいかなかったときの解決方法は明確でなければなりませんが、技術的に詳細である必要はありません。 +自動的に修正できる問題については、通知も不要です。</p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_error.png"> @@ -256,15 +256,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> <h4 id="sprinkle-encouragement">操作を促すしかけを散りばめる</h4> -<p>複雑なタスクは分割し、それぞれ簡単に達成できるようにします。1 つ 1 つにフィードバックすることで、ユーザーの満足度は高まります。 +<p>複雑なタスクは分割し、簡単に達成できるようにします。1 つ 1 つのアクションにフィードバックすることで、ユーザーの満足度は高まります。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png"> @@ -273,16 +273,16 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> -<h4 id="do-heavy-lifting-for-me">作業の手間はかけない</h4> -<p>できると思っていなかったことをできるようにすることで、知識がなくても専門家のような気分を味わってもらえます。たとえば複数の写真効果を組み合わせたショートカットを使うことで、わずかな手順でプロのような写真に仕上げられます。 +<h4 id="do-heavy-lifting-for-me">手間のかかる作業は不要</h4> +<p>できないと思っていたことができるようになれば、初心者でもエキスパートの気分が味わえます。たとえば複数の写真効果を組み合わせるショートカットを使うことで、わずかな手順でプロのような写真に仕上げられます。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_heavy_lifting.png"> @@ -291,15 +291,15 @@ page.title=Android デザイン指針 <div class="vspace size-2"> </div> -<div class="layout-content-row"> - <div class="layout-content-col span-7"> +<div class="cols"> + <div class="col-7"> <h4 id="make-important-things-fast">重要なことはすみやかに</h4> -<p>すべてのアクションが同じ優先度とは限りません。アプリのアクションには優先度を設定し、重要なものはたとえばカメラのシャッター ボタンや音楽プレイヤーの一時停止ボタンのように、簡単に見つけられすぐに使えるようにします。 +<p>すべてのアクションが同じ優先度とは限りません。アプリのアクションに優先度を設定し、カメラのシャッター ボタンや音楽プレイヤーの一時停止ボタンのように重要なものは、簡単に見つけてすぐに使えるようにします。 </p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/principles_make_important_fast.png"> diff --git a/docs/html-intl/intl/ja/design/material/index.jd b/docs/html-intl/intl/ja/design/material/index.jd index 3acd4234863f..3330b0cbe6a4 100644 --- a/docs/html-intl/intl/ja/design/material/index.jd +++ b/docs/html-intl/intl/ja/design/material/index.jd @@ -1,15 +1,14 @@ -page.title=マテリアル デザイン -page.tags=Material, design -page.type=design -page.image=design/material/images/MaterialLight.png +page.title=Android のマテリアル デザイン +page.tags=Material,design +page.image=images/cards/design-material-for-android_2x.jpg @jd:body <!-- developer docs box --> <a class="notice-developers right" href="{@docRoot}training/material/index.html"> <div> - <h3>デベロッパー文書</h3> - <p>マテリアル デザインを使ったアプリの作成</p> + <h3>デベロッパー ドキュメント</h3> + <p>マテリアル デザインを使用したアプリの作成</p> </div> </a> @@ -25,7 +24,7 @@ page.image=design/material/images/MaterialLight.png <a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> <div> <h3>ビデオ</h3> - <p>紙とインク:重要なマテリアル</p> + <p>紙とインク: 重要なマテリアル</p> </div> </a> @@ -39,27 +38,27 @@ page.image=design/material/images/MaterialLight.png -<p itemprop="description">マテリアル デザインは、視覚や動作と、複数のプラットフォームや端末間でのインタラクション デザインに関する包括的な指針です。 +<p itemprop="description">マテリアル デザインは、複数のプラットフォームや端末の視覚、モーション、インタラクション デザインの包括的な指針です。 Android はマテリアル デザイン アプリに対応するようになりました。 -Android アプリでマテリアル デザインを使うには、<a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a>で説明されているガイドラインに従い、Android 5.0(API レベル 21)以降の新しいコンポーネントや機能を使用します。 +Android アプリでマテリアル デザインを使うには、<a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a>で定義されているガイドラインに従い、Android 5.0(API レベル 21)以降の新しいコンポーネントや機能を使用します。 </p> -<p>Android にはマテリアル デザインの作成に使うことができる次の要素が用意されています。</p> +<p>Android にはマテリアル デザインのアプリのビルドに使用できる次の要素が用意されています。</p> <ul> <li>新しいテーマ</li> - <li>複雑なビュー用の新しいウィジェット</li> + <li>複雑なビューに対応した新しいウィジェット</li> <li>カスタムのシャドウとアニメーション用の新しい API</li> </ul> -<p>Android でのマテリアル デザインの実装については、<a href="{@docRoot}training/material/index.html">マテリアル デザインを使ったアプリの作成</a>をご覧ください。 +<p>Android でのマテリアル デザインの実装については、<a href="{@docRoot}training/material/index.html">マテリアル デザインを使用したアプリの作成</a>をご覧ください。 </p> <h3>マテリアル テーマ</h3> -<p>マテリアル テーマはアプリの新しいスタイルである、システム ウィジェットを提供します。システム ウィジェットを使ってカラーパレット、タッチ フィードバックやアクティビティ遷移のためのデフォルトのアニメーションを指定できます。 +<p>マテリアル テーマには、アプリの新しいスタイルであるシステム ウィジェットがあります。このシステム ウィジェットを使うと、システム ウィジェットのカラーパレットを設定したり、タッチ フィードバックやアクティビティ遷移のためのデフォルトのアニメーションを設定したりできます。 </p> <!-- two columns --> @@ -67,13 +66,13 @@ Android アプリでマテリアル デザインを使うには、<a href="http: <div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">暗色マテリアル テーマ</p> + <p style="margin-top:8px">暗い色のマテリアル テーマ</p> </div> </div> <div style="float:left;width:250px;margin-right:0px;"> <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">明色マテリアル テーマ</p> + <p style="margin-top:8px">明るい色のマテリアル テーマ</p> </div> </div> <br style="clear:left"/> @@ -85,19 +84,19 @@ Android アプリでマテリアル デザインを使うには、<a href="http: <h3>リストとカード</h3> -<p>Android はマテリアル デザインのスタイルとアニメーションを含むカードとリストを表示する新しい 2 つのウィジェットを提供しています。 +<p>Android はマテリアル デザインのスタイルとアニメーションを含むカードとリストを表示する、次のような新しい 2 つのウィジェットを提供しています。 </p> <!-- two columns --> <div style="width:700px;margin-top:25px;margin-bottom:20px"> <div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p><code>RecyclerView</code> ウィジェットは <code>ListView</code> のさらに柔軟なバージョンで、さまざまなレイアウト タイプをサポートしてパフォーマンスを向上します。 -</p> + <p>新しい <code>RecyclerView</code> ウィジェットは <code>ListView</code> + に比べてさらに柔軟に機能を追加できるようになっており、さまざまなレイアウト タイプをサポートしてパフォーマンスを向上させます。</p> </div> <div style="float:left;width:250px;margin-right:0px;"> <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>新しい <code>CardView</code> ウィジェットでは、外観や使用感が一貫しているカード内に重要な情報を表示できます。 + <p>新しい <code>CardView</code> ウィジェットではカードの外観や操作性が統一され、カード内の重要な情報を表示できるようになりました。 </p> </div> <br style="clear:left"/> @@ -109,12 +108,12 @@ Android アプリでマテリアル デザインを使うには、<a href="http: <h3>シャドウの表示</h3> -<p>X と Y プロパティに加え、Android のビューに Z プロパティが追加されました。 -この新しいプロパティはビューのエレベーションを表し、次を指定します。</p> +<p>Android のビューに、X と Y のプロパティに加えて Z プロパティが追加されました。 +この新しいプロパティはビューのエレベーションを表し、次の要素を指定します。</p> <ul> -<li>シャドウのサイズ: Z 値が高いビューほどキャストするシャドウのサイズが大きくなります。</li> -<li>表示される順序: Z 値が高いビューほど他のビューより上位に表示されます。</li> +<li>シャドウのサイズ: ビューの Z 値が高いほどシャドウのサイズが大きくなります。</li> +<li>描画順序: ビューの Z 値が高いほど他のビューの前面に表示されます。</li> </ul> <div style="width:290px;margin-left:35px;float:right"> @@ -136,33 +135,33 @@ Android アプリでマテリアル デザインを使うには、<a href="http: <h3>アニメーション</h3> -<p>新しいアニメーション API を使って UI コントロールのタッチ フィードバック、ビューの状態遷移、アクティビティ遷移のカスタム アニメーションを作成できます。 +<p>新しいアニメーション API を使って、UI コントロールのタッチ フィードバック、ビューの状態変化、アクティビティ間の遷移時のカスタム アニメーションを作成できます。 </p> -<p>これらの API で次の操作を実行できます。</p> +<p>この API で次のようなことができます。</p> <ul> <li style="margin-bottom:15px"> -<strong>タッチ フィードバック</strong> アニメーションを使ってビューのタップイベントに応答します。 +<strong>タッチ フィードバック</strong> アニメーションでビューのタップ イベントに応答する。 </li> <li style="margin-bottom:15px"> -<strong>円形状の出現</strong>アニメーションを使ってビューを表示 / 非表示にします。 +<strong>円形状の出現</strong>アニメーションを使ってビューを表示したり、非表示にしたりする。 </li> <li style="margin-bottom:15px"> -カスタムの<strong>アクティビティ遷移</strong>アニメーションを使ってアクティビティを切り替えます。 +カスタムの<strong>アクティビティ遷移</strong>アニメーションを使ってアクティビティを切り替える。 </li> <li style="margin-bottom:15px"> -<strong>曲線モーション</strong>を使ってより自然なアニメーションを作成します。 +<strong>曲線モーション</strong>を使ってより自然なアニメーションを作成する。 </li> <li style="margin-bottom:15px"> -<strong>ビューの状態遷移</strong>アニメーションを使って 1 つ以上のビュー プロパティの遷移を表現します。 +<strong>ビューの状態変化</strong>アニメーションを使って 1 つ以上のビュー プロパティを変化させるアニメーションを作成する。 </li> <li style="margin-bottom:15px"> -ビューの状態遷移間のアニメーションを<strong>状態リスト ドローアブル</strong>で表示します。 +ビューの状態を変化させるアニメーションを<strong>状態リスト ドローアブル</strong>で表示します。 </li> </ul> -<p>タッチ フィードバック アニメーションはボタンなどの複数の標準ビューに組み込まれます。新しい API を使ってこれらのアニメーションをカスタマイズし、それらをカスタム ビューに追加できます。 +<p>タッチ フィードバック アニメーションはボタンなどの複数の標準ビューに組み込まれています。新しい API を使うと、これらのアニメーションをカスタマイズして、カスタム ビューに追加できます。 </p> <p>詳細については、<a href="{@docRoot}training/material/animations.html">カスタム アニメーションの定義</a>をご覧ください。 @@ -171,12 +170,12 @@ Android アプリでマテリアル デザインを使うには、<a href="http: <h3>ドローアブル</h3> -<p>次の新しいドローアブル機能を使ってマテリアル デザイン アプリを実装できます。</p> +<p>次の新しいドローアブル機能を使用してマテリアル デザイン アプリを実装できます。</p> <ul> -<li><strong>ベクター型ドローアブル</strong>は鮮明度を失わずに拡張でき、単色のアプリ内アイコンに最適です。 +<li><strong>ベクター型ドローアブル</strong>は定義を失わずにスケールできるので、単色のアプリ アイコンに最適です。 </li> -<li><strong>ドローアブルによる着色</strong>を使ってビットマップをアルファマスクとして定義し、実行時にそれらのビットマップに色付けすることができます。 +<li><strong>ドローアブルによる着色</strong>を使ってビットマップをアルファ マスクとして定義し、実行時にそのビットマップに色付けできます。 </li> <li><strong>色の抽出</strong>を使ってビットマップ画像から代表色を自動的に抽出できます。 </li> diff --git a/docs/html-intl/intl/ja/design/patterns/compatibility.jd b/docs/html-intl/intl/ja/design/patterns/compatibility.jd new file mode 100644 index 000000000000..c035a15a3630 --- /dev/null +++ b/docs/html-intl/intl/ja/design/patterns/compatibility.jd @@ -0,0 +1,70 @@ +page.title=下方互換性 +page.tags="support" +page.metaDescription=Android 4.x がバージョンの古いハードウェアや OS 向けにデザインされた UI にどのように対応するかについての注意事項。 +@jd:body + +<a class="notice-developers" href="{@docRoot}training/basics/supporting-devices/index.html"> + <div> + <h3>デベロッパー ドキュメント</h3> + <p>異なる端末のサポート</p> + </div> +</a> + +<p>Android 3.0 での大きな変更点には、以下のような点があります。</p> +<ul> +<li>仮想コントロール(Back、Home、Recents)のナビゲーション処理の導入によるナビゲーション ハードウェア キー(Back、Menu、Search、Home)の廃止 +</li> +<li>アクションバーでメニュー項目を使用する際の表現パターンの強化</li> +</ul> +<p>Android 4.0 では、こういったタブレット向けの変更点が携帯端末プラットフォームにも導入されました。</p> + +<h2 id="older-hardware">古いハードウェアやアプリへの Android 4.0 の対応</h2> + +<div class="cols"> + <div class="col-6"> + +<h4>仮想ナビゲーション コントロールのある携帯端末</h4> +<p>Android 3.0 以降をターゲットにした Android アプリは、アクションをアクションバーに表示します。アクションバーに収まらないアクションや、トップレベルに表示するほど重要ではないアクションは、アクション オーバーフローに表示されます。 + +</p> +<p>ユーザーは、アクションバーをタップすることで、アクション オーバーフローにアクセスできます。</p> + + </div> + <div class="col-7"> + + <img src="{@docRoot}design/media/compatibility_virtual_nav.png"> + + </div> +</div> + +<div class="cols"> + <div class="col-6"> + +<h4>物理ナビゲーション キーのある携帯端末</h4> +<p>従来型のナビゲーション ハードウェア キーのある Android 携帯端末では、画面下部に仮想ナビゲーション バーは表示されません。 +代わりに、メニュー ハードウェア キーからアクション オーバーフローを利用できます。そのため、ポップアップするアクションは先ほどの例と同じように利用できますが、画面の下部に表示される点が異なります。 +</p> + + </div> + <div class="col-7"> + + <img src="{@docRoot}design/media/compatibility_physical_buttons.png"> + + </div> +</div> + +<div class="cols"> + <div class="col-6"> + +<h4>仮想ナビゲーション コントロールのある携帯端末でのレガシー アプリ</h4> +<p>Android 2.3 以前をターゲットにビルドされたアプリを仮想ナビゲーション コントロールのある携帯端末で実行すると、仮想ナビゲーション バーの右側にアクション オーバーフロー コントロールが表示されます。 +コントロールをタップすると、アプリのアクションを従来型の Android メニュー形式で表示できます。 +</p> + + </div> + <div class="col-7"> + + <img src="{@docRoot}design/media/compatibility_legacy_apps.png"> + + </div> +</div> diff --git a/docs/html-intl/intl/ja/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/ja/design/patterns/confirming-acknowledging.jd index 35ba821a5cf6..c2dfb8492a8e 100644 --- a/docs/html-intl/intl/ja/design/patterns/confirming-acknowledging.jd +++ b/docs/html-intl/intl/ja/design/patterns/confirming-acknowledging.jd @@ -2,69 +2,69 @@ page.title=確認と通知 page.tags=dialog,toast,notification @jd:body -<p>状況に応じて、ユーザーがアプリでアクションを呼び出したときに、テキストを使ってそのアクションを<em>確認</em>したり<em>通知</em>したりするのは良い方法です。</p> +<p>アプリでアクションを呼び出すときに、テキストでそのアクションを<em>確認</em>または<em>通知</em>するとよい場合があります。</p> -<div class="layout-content-row"> - <div class="layout-content-col span-6"> +<div class="cols"> + <div class="col-6"> <img src="{@docRoot}design/media/confirm_ack_confirming.png"> - <p><strong>確認</strong>とは、呼び出したアクションを続けるかどうかをユーザーに確認してもらうことです。場合によって、確認は考慮する必要があるアクションに関連する警告や重要情報とともに表示されることがあります。</p> + <p><strong>確認</strong>とは、呼び出したアクションを本当に続行してもよいかどうかをユーザーにたずねることです。検討を要するアクションがあれば、それに関する警告や重要情報とともに表示されることもあります。</p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <img src="{@docRoot}design/media/confirm_ack_acknowledge.png"> - <p><strong>通知</strong>とは、呼び出したアクションが完了したことをユーザーにお知らせするテキストを表示することです。これによって、システムが実行している暗黙的な処理の不明瞭さをなくすことができます。場合によって、通知はアクションを元に戻すオプションとともに表示されることがあります。</p> + <p><strong>通知</strong>とは、呼び出したアクションが完了したことをユーザーに知らせるテキストを表示することです。システムにより実行中であり、ユーザーには表示されない操作を確認できます。アクションを元に戻すオプションとともに表示されることもあります。</p> </div> </div> -<p>このような方法でユーザーに情報を伝えると、実行された処理やこれから実行される処理についての不明瞭さを軽減できます。確認や通知によって、後悔するような間違いをするのを防ぐこともできます。</p> +<p>このような機能を使用すれば、実行済みの処理やこれから実行される処理を明確に把握できます。確認や通知を表示することで、後悔するような間違いを防ぐこともできます。</p> -<h2>ユーザーのアクションを確認または通知する場合</h2> -<p>すべてのアクションに確認または通知が必要なわけではありません。デザインを決定する際の指針として次のチャートを使用してください。</p> +<h2>ユーザーのアクションを確認または通知するタイミング</h2> +<p>すべてのアクションに確認または通知が必要なわけではありません。確認や通知が必要かどうかを判断するには、次のチャートを使用してください。</p> <img src="{@docRoot}design/media/confirm_ack_flowchart.png"> <h2>確認</h2> -<div class="layout-content-row"> - <div class="layout-content-col span-6"> +<div class="cols"> + <div class="col-6"> <h4>例: Google Play ブックス</h4> <img src="{@docRoot}design/media/confirm_ack_ex_books.png"> - <p>この例では、ユーザーが Google Play ライブラリから書籍を削除することを要求しています。その書籍が今後端末で使えなくなることを知ってもらうことが重要であるため、このアクションを確認する<a href="{@docRoot}design/building-blocks/dialogs.html#alerts">アラート</a>が表示されます。</p> - <p>確認のダイアログを作成するときは、要求されたアクションがすぐわかるようなタイトルにします。</p> + <p>この例では、ユーザーは Google Play ライブラリから書籍を削除するよう要求しています。この書籍が今後いずれの端末でも使用できなくなるということを知らせる必要があるため、このアクションを確認する<a href="{@docRoot}design/building-blocks/dialogs.html#alerts">アラート</a>が表示されます。</p> + <p>確認ダイアログは、要求されたアクションをタイトルに記述するなどして、わかりやすく作成します。</p> </div> - <div class="layout-content-col span-7"> - <h4>例: Android Beam</h4> + <div class="col-7"> + <h4>例: Android ビーム</h4> <img src="{@docRoot}design/media/confirm_ack_ex_beam.png"> - <p>確認は、必ずしも 2 つのボタンの付いたアラートで示す必要はありません。Android Beam を開始した後に、ユーザーには共有するコンテンツ(この例では写真)にタップするように求めるメッセージが表示されます。共有を続行しない場合は、電話を離すだけです。</p> + <p>確認は、必ずしも 2 つのボタンが付いたアラートで行う必要はありません。Android ビームを開始した後、共有するコンテンツ(この例では写真)をタップするようメッセージが表示されます。共有を続行しない場合は、携帯端末を離すだけです。</p> </div> </div> <h2>通知</h2> -<div class="layout-content-row"> - <div class="layout-content-col span-6"> - <h4>例: 放置した Gmail 下書きの保存</h4> +<div class="cols"> + <div class="col-6"> + <h4>例: 途中まで書いた Gmail の下書きの保存</h4> <img src="{@docRoot}design/media/confirm_ack_ex_draftsave.png"> - <p>この例では、ユーザーが Gmail 作成画面から前の画面に戻ったり、上位画面に移動したりするときに、予測しないことが起こる可能性があるため、現在の下書きが自動的に保存されます。トースト形式の通知によってその状態が明らかになります。この通知は数秒後にフェードします。</p> + <p>この例では、ユーザーが Gmail 作成画面から前の画面に戻ったり、画面の上部に移動したりすると、予測しないことが起こることもあるため、現在の下書きが自動的に保存されています。この動作はトースト形式で通知され、数秒後に消えます。</p> <p>この場合、保存操作はユーザーではなくアプリによって行われるため、元に戻す操作は適切ではありません。また、下書きのリストに移動するだけでメッセージの作成をすぐに再開できます。</p> </div> - <div class="layout-content-col span-6"> + <div class="col-6"> <h4>例: Gmail スレッドの削除</h4> <img src="{@docRoot}design/media/confirm_ack_draft_deleted.png"> - <p>ユーザーが Gmail のリストからスレッドを削除した後に、元に戻すオプションとともに通知が表示されます。ユーザーがリストのスクロールなど関連しないアクションを実行するまで通知は表示されたままになります。</p> + <p>ユーザーが Gmail のリストから会話を削除した後に、元に戻すオプションとともに認定が表示されます。リストのスクロールなど無関係なアクションをユーザーが実行するまで、通知の表示は消えません。</p> </div> </div> <h2>確認または通知を行わない場合</h2> -<div class="layout-content-row"> - <div class="layout-content-col span-6"> +<div class="cols"> + <div class="col-6"> <h4>例: +1 操作</h4> <img style="padding: 33px 0 30px;" src="{@docRoot}design/media/confirm_ack_ex_plus1.png"> - <p><strong>確認は不要</strong>。ユーザーが誤って +1 ボタンをタップしても、大きな問題にはなりません。ボタンをもう一度タップすればアクションを元に戻すことができます。</p> - <p><strong>通知は不要</strong>。+1 ボタンがバウンスし、赤に変わります。これは非常にわかりやすいシグナルです。</p> + <p><strong>確認は不要です</strong>。ユーザーが誤って [+1] ボタンをタップしても、あまり問題ではありません。ボタンをもう一度タップすれば、アクションを元に戻すことができるからです。</p> + <p><strong>通知は不要です</strong>。[+1] ボタンがバウンドして赤に変わります。これは非常にわかりやすいシグナルです。</p> </div> - <div class="layout-content-col span-7"> - <h4>例: ホームスクリーンからアプリを削除</h4> + <div class="col-7"> + <h4>例: ホームスクリーンからアプリを削除する場合</h4> <img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png"> - <p><strong>確認は不要</strong>。これは意図的なアクションです。ユーザーはアイテムを比較的大きな分離されたターゲットにドラッグ アンド ドロップする必要があります。そのため、不測の問題が発生することはほとんどありません。ユーザーがこの決定を元に戻したい場合は、ほんの数秒で元に戻すことができます。</p> - <p><strong>通知は不要</strong>。ユーザーは自分でアプリをドラッグして削除するため、アプリがホームスクリーンから消えることがわかっています。</p> + <p><strong>確認は不要です</strong>。このアクションは賢明に設計されており、ユーザーはアイテムを比較的離れたところにある大きいターゲットにドラッグ アンド ドロップする必要があります。そのため、アクシデントが発生することはほとんどありません。しかもこの操作を取り消したい場合は、ほんの数秒で元に戻すことができるようになっています。</p> + <p><strong>通知は不要です</strong>。ユーザーが自分でアプリをドラッグして削除しているので、アプリがホームスクリーンから消えるのがわかっているからです。</p> </div> </div> diff --git a/docs/html-intl/intl/ja/design/patterns/navigation.jd b/docs/html-intl/intl/ja/design/patterns/navigation.jd index dbb6b04e14e3..079ad2511f53 100644 --- a/docs/html-intl/intl/ja/design/patterns/navigation.jd +++ b/docs/html-intl/intl/ja/design/patterns/navigation.jd @@ -1,213 +1,213 @@ -page.title=Back と Up を使用したナビゲーション +page.title=Back ボタンと Up ボタンを使用したナビゲーション page.tags="navigation","activity","task","up navigation","back navigation" page.image=/design/media/navigation_between_siblings_gmail.png @jd:body <a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html"> <div> - <h3>デベロッパー文書</h3> - <p>効果的なナビゲーションを実装する</p> + <h3>デベロッパー ドキュメント</h3> + <p>効果的なナビゲーションの実装</p> </div> </a> -<p itemprop="description">一貫したナビゲーションは全体的なユーザーの操作性を向上するために欠かせない重要な要素です。一貫性がなく予測できない動作ほどユーザーにとって不快なものはありません。 -Android 3.0 では、全体的なナビゲーション動作が大きく変更されました。 -注意深く Back と Up のガイドラインに従うことで、アプリのナビゲーションをユーザーにとって予測可能で信頼できるものにすることができます。 +<p itemprop="description">使いやすいアプリでは、ナビゲーションに統一性があります。統一性がなく、動作の読めないアプリほど使いにくいものはありません。 +Android 3.0 では、全体的なナビゲーション動作が大きく変わりました。 +Back ボタンと Up ボタンのガイドラインに従えば、ユーザーにとってわかりやすく、信頼できるナビゲーションを実装できます。 </p> -<p>Android 2.3 以前のアプリ内でのナビゲーションはシステムの <em>Back</em> ボタンを使って行われてきました。Android 3.0 よりアクションバーが導入され、第 2 のナビゲーション メカニズムとして <em>Up</em> ボタンが登場しました。このボタンはアプリアイコンと左向きのキャラットで構成されています。 - +<p>Android 2.3 以前のアプリのナビゲーションはシステムの <em>Back</em> ボタンで行っていました。 +Android 3.0 よりアクションバーが導入され、第 2 のナビゲーション メカニズムとして <em>Up</em> ボタンが登場しました。このボタンはアプリアイコンと左向きのキャレットで表されています。 </p> <img src="{@docRoot}design/media/navigation_with_back_and_up.png"> -<h2 id="up-vs-back">Up と Back</h2> +<h2 id="up-vs-back">Up ボタンと Back ボタンの違い</h2> <p>Up ボタンは、画面間の階層関係に基づいてアプリ内を移動するために使います。 -たとえば、画面 A がアイテムのリストを表示し、アイテムを選択すると(そのアイテムの詳細を表示する)画面 B に移動する場合、画面 B には画面 A に戻るための Up ボタンを用意する必要があります。 +たとえば、画面 A でアイテムのリストを表示し、アイテムを選択すると(そのアイテムの詳細を表示する)画面 B に移動する場合、画面 B には画面 A に戻るための Up ボタンが必要です。 </p> -<p>画面がアプリの最上位(つまり、アプリのホーム)であれば、Up ボタンを表示すべきではありません。 +<p>画面がアプリのトップ レベル(アプリのホーム)であれば、Up ボタンを表示する必要はありません。 </p> -<p>システムの Back ボタンはユーザーが最近使用した画面を、さかのぼって順番に移動する場合に使用されます。 -通常このナビゲーションはアプリの階層ではなく、画面を表示した順番に基づいています。 +<p>システムの Back ボタンは、最近使用した画面をさかのぼって順番に移動する場合に使用します。 +通常、このナビゲーションはアプリの階層ではなく、画面を表示した順番に基づいています。 </p> -<p>前に表示していた画面が現在の画面の親階層となる場合は、Back ボタンを押すとUp ボタンを押したときと同じ結果になります — これはよくある動作です。 +<p>前に表示していた画面が現在の画面の親階層となる場合は、Back ボタンを押すと Up ボタンを押したときと同じ結果になります — これは一般的な動作です。 -ただし、Up ボタンではユーザーが確実にアプリ内に留まるのに対して、Back ボタンを使えばホームスクリーンに、さらには別のアプリに戻ることさえできます。 +ただし、Up ボタンではユーザーの移動がアプリ内に限られるのに対して、Back ボタンではホーム画面や、別のアプリにも戻れます。 </p> <img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png"> -<p>Back ボタンは、画面間を直接ナビゲーションするだけでなく、次のような動作もサポートします。 +<p>Back ボタンは、画面間を直接ナビゲーションするだけでなく、次のような動作にも対応しています。 </p> <ul> <li>フローティング ウィンドウ(ダイアログ、ポップアップ)を閉じる</li> <li>コンテキスト アクションバーを閉じて、選択したアイテムのハイライト表示を解除する</li> -<li>オンスクリーン キーボード(IME)を非表示にする</li> +<li>画面上のキーボード(IME)を非表示にする</li> </ul> <h2 id="within-app">アプリ内でのナビゲーション</h2> -<h4>複数のエントリ ポイントのある画面のナビゲーション</h4> -<p>画面にアプリ階層内の正確な位置がなく、アプリ内の他のどの画面からでもアクセスできる設定画面などのように複数のエントリ ポイントからアクセスできる場合があります。この場合、Up ボタンは参照元の画面に戻ることを選択する必要があります。これは Back も同様です。 -— +<h4>エントリ ポイントが複数ある画面へのナビゲート</h4> +<p>設定画面のように、アプリ内の他のどの画面からでもアクセスでき、アプリ階層内に定位置がなく、複数のエントリ ポイントからアクセスできる画面もあります。 +この場合、Up ボタンは Back ボタンと同じように元の画面に戻ります。 </p> -<h4>画面内でビューを変更する</h4> -<p>画面のビュー オプションを変更しても Up と Back の動作は変わりません。画面はアプリの階層内の同じ位置に留まり、新しいナビゲーション履歴は作成されません。 +<h4>画面内でのビューの変更</h4> +<p>画面のビュー オプションを変更しても Up ボタンと Back ボタンの動作は変わりません。画面はアプリの階層内の同じ位置にあり、新しいナビゲーション履歴は作成されません。 </p> <p>このようなビューの変更には次のようなものがあります。</p> <ul> -<li>タブや左右のスワイプを使ってビューを切り替える</li> -<li>ドロップダウン(折りたたみタブ)を使ってビューを切り替える</li> -<li>リストにフィルタをかける</li> -<li>リストをソートする</li> -<li>表示の方法を変える(ズームなど)</li> +<li>タブや左右のスワイプを使ったビューの切り替え</li> +<li>ドロップダウン(折りたたみタブ)を使ったビューの切り替え</li> +<li>リストへのフィルタの適用</li> +<li>リストの並び替え</li> +<li>表示方法の変更(ズームなど)</li> </ul> <h4>兄弟画面間のナビゲーション</h4> -<p>アプリでアイテムのリストから 1 つのアイテム詳細画面に移動するとき、そのアイテムからリスト内の前後にある別のアイテムへのナビゲーションをサポートするのが望ましいことがよくあります。 +<p>アプリでアイテムのリストから選択して、あるアイテムの詳細画面に移動するとき、そのアイテムからリストの前後にある別のアイテムにナビゲーションできるようにすると使いやすくなる場合があります。 -たとえば、Gmail では、スワイプすることで、ある会話から同じ受信トレイの新しいまたは古い会話へ左右に簡単に移動できます。 -画面内でビューを変更する場合と同じように、このようなナビゲーションによって Up または Back の動作は変わりません。 +たとえば、Gmail で左か右にスワイプすると、同じ受信トレイのある会話から新しい会話や古い会話に簡単に移動できます。 +画面内でビューを変更する場合と同様に、このナビゲーションでも Up ボタンまたは Back ボタンの動作は変わりません。 </p> <img src="{@docRoot}design/media/navigation_between_siblings_gmail.png"> -<p>しかし、参照リストで結び付けられていない関連詳細ビュー間をブラウジングする場合 — たとえば Play ストアで同じデベロッパーのアプリや同じアーティストのアルバム間をブラウジング場合、その動作はこれとは明らかに異なります。 +<p>ただし、参照リストで結び付けられていない関連詳細ビュー間をブラウジングする場合は例外です。たとえば Play Store で同じデベロッパーのアプリや同じアーティストのアルバム間をブラウジングする場合です。 この場合、各リンクをたどると履歴が作成され、Back ボタンで以前に表示した各画面に戻ることになります。 -Up では常にこれらの関連画面をバイパスして、直前に表示したコンテナ画面に移動します。 +Up ボタンを使用するとこれらの関連画面をバイパスして、直前に表示したコンテナ画面に移動します。 </p> <img src="{@docRoot}design/media/navigation_between_siblings_market1.png"> -<p>Up の動作を詳細ビューの知識に基づいてより使いやすくすることができます。 -前述の Play ストアの例で、ユーザーが直前に表示した書籍から映画版の詳細に移動したとします。 -その場合、Up でユーザーが前に表示していないコンテナ(映画)に戻ることができます。 +<p>詳細ビューを応用すれば、Up ボタンを使いやすくできます。 +前述の Play Store の例で、直前に表示した書籍から映画版の詳細に移動したとします。 +その場合、Up ボタンを使用すると前に表示していないコンテナ(映画)に戻ることができます。 </p> <img src="{@docRoot}design/media/navigation_between_siblings_market2.png"> -<h2 id="into-your-app">ホームスクリーンのウィジェットと通知によるアプリへのナビゲーション</h2> +<h2 id="into-your-app">ホーム画面のウィジェットと通知を使用したアプリへのナビゲーション</h2> -<p>ホームスクリーンのウィジェットや通知を使ってユーザーがアプリ階層内の深い階層にある画面に直接移動できるようにします。 -たとえば、Gmail の受信ボックスのウィジェットと新しいメッセージ通知はどちらも受信トレイ画面をバイパスし、会話ビューを直接表示できます。 +<p>ホーム画面のウィジェットや通知を使用して、アプリの深い階層にある画面に直接移動できるようにします。 +たとえば、Gmail の受信トレイのウィジェットと新しいメッセージ通知をタップすると、どちらも受信トレイ画面をバイパスし、会話ビューを直接表示できます。 </p> <p>この両方の機能で、Up ボタンを次のように処理します。</p> <ul> -<li><em>通常アプリ内の特定の画面から移動先画面に移動する場合</em>、Up でその画面に移動します。 +<li><em>通常どおりにアプリの特定の画面から移動先画面に移動する場合</em>、Up ボタンを使用するとその画面に移動します。 </li> -<li><em>それ以外の場合は</em>、Up でアプリの最上位(「ホーム」)画面に移動します。</li> +<li><em>それ以外の場合は</em>、Up ボタンを使用するとアプリのトップレベル([ホーム])の画面に移動します。</li> </ul> -<p>Back ボタンの場合は、アプリの最上位画面への完全な上向きナビゲーション パスをタスクのバックスタックに挿入してナビゲーションをより予測可能なものにする必要があります。 -この設定によって、アプリにどのように入ったか忘れたユーザーは、終了前のアプリの最上位画面に移動できます。 +<p>Back ボタンの場合は、アプリのトップ レベルの画面に直接ナビゲートできるパスをタスクのバック スタックに挿入して、わかりやすいナビゲーションにします。 +こうすることで、アプリをどのように起動したか覚えていなくても、トップ レベルの画面に移動してから終了できます。 </p> -<p>たとえば Gmail のホームスクリーンのウィジェットには、その作成画面に直接移動するボタンがあります。 -作成画面の Up または Back で受信トレイが表示され、そこから Back ボタンでホームに移動します。 +<p>たとえば Gmail のホーム画面のウィジェットには、作成画面に直接移動するボタンがあります。 +作成画面の Up ボタンまたは Back ボタンで受信トレイが表示され、そこから Back ボタンでホームに移動します。 </p> <img src="{@docRoot}design/media/navigation_from_outside_back.png"> <h4>間接通知</h4> -<p>アプリで複数のイベントに関する情報を同時に表示する必要がある場合、1 つの通知を使ってユーザーをインタースティシャル画面に導くことができます。 -この画面にはこれらのイベントがまとめてあり、アプリのさらに深い階層に移動するためのパスが示されます。このスタイルの通知を<em>間接通知</em>と呼びます。 - +<p>アプリで複数のイベントに関する情報を同時に表示する必要がある場合、通知を 1 つにまとめてそこからインタースティシャル画面に遷移させることができます。 +この画面にはこれらのイベントの要約が表示されており、アプリのさらに深い階層に移動するパスが示されます。 +このスタイルの通知を<em>間接通知</em>と呼びます。 </p> -<p>標準(直接)通知とは異なり、間接通知のインタースティシャル画面から Back を押すとユーザーは通知がトリガーされた地点に戻ります — バックスタックには追加の画面は挿入されません。 +<p>標準(直接)通知とは異なり、間接通知のインタースティシャル画面で Back ボタンを押すと、通知がトリガーされた画面に戻ります。バックスタックには追加の画面は挿入されません。 -ユーザーがインタースティシャル画面からアプリに移動すると、Up および Back は前述した標準通知の場合と同様に動作します。つまりインタースティシャル画面に戻るのではなくアプリ内でナビゲーションします。 +ユーザーがインタースティシャル画面からアプリに移動すると、Up ボタンと Back ボタンは前述の標準通知と同様に動作します。つまり、インタースティシャル画面に戻るのではなくアプリ内で遷移します。 </p> -<p>たとえば Gmail のユーザーがカレンダーから間接通知を受け取ったとします。この通知をタップするとインタースティシャル画面が開き、複数の異なるイベントに関するリマインダーが表示されます。 +<p>たとえば Gmail がカレンダーから間接通知を受け取ったとします。この通知をタップするとインタースティシャル画面が開き、複数の異なるイベントのリマインダーが表示されます。 -インタースティシャル画面で Back をタップすると Gmail に戻ります。特定のイベントをタップすると、インタースティシャル画面から完全なカレンダー アプリに移動し、そのイベントの詳細が表示されます。 +インタースティシャル画面で Back ボタンをタップすると Gmail に戻ります。特定のイベントをタップすると、インタースティシャル画面からカレンダー アプリに移動し、そのイベントの詳細が表示されます。 -イベントの詳細から、Up および Back を使うとカレンダーの最上位ビューが表示されます。</p> +イベントの詳細画面で Up ボタンや Back ボタンを使うと、カレンダーのトップ ビューに移動します。</p> <img src="{@docRoot}design/media/navigation_indirect_notification.png"> <h4>ポップアップ通知</h4> -<p><em>ポップアップ通知</em>は通知ドロワーをバイパスしてユーザーの前に直接表示されます。 -ポップアップ通知はめったに使われません。<strong>タイムリーな応答が要求され、ユーザーのコンテキストの中断が必要な場合に使われます</strong>。 -たとえばトークでは、このスタイルを使って友人からのビデオチャットへの参加に関する招待状についてユーザーに通知します。というのも、この招待状は数秒後に自動的に期限切れになるからです。 +<p><em>ポップアップ通知</em>は通知ドロワーをバイパスし、直接表示される通知です。 +ポップアップ通知はほとんど使われません。<strong>タイムリーな応答が要求され、ユーザーの操作の中断が必要な場合にのみ使うべきです</strong>。 +たとえばトークでは、友人からのビデオチャットへの招待が数秒後に自動的に期限切れとなる場合、このスタイルを使ってユーザーに通知します。 </p> -<p>ナビゲーション動作の点から、ポップアップ通知は間接通知のインタースティシャル画面の動作に厳密に従います。 -Back でポップアップ通知は閉じます。ユーザーがポップアップから通知元のアプリに移動すると、Up と Back は標準通知のルールに従い、アプリ内でナビゲーションします。 +<p>ナビゲーションでは、間接通知のインタースティシャル画面の動作に慎重に従ってポップアップ通知を行います。 +Back ボタンでポップアップ通知を閉じます。ポップアップから通知対象のアプリに移動すると、Up ボタンと Back ボタンは標準通知のルールに従って、そのアプリ内で通常のナビゲーションを実行します。 </p> <img src="{@docRoot}design/media/navigation_popup_notification.png"> -<h2 id="between-apps">アプリ間のナビゲーション</h2> - -<p>Android システムの基本的な利点の 1 つにアプリ同士がそれぞれをアクティブにできる機能があります。これによりユーザーは特定のアプリから別のアプリへ直接移動できます。 -たとえば写真を撮影する必要があるアプリでは、カメラアプリをアクティブにすることができます。カメラアプリは写真を参照元のアプリに戻します。これはデベロッパーにとっては他のアプリのコードを簡単に利用できるという点で、またユーザーにとっては通常実行するアクションに対して一貫した操作を実行できるという点で大きなメリットです。 +<h2 id="between-apps">アプリ間ナビゲーション</h2> +<p>Android システムの基本的な利点の 1 つに、アプリが別のアプリを起動できる機能があります。これを使用すると、あるアプリから別のアプリへ直接移動できます。 +たとえば、写真をキャプチャするアプリで、カメラアプリを起動できます。カメラアプリは写真を起動元のアプリに返します。 +デベロッパーにとっては他のアプリのコードを簡単に利用できるという点で、ユーザーにとってはよく実行するアクションを常に同じ操作で実行できるという点で大きなメリットです。 </p> -<p>アプリ間のナビゲーションを理解するには、次に説明する Android フレームワークの動作を理解することが重要です。 +<p>アプリ間ナビゲーションを理解するには、次に説明する Android フレームワークの動作を理解する必要があります。 </p> <h4>アクティビティ、タスク、インテント</h4> -<p>Android における<strong>アクティビティ</strong>とは情報の画面と、ユーザーが実行できるすべての関連アクションを定義するアプリケーション コンポーネントです。 -アプリはアクティビティのコレクションで、作成したアクティビティと他のアプリから再利用するアクティビティの両方で構成されています。 +<p>Android における<strong>アクティビティ</strong>とは、情報を表示する画面と、実行できるすべての関連アクションを定義するアプリケーション コンポーネントのことです。 +アプリはアクティビティの集まりで構成され、作成したアクティビティと他のアプリから再利用するアクティビティで構成されています。 </p> -<p><strong>タスク</strong>とは目標を実現するためにユーザーが従う一連のアクティビティです。1 つのタスクで 1 つのアプリだけのアクティビティを利用することも、複数のアプリのアクティビティを利用することもできます。 +<p><strong>タスク</strong>とは目的の動作を遂行するために実行する、一連のアクティビティのことです。1 つのタスクで 1 つのアプリだけのアクティビティを利用することも、複数のアプリのアクティビティを利用することもできます。 </p> -<p><strong>インテント</strong>とは、あるアプリがアクションの実行に関して別のアプリのサポートが必要であることを示すメカニズムです。 -アプリのアクティビティでそれらのアプリが対応できるインテントを示すことができます。 -「共有」などの一般的なインテントの場合、ユーザーはその要求を実現できる多くのアプリをインストールしている場合があります。 +<p><strong>インテント</strong>とは、アプリがあるアクションを実行するために、別のアプリにアシストを要求するためのシグナルを出すメカニズムです。 +アプリのアクティビティは、どのようなインテントに応答できるか決めることができます。 +「共有」などの一般的なインテントの場合、その要求に対応できるアプリが複数インストールされていることもあります。 </p> -<h4>例: 共有をサポートするアプリ間のナビゲーション</h4> - -<p>アクティビティ、タスク、インテントの連携を理解するには、1 つのアプリが別のアプリを使ってユーザーによるコンテンツの共有を可能にする仕組みを知る必要があります。たとえばホームから Play ストアのアプリを起動すると、新しいタスク A が開始されるとします(以下の図を参照)。 +<h4>例: アプリ間をナビゲートして共有をサポートする</h4> -Play ストア内をナビゲートし、プロンプトで表示された書籍をタップしてその詳細を表示した後もユーザーは同じタスク内に留まり、アクティビティを追加するとタスクは拡張されます。 -「共有」アクションをトリガーすると、共有インテントを処理するよう登録されている(さまざまなアプリの)各アクティビティを示すダイアログがユーザー表示されます。 +<p>アクティビティ、タスク、インテントの連携を理解するには、あるアプリが別のアプリを使ってコンテンツを共有する仕組みについて理解する必要があります。 +たとえば、ホームから Play Store のアプリを起動すると、新しいタスク A が開始されるとします(以下の図を参照)。 +Play Store 内をナビゲートし、おすすめの書籍をタップしてその詳細を表示した後もユーザーは同じタスク内に留まり、アクティビティを追加するとタスクが拡張されます。 +「共有」アクションをトリガーすると、共有インテントを処理するよう登録されている(さまざまなアプリの)各アクティビティを一覧表示するダイアログが表示されます。 </p> <img src="{@docRoot}design/media/navigation_between_apps_inward.png"> -<p>ユーザーが Gmail 経由で共有することを選択すると、Gmail の作成アクティビティがタスク A の続きとして追加されます — 新しいタスクは作成されません。 -Gmail にバックグラウンドで実行中の独自のタスクがある場合、そのタスクは影響を受けません。 +<p>Gmail で共有するよう選択すると、Gmail の作成アクティビティがタスク A の続きとして追加され、新しいタスクは作成されません。 +Gmail にバックグラウンドで実行中のタスクがある場合、そのタスクは影響を受けません。 </p> -<p>作成アクティビティからメッセージを送信するか、Back ボタンをタップするとユーザーは書籍の詳細アクティビティに戻ります。 -Back を連続してタップすると Play ストアに戻り、最終的にはホームが表示されます。 +<p>作成アクティビティからメッセージを送信するか、Back ボタンをタップすると書籍の詳細アクティビティに戻ります。 +Back ボタンを連続してタップすると Play Store に戻り、最後にホーム画面が表示されます。 </p> <img src="{@docRoot}design/media/navigation_between_apps_back.png"> -<p>ただし、作成アクティビティから Up をタップすると、ユーザーは Gmail 内に留まる意思を示すことになります。 -Gmail の会話リストのアクティビティが表示され、新しいタスク B が作成されます。新しいタスクは常にホームをルートとしているため、会話リストからBack をタップするとホームに戻ります。 +<p>ただし、作成アクティビティで Up ボタンをタップすると、Gmail で引き続き作業することになります。 +Gmail の会話リストのアクティビティが表示され、新しいタスク B が作成されます。新しいタスクでは常にホーム画面がルートになるため、会話リストから Back ボタンをタップするとホーム画面に戻ります。 </p> <img src="{@docRoot}design/media/navigation_between_apps_up.png"> -<p>タスク A はバックグラウンドで維持され、ユーザー後から(たとえば [最近使ったアプリ] 画面経由で)このタスクに戻ることができます。 -Gmail にバックグラウンドで実行中の独自のタスクが既にある場合、そのタスクはタスク B に置き換えられます — 前のコンテキストはユーザーの新しい目標の導入より破棄されます。 +<p>タスク A はバックグラウンドで待機しているので、後から(たとえば [最近使ったアプリ] 画面から)このタスクに戻ることができます。 +Gmail にバックグラウンドで実行中のタスクが既にある場合、そのタスクはタスク B に置き換えられます。新しいタスクが選択され、前のコンテキストは破棄されます。 </p> -<p>アプリがアプリ階層内の深い階層にあるアクティビティでインテントを処理するように登録されている場合は、Up ナビゲーションの指定方法について<a href="#into-your-app">ホームスクリーンのウィジェットと通知によるアプリへのナビゲーション</a>をご覧ください。 +<p>深い階層にあるアクティビティでインテントを処理するようアプリで登録されている場合は、Up ナビゲーションの指定方法については、<a href="#into-your-app">ホーム画面のウィジェットと通知を使用したアプリへのナビゲーション</a>をご覧ください。 </p> diff --git a/docs/html-intl/intl/ja/distribute/index.jd b/docs/html-intl/intl/ja/distribute/index-ja.jd index 27f1cb4a839a..27f1cb4a839a 100644 --- a/docs/html-intl/intl/ja/distribute/index.jd +++ b/docs/html-intl/intl/ja/distribute/index-ja.jd diff --git a/docs/html-intl/intl/ja/guide/components/activities.jd b/docs/html-intl/intl/ja/guide/components/activities.jd new file mode 100644 index 000000000000..9b06d2c838bb --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/activities.jd @@ -0,0 +1,756 @@ +page.title=アクティビティ +page.tags=activity,intent +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> +<h2>本書の内容</h2> +<ol> + <li><a href="#Creating">アクティビティを作成する</a> + <ol> + <li><a href="#UI">ユーザー インターフェースを実装する</a></li> + <li><a href="#Declaring">マニフェストでアクティビティを宣言する</a></li> + </ol> + </li> + <li><a href="#StartingAnActivity">アクティビティを開始する</a> + <ol> + <li><a href="#StartingAnActivityForResult">結果待ちのアクティビティを開始する</a></li> + </ol> + </li> + <li><a href="#ShuttingDown">アクティビティをシャットダウンする</a></li> + <li><a href="#Lifecycle">アクティビティのライフサイクルを管理する</a> + <ol> + <li><a href="#ImplementingLifecycleCallbacks">ライフサイクル コールバックを実装する</a></li> + <li><a href="#SavingActivityState">アクティビティの状態を保存する</a></li> + <li><a href="#ConfigurationChanges">構成の変更を処理する</a></li> + <li><a href="#CoordinatingActivities">アクティビティを連携する</a></li> + </ol> + </li> +</ol> + +<h2>キークラス</h2> +<ol> + <li>{@link android.app.Activity}</li> +</ol> + +<h2>関連ドキュメント</h2> +<ol> + <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">タスクとバックスタック +</a></li> +</ol> + +</div> +</div> + + + +<p>{@link android.app.Activity} は、電話をかける、写真を撮影する、メールを送る、マップを閲覧するといった操作をユーザーができる画面を提供するアプリケーション コンポーネントです。 + +各アクティビティには、ユーザー インターフェースを描画できるウィンドウがあります。一般的にはウィンドウは画面と同じ大きさになりますが、画面より小さくしたり、他のウィンドウ上にフローティングさせたりすることもできます。 + +</p> + +<p> 通常、アプリケーションは複数のアクティビティで構成されており、各アプリケーションはそれぞれ緩やかにつながっています。 +一般的には、アプリケーションの 1 つのアクティビティが「メイン」アクティビティとして指定され、ユーザーが初めてアプリケーションを起動したときに表示されるのがこのアクティビティになります。 +その後、各アクティビティで別のアクティビティを開始して別の操作を実行できます。 +新しいアクティビティの開始時には、前のアクティビティは停止しますが、そのアクティビティはシステムによってスタック(「バックスタック」)に維持されます + +新しいアクティビティが開始すると、それがバックスタックに入ってユーザーに表示されます。 +バックスタックは「後入れ先出し」の基本的なスタック メカニズムを順守するため、ユーザーが現在のアクティビティを完了して [<em>戻る</em>] ボタンを押すと、そのアクティビティはスタックから消え(破棄され)、前のアクティビティが再開します。 + +(バックスタックの詳細については、<a href="{@docRoot}guide/components/tasks-and-back-stack.html">タスクとバックスタック</a>ドキュメントで説明します)。 + +</p> + +<p>新しいアクティビティが開始したことで、別のアクティビティが停止した場合、その状態の変化がアクティビティのライフサイクル コールバック メソッド経由で通知されます。システムがアクティビティを作成しているのか、停止しているのか、再開しているのか、破棄しているのかという状態の変化によって、アクティビティが受け取るコールバック メソッドにはいくつかの種類があり、各コールバックではユーザーがその状態の変化に応じた特定の操作を実行できます。 + + +—— + +たとえば、アクティビティが停止した場合は、ネットワーク接続やデータベース接続などの大きなオブジェクトを解放することになります。 +アクティビティが再開した場合は、必要なリソースを再度取得し、中断したところから操作を再開できます。 +このような状態の推移はすべて、アクティビティのライフサイクルの一部です。 +</p> + +<p>このドキュメントでは、さまざまなアクティビティの状態間の切り替えを正しく管理できるよう、アクティビティのライフサイクルの仕組みについてさらに詳しく説明する他、アクティビティのビルド方法と使用方法の基本について解説します。 + +</p> + + + +<h2 id="Creating">アクティビティを作成する</h2> + +<p>アクティビティを作成するには、{@link android.app.Activity} のサブクラス(またはその既存のサブクラス)を作成する必要があります。 +サブクラスでは、アクティビティのライフサイクルの状態の切り替え時(アクティビティの作成、停止、再開、破棄など)にシステムが呼び出すコールバック メソッドを実装する必要があります。 + +最も重要なコールバック メソッドは次の 2 つです。 +</p> + +<dl> + <dt>{@link android.app.Activity#onCreate onCreate()}</dt> + <dd>このメソッドは必ず実装してください。システムはアクティビティ作成の際にこのメソッドを呼び出します。 +実装の際には、アクティビティの必須コンポーネントを初期化する必要があります。 + + さらに重要な点は、ここで {@link android.app.Activity#setContentView + setContentView()} を呼び出してアクティビティのユーザー インターフェースのレイアウトを定義する必要があるということです。</dd> + <dt>{@link android.app.Activity#onPause onPause()}</dt> + <dd>システムは、ユーザーがアクティビティを終了したことを始めて示すときに、このメソッドを呼び出します(アクティビティが破棄されていない場合も含む)。 +通常はここで、現在のユーザー セッション後も維持する必要のある変更点を保存しておきます(ユーザーが戻ってこない可能性があるため)。 + +</dd> +</dl> + +<p>アクティビティ間の滑らかな操作感を実現し、アクティビティが停止したり破棄されたりする可能性のある予想外の中断に対応するために使用できるライフサイクル コールバック メソッドは他にもいくつかあります。 + +すべてのライフサイクル コールバック メソッドについては、<a href="#Lifecycle">アクティビティのライフサイクルを管理する</a>のセクションで説明します。 +</p> + + + +<h3 id="UI">ユーザー インターフェースを実装する</h3> + +<p> アクティビティのユーザー インターフェースは、ビューの階層、 {@link android.view.View} から派生したオブジェクトから提供されます。— +各ビューはアクティビティ ウィンドウ内の特定の長方形のエリアを制御し、ユーザーの操作に応答します。 +たとえば、1 つのビューが、ユーザーがタップしたときに操作を開始するボタンである場合があります。 +</p> + +<p>Android には、レイアウトのデザインや整理に使用できる既成のビューが多数用意されています。 +「ウィジェット」は、ボタン、テキスト フィールド、チェックボックス、画像といった画像の視覚的(操作可能な)要素を提供するビューです。 +「レイアウト」は、{@link +android.view.ViewGroup} から派生したビューで、線形レイアウト、グリッド レイアウト、相対レイアウトなど、子ビューの特有のレイアウト モデルを提供するものです。 +また、{@link android.view.View} クラスと {@link android.view.ViewGroup} クラス(または既存のサブクラス)のサブクラスを作成し、独自のウィジェットやレイアウトを作ってアクティビティのレイアウトに適用することもできます。 + +</p> + +<p>ビューを使用したレイアウトの定義で最も一般的なのは、XML レイアウト ファイルをアプリケーション リソースに保存する方法です。 +この方法では、ユーザー インターフェースのデザインを、アクティビティの挙動を定義するソース コードとは別に維持できます。 +{@link android.app.Activity#setContentView(int) setContentView()} を使用して、レイアウトのリソース ID を渡すと、アクティビティの UI としてレイアウトを設定できます。 + +ただし、アクティビティ コードに新しい {@link android.view.View} を作成して、{@link android.view.ViewGroup} に新しい {@link +android.view.View} を挿入してビュー階層をビルドし、ルートの {@link android.view.ViewGroup} を {@link android.app.Activity#setContentView(View) +setContentView()} に渡して、そのレイアウトを使うこともできます。 + +</p> + +<p>ユーザー インターフェースの作成の詳細については、「<a href="{@docRoot}guide/topics/ui/index.html">ユーザー インターフェース</a>」のドキュメントをご覧ください。</p> + + + +<h3 id="Declaring">マニフェストでアクティビティを宣言する</h3> + +<p>アクティビティがシステムにアクセスできるようにするには、マニフェストでアクティビティを宣言する必要があります。 +アクティビティを宣言するには、マニフェスト ファイルを開いて、<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 要素を <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> の子要素として追加します。 + +次に例を示します。</p> + +<pre> +<manifest ... > + <application ... > + <activity android:name=".ExampleActivity" /> + ... + </application ... > + ... +</manifest > +</pre> + +<p>この要素には他にも、アクティビティのラベル、アクティビティのアイコン、アクティビティの UI を決めるテーマなどのプロパティを定義する属性を含めることができます。<a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">{@code android:name}</a> 属性は、アクティビティのクラス名を指定するもので、唯一の必須属性です。 + + +—アプリケーションを発行したら、この名前は変更できません。変更すると、アプリケーションのショートカットなどの一部の機能が破損する可能性があります(ブログの投稿「<a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Things That Cannot Change</a>」をご覧ください)。 + + +</p> + +<p>マニフェストでのアクティビティの宣言に関する詳細については、<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 要素のリファレンスをご覧ください。 +</p> + + +<h4>インテント フィルタを使用する</h4> + +<p><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a> 要素でも — <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> 要素を使用してさまざまなインテント フィルタを指定して — 他のアプリケーション コンポーネントでのアクティベート方法を宣言できます。 +</p> + +<p>Android SDK ツールを使用して新しいアプリケーションを作成する際、自動的に作成されるスタブ アクティビティには、「メイン」アクションに応答するアクティビティで、「ランチャー」カテゴリに置かれるべきものを宣言するインテント フィルタが含まれます。 + +インテント フィルタは次のように表示されます。 +</p> + +<pre> +<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +</pre> + +<p><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> 要素は、これがアプリケーションへの「メイン」エントリ ポイントであることを指定します。<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> 要素は、アクティビティをシステムのアプリケーション ランチャーに入れるべきであると指定します(ユーザーがこのアクティビティを起動できるようにします)。 +</p> + +<p>アプリケーションを自己完結型にして、他のアプリケーションでアクティビティをアクティベートできないようにする場合は、他のインテント フィルタは必要ありません。 +前の例のように、「メイン」アクションを持ち、「ランチャー」カテゴリにできるのは 1 つのアクティビティのみです。 +アクティビティを他のアプリケーションで利用できないようにする場合は、そのアクティビティにはインテント フィルタを使用せず、明示的なインテントを使用して自身でアクティビティを開始するようにできます(次のセクションで説明します)。 + +</p> + +<p>ただし、他のアプリケーション(と自身のアプリケーション)から派生した暗黙的なインテントにアクティビティが応答するようにする場合は、アクティビティで追加のインテント フィルタを定義する必要があります。 + +応答するインテントのタイプごとに、<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> 要素を含む <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> と、任意で <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> 要素や <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code +<data>}</a> 要素を含める必要があります。 +これらの要素は、アクティビティが応答できるインテントのタイプを指定します。 +</p> + +<p>アクティビティがインテントに応答する方法の詳細については、「<a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a>」のドキュメントをご覧ください。 +</p> + + + +<h2 id="StartingAnActivity">アクティビティを開始する</h2> + +<p>@link android.app.Activity#startActivity + startActivity()} を呼び出して、開始するアクティビティを記述する {@link android.content.Intent} を渡すと、新しいアクティビティを開始できます。 +インテントは開始するアクティビティを正確に指定するか、実行する操作のタイプを記述します(システムが適切なアクティビティを選択しますが、それが他のアプリケーションのアクティビティである場合もあります)。 + + +また、インテントには開始したアクティビティで使用する少量のデータを含めることもできます。 +</p> + +<p>自身のアプリケーションを操作するとき、既知のアクティビティを起動することが頻繁にあります。 + そのような場合、クラス名を使用して開始するアクティビティを明示的に定義するインテントを作成できます。 +例として、1 つのアクティビティで {@code +SignInActivity} という名前の他のアクティビティを開始する方法を次に示します。</p> + +<pre> +Intent intent = new Intent(this, SignInActivity.class); +startActivity(intent); +</pre> + +<p>ただし、アクティビティからのデータを使用して、アプリケーションでメールやテキスト メッセージの送信、ステータスのアップデートといった操作を実行する場合もあります。 +アプリケーションにそのような操作を実行できるアクティビティがない場合、代わりに、端末上の他のアプリケーションによるアクティビティを活用できます。 + +ここが、インテントがその存在意義を発揮する場面です。実行する操作を記述するインテントを作成し、システムが適切なアクティビティを他のアプリケーションから起動します。 +— + +インテントを処理できるアクティビティが複数ある場合は、使用するアクティビティを 1 つユーザーが選択できます。 +たとえば、メールを送信できるようにする場合は、次のようなインテントを作成します。 + +</p> + +<pre> +Intent intent = new Intent(Intent.ACTION_SEND); +intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); +startActivity(intent); +</pre> + +<p>インテントに追加された {@link android.content.Intent#EXTRA_EMAIL} のエクストラは、メールの送信先となるメールアドレスの文字列配列です。 +メール アプリケーションがこのインテントに応答するとき、エクストラにある文字列配列を読み取り、それをメール作成フォームの「宛先」フィールドに置きます。 + +この場合、メール アプリケーションのアクティビティが開始してユーザーが操作を完了したときにアクティビティが再開します。 +</p> + + + + +<h3 id="StartingAnActivityForResult">結果待ちのアクティビティを開始する</h3> + +<p>開始するアクティビティから結果を受け取りたい場合は、{@link android.app.Activity#startActivityForResult + startActivityForResult()}({@link android.app.Activity#startActivity + startActivity()} の代わりに)を呼び出してアクティビティを開始します。 +その後のアクティビティから結果を受け取るには、 +{@link android.app.Activity#onActivityResult onActivityResult()} コールバック メソッドを実装します。 +後続のアクティビティが完了すると、{@link +android.content.Intent} の結果を {@link android.app.Activity#onActivityResult onActivityResult()} メソッドに返します。 +</p> + +<p>たとえば、連絡先を 1 つ受け取って、アクティビティでその連絡先情報を使用する場合は、 +次のようにインテントを作成して結果を処理できます。 +</p> + +<pre> +private void pickContact() { + // Create an intent to "pick" a contact, as defined by the content provider URI + Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); + startActivityForResult(intent, PICK_CONTACT_REQUEST); +} + +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // If the request went well (OK) and the request was PICK_CONTACT_REQUEST + if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { + // Perform a query to the contact's content provider for the contact's name + Cursor cursor = getContentResolver().query(data.getData(), + new String[] {Contacts.DISPLAY_NAME}, null, null, null); + if (cursor.moveToFirst()) { // True if the cursor is not empty + int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); + String name = cursor.getString(columnIndex); + // Do something with the selected contact's name... + } + } +} +</pre> + +<p>この例では、アクティビティの結果を処理するために {@link +android.app.Activity#onActivityResult onActivityResult()} メソッドで使用すべき基本ロジックを示しています。 +1 つ目の条件では、要求が成功したかどうかを確認し、成功した場合は {@code resultCode} が{@link android.app.Activity#RESULT_OK} になり、この結果への要求が応答しているかどうかが判明します。この場合、{@code requestCode} が {@link android.app.Activity#startActivityForResult +startActivityForResult()} で送信された 2 つ目のパラメータに一致しています。— +—— + +そこから、コードが {@link android.content.Intent}({@code data} パラメータ)に返されたデータを照会することでアクティビティの結果を処理します。 +</p> + +<p>ここで、{@link +android.content.ContentResolver} がコンテンツ プロバイダに対してクエリを実行し、照会されたデータを読み取れるようにする {@link android.database.Cursor} が返されます。 +詳細については、「<a href="{@docRoot}guide/topics/providers/content-providers.html">コンテンツ プロバイダ</a>」のドキュメントをご覧ください。 +</p> + +<p>インテントの使用に関する詳細については、「<a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a>」のドキュメントをご覧ください。 +</p> + + +<h2 id="ShuttingDown">アクティビティをシャットダウンする</h2> + +<p>アクティビティは、{@link android.app.Activity#finish +finish()} メソッドを呼び出すことでシャットダウンできます。また、{@link android.app.Activity#finishActivity finishActivity()} を呼び出すと以前に開始した別のアクティビティをシャットダウンすることもできます。 +</p> + +<p class="note"><strong>注:</strong> ほとんどの場合、これらのメソッドを用いてアクティビティを明示的に終了しないでください。 +後述のアクティビティのライフサイクルでも説明していますが、Android システム自体がアクティビティのライフサイクルを管理するため、アクティビティを自身で終了させる必要はありません。 + +これらのメソッドを呼び出すと、期待された操作性に影響を与えることがあるため、ユーザーが絶対にアクティビティのこのインスタンスに戻らないようにする場合にのみ使用するようにしてください。 + +</p> + + +<h2 id="Lifecycle">アクティビティのライフサイクルを管理する</h2> + +<p>コールバック メソッドを実装したアクティビティのライフサイクルの管理は、強固で柔軟なアプリケーションの開発にとって重要です。 + +アクティビティのライフサイクルは、他のアクティビティ、タスク、バックスタックとの関連による影響を直接受けます。 +</p> + +<p>基本的に、アクティビティには次の 3 つの状態があります。</p> + +<dl> + <dt><i>再開状態</i></dt> + <dd>アクティビティが画面のフォアグラウンドにあり、ユーザー フォーカスのある状態。(この状態は「実行中」とも呼ばれます)。 +</dd> + + <dt><i>一時停止状態</i></dt> + <dd>他のアクティビティがフォアグラウンドにあり、メインに表示されているが、このアクティビティも表示されている。つまり、このアクティビティの上に他のアクティビティが表示されており、他方のアクティビティは一部が透明であるか、画面全体を覆ってはいない状態です。 + +一時停止状態のアクティビティは完全に生きている状態ですが({@link android.app.Activity} オブジェクトがメモリに保持されており、すべての状態やメンバー情報が維持され、ウィンドウ マネージャーにもアタッチされたまま)、メモリ量が極端に低下した場合にはシステムによって強制停止される場合もあります。 + +</dd> + + <dt><i>停止状態</i></dt> + <dd>アクティビティは、他のアクティビティによって完全に見えない状態です(アクティビティが「バックグラウンド」にある)。 +停止状態のアクティビティもまだ生きていますが({@link android.app.Activity} オブジェクトがメモリに保持されており、すべての状態やメンバー情報が維持されているが、ウィンドウ マネージャーにはアタッチ<em>されていない</em>状態です)。 + +ただし、ユーザーには表示されておらず、別の場所でメモリが必要になればシステムによって強制終了される場合もあります。 +</dd> +</dl> + +<p>アクティビティが一時停止か停止状態の場合、システムはアクティビティに終了するかどうかを尋ねる({@link android.app.Activity#finish finish()} メソッドを呼び出す)か、単純にプロセスを強制終了してメモリから解放できます。 + +アクティビティを再度開くとき(終了や強制終了後)は、もう一度最初から作成する必要があります。 +</p> + + + +<h3 id="ImplementingLifecycleCallbacks">ライフサイクル コールバックを実装する</h3> + +<p>アクティビティが上記の異なる状態の間を遷移するとき、さまざまなコールバック メソッドを介して通知されます。 +すべてのコールバック メソッドは、アクティビティの状態が変化したときに必要な操作を実行するようオーバーライドできるフックになります。 +次のスケルトン アクティビティには、基本的なライフサイクル メソッドがそれぞれ含まれています。 +</p> + + +<pre> +public class ExampleActivity extends Activity { + @Override + public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // The activity is being created. + } + @Override + protected void {@link android.app.Activity#onStart onStart()} { + super.onStart(); + // The activity is about to become visible. + } + @Override + protected void {@link android.app.Activity#onResume onResume()} { + super.onResume(); + // The activity has become visible (it is now "resumed"). + } + @Override + protected void {@link android.app.Activity#onPause onPause()} { + super.onPause(); + // Another activity is taking focus (this activity is about to be "paused"). + } + @Override + protected void {@link android.app.Activity#onStop onStop()} { + super.onStop(); + // The activity is no longer visible (it is now "stopped") + } + @Override + protected void {@link android.app.Activity#onDestroy onDestroy()} { + super.onDestroy(); + // The activity is about to be destroyed. + } +} +</pre> + +<p class="note"><strong>注:</strong> これらのライフサイクル メソッドを実装する際は、上記の例のように、すべての操作の前にスーパークラスの実装を呼び出す必要があります。 +</p> + +<p>これらのメソッドすべてで、アクティビティのライフサイクル全体を定義します。これらのメソッドを実装すると、アクティビティのライフサイクル内の次の 3 つのネストされたループを監視できます。 + </p> + +<ul> +<li>アクティビティの<b> entire lifetime</b> は、{@link +android.app.Activity#onCreate onCreate()} の呼び出しから、{@link +android.app.Activity#onDestroy} の呼び出しまでの間です。アクティビティは、{@link android.app.Activity#onCreate onCreate()} で「グローバル」状態のセットアップ(レイアウトの定義など)を実行し、{@link android.app.Activity#onDestroy} に残っているすべてのリソースを解放する必要があります。 + +たとえば、アクティビティにネットワークからデータをダウンロードするためバックグラウンドで実行しているスレッドがある場合、そのスレッドが {@link android.app.Activity#onCreate onCreate()} に作成され、{@link +android.app.Activity#onDestroy} のスレッドが停止される場合があります。 + +</li> + +<li><p>アクティビティの<b>visible lifetime</b> は、{@link +android.app.Activity#onStart onStart()} の呼び出しから、{@link +android.app.Activity#onStop onStop()} の呼び出しまでの間です。この間、アクティビティは画面上に表示され、ユーザーが操作できる状態です。 +たとえば {@link android.app.Activity#onStop onStop()} は、新たなアクティビティが開始してこのアクティビティが表示されなくなったときに呼び出されます。 +これらの 2 つのメソッド間で、アクティビティをユーザーに表示するのに必要なリソースは保持できます +たとえば、{@link android.content.BroadcastReceiver} を {@link +android.app.Activity#onStart onStart()} に登録して UI に影響のある変更を監視し、ユーザーが表示内容の閲覧をやめたときに {@link android.app.Activity#onStop onStop()} で登録解除できます + + +アクティビティがユーザーに表示されたり、非表示になったりとアクティビティの状態が変化する場合、アクティビティの entire lifetime 中にシステムが {@link android.app.Activity#onStart onStart()} と {@link +android.app.Activity#onStop onStop()} を複数回呼び出すこともあります。 +</p></li> + +<li><p>アクティビティの <b>foreground lifetime</b> は {@link +android.app.Activity#onResume onResume()} の呼び出しから、{@link android.app.Activity#onPause +onPause()} の呼び出しまでの間です。この間、アクティビティは画面上の他のすべてのアクティビティの前面にあり、ユーザーの入力フォーカスがある状態です。 +アクティビティは フォアグラウンドにある状態からそうでない状態に頻繁に遷移する可能性があります。たとえば、端末がスリープ状態になったり、ダイアログが表示されたりしたときには{@link android.app.Activity#onPause onPause()} が呼び出されます。 +— +この状態遷移は頻繁に起こるため、この 2 つのメソッドのコードはユーザーを待たせてしまうような遅い遷移にならないよう、適正な軽い処理にしておく必要があります。 +</p></li> +</ul> + +<p>図 1 では、状態間でアクティビティがたどる可能性のあるループと経路を表しています。長方形はアクティビティが状態間で遷移したときの処理用に実装できるコールバック メソッドを表しています。 + + <p> + +<img src="{@docRoot}images/activity_lifecycle.png" alt="" /> +<p class="img-caption"><strong>図 1.</strong> アクティビティのライフサイクル</p> + +<p>表 1 には同じライフサイクル コールバック メソッドがリストされており、各コールバック メソッドの詳細と、アクティビティのライフサイクル全体でのそれぞれの位置関係、コールバック メソッドの完了後にシステムによってアクティビティが強制終了されるかどうかを示しています。 + + +</p> + +<p class="table-caption"><strong>表 1.</strong> ライフサイクル コールバック メソッドの概要 +</p> + +<table border="2" width="85%" frame="hsides" rules="rows"> +<colgroup align="left" span="3"></colgroup> +<colgroup align="left"></colgroup> +<colgroup align="center"></colgroup> +<colgroup align="center"></colgroup> + +<thead> +<tr><th colspan="3">メソッド</th> <th>説明</th> <th>完了後の強制終了</th> <th>次のメソッド</th></tr> +</thead> + +<tbody> +<tr> + <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td> + <td>アクティビティが最初に作成されるときに呼び出されます。 + ここで、ビューの作成、リストとのデータバインドといった、通常の静的なセットアップを行います。— +アクティビティの前の状態を含む Bundle オブジェクトを取り出せた場合、それをメソッドに渡します(後半の<a href="#actstate">アクティビティの状態を保存する</a>をご覧ください)。 + + + + <p>常に {@code onStart()} が後に続きます。</p></td> + <td align="center">いいえ</td> + <td align="center">{@code onStart()}</td> +</tr> + +<tr> + <td rowspan="5" style="border-left: none; border-right: none;"> </td> + <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart +onRestart()}</code></td> + <td>アクティビティが停止した後、再開する直前に呼び出されます。 + + <p>常に {@code onStart()} が後に続きます。</p></td> + <td align="center">いいえ</td> + <td align="center">{@code onStart()}</td> +</tr> + +<tr> + <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td> + <td>アクティビティがユーザーに見える状態になる直前に呼び出されます。 + <p>アクティビティがフォアグラウンドになったときは {@code onResume()} が後に続き、アクティビティが非表示になったときは {@code onStop()} が後に続きます。 +</p></td> + <td align="center">いいえ</td> + <td align="center">{@code onResume()} <br/>または<br/> {@code onStop()}</td> +</tr> + +<tr> + <td rowspan="2" style="border-left: none;"> </td> + <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td> + <td>アクティビティとユーザーとの操作が開始する直前に呼び出されます。 +この時点で、アクティビティはアクティビティ スタックの先頭にあり、ユーザー入力の準備ができています。 + + <p>常に {@code onPause()} が後に続きます。</p></td> + <td align="center">いいえ</td> + <td align="center">{@code onPause()}</td> +</tr> + +<tr> + <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td> + <td>システムが別のアクティビティを再開する直前に呼び出されます。 +通常、このメソッドは永続化データへの未保存の変更をコミットしたり、アニメーションや CPU を消費する可能性のあるその他の動作を停止したりする際に使用されます。 + +それが完了するまで次のアクティビティが再開できないため、それらの操作は迅速に行う必要があります。 + + <p>アクティビティが前面に戻るときは {@code onResume()} が後に続き、アクティビティが非表示になるときは {@code onStop()} が後に続きます。 + +</td> + <td align="center"><strong style="color:#800000">はい</strong></td> + <td align="center">{@code onResume()} <br/>または<br/> {@code onStop()}</td> +</tr> + +<tr> + <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td> + <td>アクティビティがユーザーに見えなくなると呼び出されます。これは、アクティビティが破棄されたか、別のアクティビティ(既存のアクティビティや新しいアクティビティ)が再開されてこのアクティビティを覆っている場合に起こります。 + + + <p>アクティビティのユーザー操作が可能に戻るときは {@code onRestart()} が後に続き、アクティビティがなくなるときは {@code onDestroy()} が後に続きます。 + +</p></td> + <td align="center"><strong style="color:#800000">はい</strong></td> + <td align="center">{@code onRestart()} <br/>または<br/> {@code onDestroy()}</td> +</tr> + +<tr> + <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy +onDestroy()}</code></td> + <td>アクティビティが破棄される前に呼び出されます。これはアクティビティが受け取る最後の呼び出しです。 +アクティビティが終了した(<code>{@link android.app.Activity#finish + finish()}</code> が呼び出された)か、アクティビティ領域を節約するためにシステムが一時的にこのアクティビティを破棄した場合に呼び出されます。 + +この 2 つのシナリオは、<code>{@link + android.app.Activity#isFinishing isFinishing()}</code> メソッドで区別できます。 +</td> + <td align="center"><strong style="color:#800000">はい</strong></td> + <td align="center"><em>なし</em></td> +</tr> +</tbody> +</table> + +<p>「完了後の強制終了」の列は、<em>メソッドが戻った後</em>に、アクティビティのコードの後続行を実行することなく、アクティビティをホストするプロセスをシステムが強制終了できるかどうかを示しています。 + +3 つのメソッド({@link +android.app.Activity#onPause +onPause()}、{@link android.app.Activity#onStop onStop()}、{@link android.app.Activity#onDestroy +onDestroy()})が「はい」になっています。{@link android.app.Activity#onPause onPause()} は 3 つのなかで最初であるため、アクティビティが作成された後は{@link android.app.Activity#onPause onPause()} がプロセスが強制終了される<em>可能性がある</em>前に呼び出されることが保証される最後のメソッドです。システムが緊急でメモリを空ける必要がある場合は、{@link +android.app.Activity#onStop onStop()} と {@link android.app.Activity#onDestroy onDestroy()} は呼び出されない場合があります。 + +— + +そのため、重要な永続的データ(ユーザーの編集内容など)をストレージに書き込む際は、{@link android.app.Activity#onPause onPause()} を使用する必要があります。 +ただし、このメソッドで後続のアクティビティへの遷移をブロックしてしまい、ユーザー操作の速度を送らせてしまうことから、{@link android.app.Activity#onPause onPause()} 中にどんな情報を保持するかについては吟味する必要があります。 + + +</p> + +<p> <b>「強制終了」</b>列で「いいえ」となっているメソッドでは、アクティビティが呼び出された時点から、アクティビティをホストするプロセスが強制終了されないよう保護します。 +つまり、アクティビティが強制終了される可能性があるのは、{@link android.app.Activity#onPause onPause()} が戻ってから、{@link android.app.Activity#onResume onResume()} が呼び出されるまでの間です。 + +{@link android.app.Activity#onPause onPause()} が再度呼び出されて戻るまでは、再度強制終了されることはありません。 + </p> + +<p class="note"><strong>注:</strong> 表 1 の定義では技術的に「強制終了」できないアクティビティでも、システムによって強制終了されることがありますが、そうなるのはリソース不足などの緊急時のみです。 +— +アクティビティが強制終了されるケースについては、<a href="{@docRoot}guide/components/processes-and-threads.html">Processes and Threading</a> のドキュメントで説明しています。 + +</p> + + +<h3 id="SavingActivityState">アクティビティの状態を保存する</h3> + +<p><a href="#Lifecycle">アクティビティのライフサイクルを管理する</a>でも簡単に説明したように、アクティビティが一時停止や停止したとき、アクティビティの状態は保持されます。 + +これは、一時停止や停止されたときも {@link android.app.Activity} オブジェクトがメモリに保持されるためです — メンバーや現在の状態といったすべての情報は残っています。 + +つまり、アクティビティ内でユーザーが加えた変更点は保持されるため、アクティビティがフォアグラウンドに戻ったとき(「再開」したとき)、それらの変更点はそのまま表示されます。 + +</p> + +<p>ただし、メモリを確保するためにシステムがアクティビティを破棄すると、 {@link +android.app.Activity} オブジェクトが破棄されるため、システムはそれをそのままの状態で再開できなくなります。 +代わりに、ユーザーがそれに戻る操作を行った場合、システムは {@link android.app.Activity} オブジェクトを再作成します。 +ユーザーにはシステムがアクティビティを破棄して再作成したことはわからないため、アクティビティが以前の状態のままであることを期待します。 + +この場合、アクティビティの状態情報を保存できる追加のコールバック メソッド({@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()})を実装することで、アクティビティの状態に関する重要な情報を維持できます。 + +</p> + +<p>アクティビティが破棄されるような状態になる前に、システムが {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} を呼び出します。 +システムはこのメソッドを {@link android.os.Bundle} に渡し、そこでアクティビティの状態情報を名前と値のペアとして {@link +android.os.Bundle#putString putString()} や {@link +android.os.Bundle#putInt putInt()} などのメソッドを使用して保存できます。 + +その後、システムがアプリケーション プロセスを強制終了して、ユーザーがアクティビティに戻った場合、システムはアクティビティを再作成して {@link android.os.Bundle} を {@link android.app.Activity#onCreate onCreate()} と {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} の両方に渡します。 + +いずれのメソッドを使った場合でも、保存した状態を {@link android.os.Bundle} から抽出してアクティビティの状態を復元できます。 + +復元する状態情報がない場合は、{@link +android.os.Bundle} は null で渡されます(アクティビティを最初に作成した場合がこれにあたります)。 +</p> + +<img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" /> +<p class="img-caption"><strong>図 2.</strong> アクティビティが前の状態のままでユーザー フォーカスに戻るには、アクティビティが破棄され、再作成された後にアクティビティが保存された以前の状態を復元する必要があるか、アクティビティが停止し、再開した後にアクティビティの状態が以前のままになるか、の 2 つの方法があります。 + + +</p> + +<p class="note"><strong>注:</strong> アクティビティが破棄される前に {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} が呼び出される保証はありません。これは、状態を保存する必要がないケースがあるためです(ユーザーが [<em>戻る</em>] ボタンを使用してアクティビティを離れることで明示的にアクティビティを閉じた場合など)。 + + + +システムが {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} を呼び出す場合、呼び出しは常に {@link +android.app.Activity#onStop onStop()} の前、場合によっては {@link android.app.Activity#onPause +onPause()} の前に行われます。</p> + +<p>ただし、何もせず {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} も実装しない場合でも、{@link android.app.Activity} クラスの {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} のデフォルトの実装によって、アクティビティの状態が復元されるものもあります。 +具体的には、デフォルトの実装がレイアウト内のすべての {@link +android.view.View} の {@link +android.view.View#onSaveInstanceState onSaveInstanceState()} を呼び出すことで、各ビューが保存すべき情報を提供できるようになります。 + +Android フレームワークの大半のウィジェットが必要に応じてこのメソッドを実装しており、UI への視覚的な変更は自動的に保存され、アクティビティが再作成されると復元されるようになっています。 + +たとえば、{@link android.widget.EditText} ウィジェットではユーザーが入力したすべてのテキストを保存し、{@link android.widget.CheckBox} ウィジェットはオンにされたかどうかを保存するようになっています。 + +ここで必要な作業は、状態を保存する各ウィジェット用の一意の ID(<a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a>)を提供するだけです。 +ウィジェットに ID がないと、システムは状態を保存できません。 +</p> + +<div class="sidebox-wrapper"> +<div class="sidebox"> +<p>また、レイアウトのビューでの状態の保存を明示的に停止するには、{@link android.R.attr#saveEnabled android:saveEnabled} 属性を {@code "false"} に設定するか、{@link android.view.View#setSaveEnabled setSaveEnabled()} メソッドを呼び出します。 + +通常はこの機能を無効にしませんが、アクティビティ UI の状態を別の方法で復元する場合には無効にできます。 +</p> +</div> +</div> + +<p>{@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} のデフォルトの実装によってアクティビティの UI に関する有用な情報は保存されますが、追加の情報を保存するようそれをオーバーライドすることもできます。例としては、アクティビティの期間に変更されたメンバー値を保存する必要があるケースなどがあります。(UI で復元された値に関連している場合でも、それらの UI 値を持つメンバーはデフォルトでは復元されません)。 + + + +</p> + +<p>{@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} のデフォルトの実装で UI の状態を保存できるため、状態の追加情報を保存するようメソッドをオーバーライドする場合は、常に作業前に {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} のスーパークラス実装を呼び出す必要があります。 + + +同様に、オーバーライドする場合はデフォルトの実装でビューの状態を復元できるよう、{@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} のスーパークラスの実装も呼び出す必要があります。 +</p> + +<p class="note"><strong>注:</strong> {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} は呼び出される保証がないため、これはアクティビティの一時的な状態の記録用にのみ使用し、永続的データの保存には使用しないようにします。 + +—代わりに {@link +android.app.Activity#onPause onPause()} を使用して、ユーザーがアクティビティを離れたときの永続的データ(データベースに保存するインストール必要のあるデータなど)を保存します。 +</p> + +<p>アプリケーションが状態を復元できるかどうかテストするには、端末を回転してみて、方向が変化するかを確認します +画面の方向が変わるとき、システムがアクティビティを破棄して再作成し、新しい画面構成に利用可能な別のリソースを適用します。 + +アプリケーションの使用中にユーザーが端末を回転させるという場面は日常的にあるため、アクティビティが再作成されたときに状態を完全に復元することは非常に重要です。 + +</p> + + +<h3 id="ConfigurationChanges">構成の変更を処理する</h3> + +<p>端末の構成の中には、実行の際に変化するものがあります(画面の向き、キーボードの可用性、言語など)。 +そのような変化が生じたとき、Android は実行中のアクティビティを再作成します(システムが {@link android.app.Activity#onDestroy} を呼び出し、その後すぐに {@link +android.app.Activity#onCreate onCreate()})を呼び出します。 +この動作は、提供した別のリソース(異なる画面の向きやサイズに応じたレイアウトなど)を使用してアプリケーションを自動的にリロードすることで、アプリケーションを新しい構成に適応させることを目的としています。 + + +</p> + +<p>前述のように画面の向きの変化による再起動を処理して、アクティビティの状態を復元するようアプリケーションを適切にデザインしていれば、アプリケーションはアクティビティのライフサイクルでの予期しない他のイベントに対しても回復力を持つことができます。 + +</p> + +<p>このような再起動を処理するのに最適な方法は、前のセクションで説明したように、{@link + android.app.Activity#onSaveInstanceState onSaveInstanceState()} と {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}(または {@link +android.app.Activity#onCreate onCreate()})を使用してアクティビティの状態を保存、復元する方法です。 +</p> + +<p>実行の際に起こる構成の変更と、その処理方法の詳細については、「<a href="{@docRoot}guide/topics/resources/runtime-changes.html">実行時の変更の処理</a>」のガイドをご覧ください。 + +</p> + + + +<h3 id="CoordinatingActivities">アクティビティを連携する</h3> + + <p>1 つのアクティビティで別のアクティビティを開始すると、双方でライフサイクルの遷移が生じます。1 つ目のアクティビティが一時停止したり停止したりすると(バックグラウンドにある場合は停止しません)、もう一方のアクティビティが作成されます。 + +これらのアクティビティでディスクなどに保存されているデータを共有している場合は、2 つ目のアクティビティが作成される前に 1 つ目のアクティビティが完全に停止することはないということを理解しておくことが重要です。むしろ、2 つ目の開始プロセスは、1 つ目の停止プロセスにオーバーラップします。 + + +</p> + +<p>特に 2 つのアクティビティが同じプロセスにあって 1 つが別のアクティビティを開始する場合、ライフサイクル コールバックの順序は厳密に定義されています。 +アクティビティ A がアクティビティ B を開始する場合の動作の順序を次に示します。 + </p> + +<ol> +<li>アクティビティ A の {@link android.app.Activity#onPause onPause()} メソッドが実行されます。</li> + +<li>アクティビティ B の {@link android.app.Activity#onCreate onCreate()}、{@link +android.app.Activity#onStart onStart()}、{@link android.app.Activity#onResume onResume()} メソッドが順次実行されます +(このとき、ユーザー フォーカスはアクティビティ B にあります)。</li> + +<li>次に、アクティビティ A が画面から消えた場合、{@link +android.app.Activity#onStop onStop()} メソッドが実行されます。</li> +</ol> + + <p>このライフサイクル コールバックの順序を予測しておくことで、1 つのアクティビティから他のアクティビティへの情報の遷移を管理できるようになります。 +たとえば、1 つ目のアクティビティが停止したときに、後続のアクティビティが読み取れるようにデータベースに書き込む必要がある場合、データベースに書き込むタイミングは {@link +android.app.Activity#onStop onStop()} ではなく {@link android.app.Activity#onPause onPause()} の間になります。 + +</p> + +<!-- +<h2>Beginner's Path</h2> + +<p>For more information about how Android maintains a history of activities and +enables user multitasking, continue with the <b><a +href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back +Stack</a></b> document.</p> +--> diff --git a/docs/html-intl/intl/ja/guide/components/bound-services.jd b/docs/html-intl/intl/ja/guide/components/bound-services.jd new file mode 100644 index 000000000000..d115e76ed04b --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/bound-services.jd @@ -0,0 +1,658 @@ +page.title=バインドされたサービス +parent.title=サービス +parent.link=services.html +@jd:body + + +<div id="qv-wrapper"> +<ol id="qv"> +<h2>本書の内容</h2> +<ol> + <li><a href="#Basics">基本</a></li> + <li><a href="#Creating">バインドされたサービスを作成する</a> + <ol> + <li><a href="#Binder">Binder クラスを拡張する</a></li> + <li><a href="#Messenger">メッセンジャーを使用する</a></li> + </ol> + </li> + <li><a href="#Binding">サービスにバインドする</a></li> + <li><a href="#Lifecycle">バインドされたサービスのライフサイクルを管理する</a></li> +</ol> + +<h2>キークラス</h2> +<ol> + <li>{@link android.app.Service}</li> + <li>{@link android.content.ServiceConnection}</li> + <li>{@link android.os.IBinder}</li> +</ol> + +<h2>サンプル</h2> +<ol> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code + RemoteService}</a></li> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code + LocalService}</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ol> + <li><a href="{@docRoot}guide/components/services.html">サービス</a></li> +</ol> +</div> + + +<p>バインドされたサービスは、クライアントサーバー インターフェースにおけるサーバーになります。バインドされたサービスでは、コンポーネント(アクティビティなど)をサービスにバインドしたり、送信を要求したり、受信を応答したり、さらにはプロセス間通信(IPC)を実行したりできるようにします。 + +通常、バインドされたサービスは他のアプリケーション コンポーネントを提供している間だけ機能し、バックグラウンドで無期限に実行されることはありません。 +</p> + +<p>このドキュメントでは、他のアプリケーション コンポーネントからのサービスにバインドする方法を含む、バインドされたサービスの作成方法について説明します。 +ただし、サービスから通知を配信する方法や、フォアグラウンドでサービスを実行するよう設定する方法など、サービス全般の詳細については、「<a href="{@docRoot}guide/components/services.html">サービス</a>」のドキュメントをご覧ください。 + +</p> + + +<h2 id="Basics">基本</h2> + +<p>バインドされたサービスは、他のアプリケーションのバインドとやり取りを可能にする {@link android.app.Service} クラスの実装です。 +サービスのバインドを提供するには、{@link android.app.Service#onBind onBind()} コールバック メソッドを実装する必要があります。 +このメソッドでは {@link android.os.IBinder} オブジェクトが返されます。このオブジェクトはクライアントがサービスとのやり取りに使用するプログラミング インターフェースを定義します。 + +</p> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <h3>開始されたサービスにバインドする</h3> + +<p><a href="{@docRoot}guide/components/services.html">サービス</a> ドキュメントで説明されているように、開始されるサービスとバインドされるサービスの両方を作成できます。 +つまり、{@link android.content.Context#startService startService()} を呼び出して開始されるサービスは無期限に実行でき、クライアントが {@link +android.content.Context#bindService bindService()} を呼び出してサービスにバインドできます。 + + + <p>サービスの開始とバインドを許可すると、サービスが開始するとすべてのクライアントがアンバインドしても、システムによってサービスが破棄されることは<em>ありません</em>。 +代わりに、{@link android.app.Service#stopSelf stopSelf()} や {@link +android.content.Context#stopService stopService()} を呼び出して、サービスを明示的に停止する必要があります。 +</p> + +<p>通常実装するのは、{@link android.app.Service#onBind onBind()} +<em> か </em>{@link android.app.Service#onStartCommand onStartCommand()} のどちらかですが、両方の実装が必要な場合もあります。 +たとえば、音楽プレーヤーの場合はサービスを無期限に実行しつつ、バインドも提供できると便利な場合があります。 +この方法であれば、アクティビティがサービスを開始して音楽を再生し、ユーザーがアプリケーションから離れた場合も音楽を再生し続けることができます。 +次にユーザーがアプリケーションに戻ったとき、アクティビティがサービスにバインドして再生のコントロールをもう一度行えるようになります。 +</p> + +<p>開始されたサービスにバインドを追加する際のサービスのライフサイクルの詳細については、<a href="#Lifecycle">バインドされたサービスのライフサイクルを管理する</a>を必ずご覧ください。 + +</p> +</div> +</div> + +<p>クライアントは、{@link android.content.Context#bindService +bindService()} を呼び出せばサービスにバインドできます。バインドするときは、サービスとの接続を監視する {@link +android.content.ServiceConnection} を実装する必要があります。{@link +android.content.Context#bindService bindService()} メソッドは値なしですぐに返されますが、Android システムがクライアントとサービス間の接続を作成すると {@link +android.content.ServiceConnection} の {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} が呼び出され、クライアントがサービスとの通信に使用できる {@link android.os.IBinder} が配信されます。 + + +</p> + +<p>複数のクライアントが同時にサービスに接続できます。ただし、1 つ目のクライアントのバインドの際にのみ、システムはサービスの {@link android.app.Service#onBind onBind()} メソッドを呼び出して{@link android.os.IBinder} を取得します。 + +その後システムは {@link android.app.Service#onBind onBind()} を呼び出すことなく、同じ {@link android.os.IBinder} をバインドしたすべてのクライアントに配信します。 +</p> + +<p>最後のクライアントがサービスからアンバインドされると、システムはサービスを破棄します(サービスが {@link android.content.Context#startService startService()} でも開始された場合を除く)。 +</p> + +<p>バインドされたサービスを実装するときに最も重要なのは、{@link android.app.Service#onBind onBind()} コールバック メソッドが返すインターフェースを定義することです。 +サービスの {@link android.os.IBinder} インターフェースの定義には複数の方法があり、次のセクションではそれぞれのテクニックについて説明していきます。 + +</p> + + + +<h2 id="Creating">バインドされたサービスを作成する</h2> + +<p>バインドを提供するサービスを作成するとき、クライアントがサービスとのやり取りに使用するプログラミング インターフェースを提供する {@link android.os.IBinder} を提示する必要があります。 +インターフェースを定義するには、次の 3 つの方法があります。 +</p> + +<dl> + <dt><a href="#Binder">Binder クラスを拡張する</a></dt> + <dd>サービスが独自のアプリケーション専用であり、クライアントと同じプロセスで実行する場合(ほとんどのケースに該当)、{@link android.os.Binder} クラスを拡張して {@link android.app.Service#onBind onBind()} からそのインスタンスを返すことでインターフェースを作成します。 + + +クライアントは {@link android.os.Binder} を受け取り、それを使用して {@link android.os.Binder} の実装や {@link android.app.Service} で利用できる public メソッドに直接アクセスできます。 + + + <p>サービスが単にアプリケーションのバックグラウンド ワーカーである場合は、この方法が適しています。 +この方法が適していない唯一のケースは、サービスが他のアプリケーションや、別のプロセス間で使用されている場合です。 +</dd> + + <dt><a href="#Messenger">メッセンジャーを使用する</a></dt> + <dd>別のプロセス間で動作するインターフェースが必要な場合は、{@link android.os.Messenger} を使用してサービス用のインターフェースを作成できます。 +この方法では、サービスが異なるタイプの {@link +android.os.Message} オブジェクトに応答する {@link android.os.Handler} を定義します。 +この {@link android.os.Handler} を基本として {@link android.os.Messenger} は {@link android.os.IBinder} をクライアントと共有でき、 クライアントは {@link +android.os.Message} オブジェクトを使用してサービスにコマンドを送信できるようになります。 + +さらに、クライアントはサービスがメッセージを返信できるように独自の {@link android.os.Messenger} を定義できます。 + + <p>これは、最も簡単にプロセス間通信(IPC)を実行する方法であり、{@link +android.os.Messenger} がすべてのリクエストを 1 つのスレッドにキューイングするため、サービスをスレッドセーフにデザインする必要がありません。 +</p> + </dd> + + <dt>AIDL を使用する</dt> + <dd>AIDL(Android インターフェース定義言語)は、オブジェクトをオペーレーティングシステムが理解できるプリミティブに分解するためのすべての処理のを実行し、プロセス間でそれを整理して IPC 実行します。{@link android.os.Messenger} を使用する前の方法は、実際には AIDL を基本構造としています。 + + +前述したように、{@link android.os.Messenger} はすべてのクライアントの要求のキューを 1 つのスレッドに作成するため、サービスは要求を一度に受け取ります。 +ただし、サービスで複数の要求を同時に処理する場合は、AIDL を直接使用できます。 + +その場合、サービスがマルチスレッドに対応しており、スレッドセーフで構築されている必要があります。 + <p>AIDL を直接使用するには、プログラミング インターフェースを定義する {@code .aidl} ファイルを作成する必要があります。 +Android SDK ツールはこのファイルを使用して、インターフェースを実装して IPC を処理する抽象クラスを生成し、それをサービス内に拡張できます。 + +</p> + </dd> +</dl> + + <p class="note"><strong>注:</strong> ほとんどのアプリケーションにおいて、マルチスレッド化が必要な点や、結果的により複雑な実装となってしまうことから、AIDL を使ったバインドされたサービスの作成は<strong>お勧めしません</strong>。 + +AIDL はほとんどのアプリケーションに適していないため、このドキュメントではサービスでの AIDL の使用方法については取り上げません。 +どうしても AIDL の直接使用が必要な場合は、「<a href="{@docRoot}guide/components/aidl.html">AIDL</a>」のドキュメントをご覧ください。 + +</p> + + + + +<h3 id="Binder">Binder クラスを拡張する</h3> + +<p>サービスがローカルのアプリケーションでのみ使用されていて、プロセス間での作業が必要ない場合は、クライアントがサービスの public メソッドに直接アクセスできるようにする独自の {@link android.os.Binder} クラスを実装できます。 + +</p> + +<p class="note"><strong>注:</strong> この方法は、クライアントとサービスが同じアプリケーションとプロセスにある場合(最も一般的なケース)のみ使用できます。 +たとえば、バックグラウンドで音楽を再生する独自のサービスに、アクティビティをバインドする必要のある音楽アプリケーションに適しています。 + +</p> + +<p>セットアップ方法は次のとおりです。</p> +<ol> + <li>サービスで次のいずれかに該当する {@link android.os.Binder} のインスタンスを作成します。 + <ul> + <li>クライアントが呼び出せる public メソッドを含んでいる</li> + <li>クライアントが呼び出せる public メソッドのある現在の {@link android.app.Service} インスタンスを返す +</li> + <li>クライアントが呼び出せる public メソッドのあるサービスでホストされた他のクラスのインスタンスを返す +</li> + </ul> + <li>{@link android.os.Binder} のインスタンスを {@link +android.app.Service#onBind onBind()} コールバック メソッドから返します。</li> + <li>クライアントで、{@link android.os.Binder} を {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} コールバック メソッドから受け取り、提供されたメソッドを使用してバインドされたサービスを呼び出します。 +</li> +</ol> + +<p class="note"><strong>注:</strong> サービスとクライアントが同じアプリケーションになければならない理由は、クライアントが返されたオブジェクトをキャストでき、その API を適切に呼び出せるようにするためです。 +また、サービスとクライアントが同じプロセスになければならない理由は、この方法ではプロセス間の整理が一切行われないためです。 + +</p> + +<p>以下は、{@link android.os.Binder} の実装を介してサービスのメソッドにクライアントアクセスを提供するサービスの例です。 +</p> + +<pre> +public class LocalService extends Service { + // Binder given to clients + private final IBinder mBinder = new LocalBinder(); + // Random number generator + private final Random mGenerator = new Random(); + + /** + * Class used for the client Binder. Because we know this service always + * runs in the same process as its clients, we don't need to deal with IPC. + */ + public class LocalBinder extends Binder { + LocalService getService() { + // Return this instance of LocalService so clients can call public methods + return LocalService.this; + } + } + + @Override + public IBinder onBind(Intent intent) { + return mBinder; + } + + /** method for clients */ + public int getRandomNumber() { + return mGenerator.nextInt(100); + } +} +</pre> + +<p>{@code LocalBinder} が {@code LocalService} の現在のインスタンスを取り出すための {@code getService()}メソッドをクライアントに提供します。 +これにより、クライアントがサービス内の public メソッドを呼び出せるようになります。 +たとえば、クライアントはサービスから {@code getRandomNumber()} を呼び出すことができます。</p> + +<p>以下は、{@code LocalService} にバインドして、ボタンがクリックされたときに {@code getRandomNumber()} を呼び出すアクティビティの例です。 +</p> + +<pre> +public class BindingActivity extends Activity { + LocalService mService; + boolean mBound = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } + + @Override + protected void onStart() { + super.onStart(); + // Bind to LocalService + Intent intent = new Intent(this, LocalService.class); + bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + } + + @Override + protected void onStop() { + super.onStop(); + // Unbind from the service + if (mBound) { + unbindService(mConnection); + mBound = false; + } + } + + /** Called when a button is clicked (the button in the layout file attaches to + * this method with the android:onClick attribute) */ + public void onButtonClick(View v) { + if (mBound) { + // Call a method from the LocalService. + // However, if this call were something that might hang, then this request should + // occur in a separate thread to avoid slowing down the activity performance. + int num = mService.getRandomNumber(); + Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); + } + } + + /** Defines callbacks for service binding, passed to bindService() */ + private ServiceConnection mConnection = new ServiceConnection() { + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + LocalBinder binder = (LocalBinder) service; + mService = binder.getService(); + mBound = true; + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mBound = false; + } + }; +} +</pre> + +<p>上の例は、{@link android.content.ServiceConnection} の実装と {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} コールバックを使用してクライアントがサービスにバインドする方法を示しています。 +次のセクションでは、サービスへのバインドのプロセスについて詳しく説明していきます。 +</p> + +<p class="note"><strong>注:</strong> 上記の例ではサービスから明示的にアンバウンドしていませんが、すべてのクライアントは適切なタイミング(アクティビティが一時停止したときなど)でアンバウンドする必要があります。 +</p> + +<p>他のサンプル コードについては、<a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a> の <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code +LocalService.java}</a> クラスと <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code +LocalServiceActivities.java}</a> クラスをご覧ください。</p> + + + + + +<h3 id="Messenger">メッセンジャーを使用する</h3> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <h4>AIDL との比較</h4> + <p>IPC を実行する必要がある場合、インターフェースで {@link android.os.Messenger} を使う方が AIDL で実装するよりも簡単です。{@link android.os.Messenger} がすべての呼び出しをサービスにキューイングするのに対して、純粋な AIDL インターフェースでは同時に複数の要求をサービスに送るため、マルチスレッドの処理が必要になるためです。 + + +</p> + <p>ほとんどのアプリケーションにおいて、サービスはマルチスレッドを実行する必要がないため、{@link +android.os.Messenger} を使用することでサービスが一度に 1 つの呼び出しを処理できます。サービスのマルチスレッド化が重視されている場合は、<a href="{@docRoot}guide/components/aidl.html">AIDL</a> を使用してインターフェースを定義してください。 +</p> +</div> +</div> + +<p>リモート プロセスと通信するサービスが必要な場合は、{@link android.os.Messenger} を使用してサービスのインターフェースを提供できます。 +この方法では、AIDL を使用する必要なくプロセス間通信(IPC)を実行できます。 +</p> + +<p>{@link android.os.Messenger} の使用方法の概要は以下のとおりです。</p> + +<ul> + <li>クライアントからの呼び出しごとにコールバックを受け取る{@link android.os.Handler} をサービスが実装します。 +</li> + <li>{@link android.os.Handler} を使用して {@link android.os.Messenger} オブジェクトを作成します( +{@link android.os.Handler} への参照になります)。</li> + <li>{@link android.os.Messenger} が、サービスが {@link android.app.Service#onBind onBind()} からクライアントに返す {@link android.os.IBinder} を作成します。 +</li> + <li>クライアントが {@link android.os.IBinder} を使用して、(サービスの {@link android.os.Handler} を参照する){@link android.os.Messenger} をインスタンス化し、これを使用してクライアントが {@link android.os.Message} オブジェクトをサービスに送ります。 + +</li> + <li>サービスが {@link +android.os.Handler}、具体的には、{@link android.os.Handler#handleMessage +handleMessage()} メソッドで、それぞれの {@link android.os.Message} を受け取ります。—</li> +</ul> + + +<p>この方法には、クライアントがサービスで呼び出す「メソッド」はありません。代わりに、クライアントはサービスが {@link android.os.Handler} で受け取る「メッセージ({@link android.os.Message} オブジェクト)」を配信します。 + +</p> + +<p>以下は、{@link android.os.Messenger} インターフェースを使用するサービスの簡単な例です。</p> + +<pre> +public class MessengerService extends Service { + /** Command to the service to display a message */ + static final int MSG_SAY_HELLO = 1; + + /** + * Handler of incoming messages from clients. + */ + class IncomingHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_SAY_HELLO: + Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); + break; + default: + super.handleMessage(msg); + } + } + } + + /** + * Target we publish for clients to send messages to IncomingHandler. + */ + final Messenger mMessenger = new Messenger(new IncomingHandler()); + + /** + * When binding to the service, we return an interface to our messenger + * for sending messages to the service. + */ + @Override + public IBinder onBind(Intent intent) { + Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); + return mMessenger.getBinder(); + } +} +</pre> + +<p>{@link android.os.Handler} の {@link android.os.Handler#handleMessage handleMessage()} メソッドが、サービスが {@link android.os.Message} を受け取る場所であり、{@link android.os.Message#what} メンバーに基づいてその後の操作を決める場面であることに注目してください。 + +</p> + +<p>クライアントで必要な操作は、サービスから返された {@link +android.os.IBinder} に基づいて {@link android.os.Messenger} を作成し、{@link +android.os.Messenger#send send()} を使用してメッセージを送信するだけです。例として、サービスにバインドして {@code MSG_SAY_HELLO} メッセージをサービスに送信する簡単なアクティビティを次に示します。 +</p> + +<pre> +public class ActivityMessenger extends Activity { + /** Messenger for communicating with the service. */ + Messenger mService = null; + + /** Flag indicating whether we have called bind on the service. */ + boolean mBound; + + /** + * Class for interacting with the main interface of the service. + */ + private ServiceConnection mConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + // This is called when the connection with the service has been + // established, giving us the object we can use to + // interact with the service. We are communicating with the + // service using a Messenger, so here we get a client-side + // representation of that from the raw IBinder object. + mService = new Messenger(service); + mBound = true; + } + + public void onServiceDisconnected(ComponentName className) { + // This is called when the connection with the service has been + // unexpectedly disconnected -- that is, its process crashed. + mService = null; + mBound = false; + } + }; + + public void sayHello(View v) { + if (!mBound) return; + // Create and send a message to the service, using a supported 'what' value + Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); + try { + mService.send(msg); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } + + @Override + protected void onStart() { + super.onStart(); + // Bind to the service + bindService(new Intent(this, MessengerService.class), mConnection, + Context.BIND_AUTO_CREATE); + } + + @Override + protected void onStop() { + super.onStop(); + // Unbind from the service + if (mBound) { + unbindService(mConnection); + mBound = false; + } + } +} +</pre> + +<p>この例では、サービスがクライアントにどのように応答できるのかは示されていません。サービスが応答するようにするには、クライアントで {@link android.os.Messenger} も作成する必要があります。 +その後、クライアントが {@link android.content.ServiceConnection#onServiceConnected +onServiceConnected()} コールバックを受け取るとき、{@link android.os.Messenger#send send()} メソッドの {@link android.os.Message#replyTo} パラメータにクライアントの{@link android.os.Messenger} を含めてサービスに {@link android.os.Message} を送信します。 + + +</p> + +<p>双方向メッセージを提供する方法のサンプルについては、<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">{@code +MessengerService.java}</a>(サービス)と <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code +MessengerServiceActivities.java}</a>(クライアント)のサンプルをご覧ください。</p> + + + + + +<h2 id="Binding">サービスにバインドする</h2> + +<p>アプリケーションのコンポーネント(クライアント)は、{@link android.content.Context#bindService bindService()} を呼び出してサービスにバインドできます。 +次に Android システムがサービスの {@link android.app.Service#onBind +onBind()} メソッドを呼び出し、そこからサービスとのやり取りに必要な {@link android.os.IBinder} が返されます。 +</p> + +<p>バインドは非同期的に行われます。{@link android.content.Context#bindService +bindService()} は瞬時に返され、{@link android.os.IBinder} はクライアントには<em>返されません</em>。 +{@link android.os.IBinder} を受け取るには、クライアントが {@link +android.content.ServiceConnection} のインスタンスを作成し、それを {@link android.content.Context#bindService +bindService()} に渡す必要があります。{@link android.content.ServiceConnection} にはシステムが {@link android.os.IBinder} の配信用に呼び出すコールバック メソッドが含まれています。 +</p> + +<p class="note"><strong>注:</strong> サービスにバインドできるのは、アクティビティ、サービス、コンテンツ プロバイダのみです。ブロードキャスト レシーバーからサードパーティビスにはバインド<strong>できません</strong>。 +—</p> + +<p>そのため、クライアントからサービスにバインドするには次の操作が必要です。 </p> +<ol> + <li>{@link android.content.ServiceConnection} を実装する。 + <p>実装では次の 2 つのコールバック メソッドをオーバーライドする必要があります。</p> + <dl> + <dt>{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}</dt> + <dd>システムがこれを呼び出して、サービスの {@link android.app.Service#onBind onBind()} メソッドから返された {@link android.os.IBinder} を配信します。 +</dd> + <dt>{@link android.content.ServiceConnection#onServiceDisconnected +onServiceDisconnected()}</dt> + <dd>サービスがクラッシュしたり強制終了されたりした場合など、サービスへの接続が予期せず失われたときに、Android システムがこれを呼び出します。 +これは、クライアントのアンバウンドの際には<em>呼び出されません</em>。 +</dd> + </dl> + </li> + <li>{@link +android.content.Context#bindService bindService()} を呼び出して、{@link +android.content.ServiceConnection} の実装を渡します。 </li> + <li>システムが {@link android.content.ServiceConnection#onServiceConnected +onServiceConnected()} コールバック メソッドを呼び出すと、インターフェースで定義されたメソッドを使用してサービスへの呼び出しを開始できます。 +</li> + <li>サービスとの接続を切断するには、{@link +android.content.Context#unbindService unbindService()} を呼び出します。 + <p>クライアントが破棄されたときにはサービスからアンバウンドしますが、サービスが使用されていないときはシャットダウンできるよう、サービスとのやり取りが終了したときや、アクティビティが停止したときは常にアンバウンドする必要があります + +(バインドとアンバインドの適切なタイミングについては後半でさらに詳しく説明します)。 +</p> + </li> +</ol> + +<p>たとえば、次のスニペットは <a href="#Binder"> Binder クラスを拡張</a>して先ほど作成したサービスにクライアントを接続しており、返された {@link android.os.IBinder} を {@code LocalService} クラスにキャストして、{@code +LocalService} インスタンスを要求することだけが必要になります。 + +</p> + +<pre> +LocalService mService; +private ServiceConnection mConnection = new ServiceConnection() { + // Called when the connection with the service is established + public void onServiceConnected(ComponentName className, IBinder service) { + // Because we have bound to an explicit + // service that is running in our own process, we can + // cast its IBinder to a concrete class and directly access it. + LocalBinder binder = (LocalBinder) service; + mService = binder.getService(); + mBound = true; + } + + // Called when the connection with the service disconnects unexpectedly + public void onServiceDisconnected(ComponentName className) { + Log.e(TAG, "onServiceDisconnected"); + mBound = false; + } +}; +</pre> + +<p>この {@link android.content.ServiceConnection} を使用して、クライアントは {@link android.content.Context#bindService bindService()} に渡すことでサービスにバインドできます。 +次に例を示します。</p> + +<pre> +Intent intent = new Intent(this, LocalService.class); +bindService(intent, mConnection, Context.BIND_AUTO_CREATE); +</pre> + +<ul> + <li>{@link android.content.Context#bindService bindService()} の最初のパラメータは、バインドするサービス名を明示的に指定する {@link android.content.Intent} です(インテントは暗黙的である場合があります)。 + +</li> +<li>2 つ目のパラメータは {@link android.content.ServiceConnection} オブジェクトです。</li> +<li>3 つ目のパラメータはバインドのオプションを示すフラグです。通常は {@link +android.content.Context#BIND_AUTO_CREATE} でサービスがまだ存在していない場合にサービスを作成します。他の有効な値は、{@link android.content.Context#BIND_DEBUG_UNBIND} と {@link android.content.Context#BIND_NOT_FOREGROUND} か、未指定の {@code 0} です。 + +</li> +</ul> + + +<h3>その他の注意点</h3> + +<p>サービスへのバインドに関する重要な注意点は次のとおりです。</p> +<ul> + <li>接続が切れたときに投げられる {@link android.os.DeadObjectException} 例外は、常に処理する必要があります。 +リモート メソッドから投げられる例外はこれのみです。</li> + <li>オブジェクトはプロセス間で有効な参照です。 </li> + <li>通常は、クライアントのライフサイクルの立ち上がりと終了のタイミングに合わせて、その間でバインドとアンバインドをペア設定します。 +次に例を示します。 + <ul> + <li>アクティビティが見えている間のみサービスとやり取りする必要がある場合は、 +{@link android.app.Activity#onStart onStart()} の間にバインドし、{@link +android.app.Activity#onStop onStop()} の間にアンバインドします。</li> + <li>アクティビティがバックグラウンドで停止している間も応答を受け取りたい場合は、{@link android.app.Activity#onCreate onCreate()} の間にバインドし、{@link android.app.Activity#onDestroy onDestroy()} の間にアンバインドします。 + +つまり、アクティビティの実行中は(バックグラウンドも含む)常にサービスを使用する必要があるため、サービスが別のプロセスにある場合は、プロセスの重みを上げて、システムに強制終了させやすいようにします。 + + +</li> + </ul> + <p class="note"><strong>注:</strong> 通常、アクティビティの {@link android.app.Activity#onResume onResume()} と {@link +android.app.Activity#onPause onPause()} の間にはバインドとアンバインドは<strong>行いません</strong>。これは、これらのコールバックがライフサイクルの遷移すべてで発生するため、その遷移で発生するプロセスを最小限に抑える必要があるためです。 + +また、アプリケーションの複数のアクティビティが同一サービスにバインドしていて、そのなかの 2 つのアクティビティ間の遷移が生じる場合、現在のアクティビティは次のアクティビティがバインドする(再開中)前にアンバインドされる(停止中)ため、サービスが破棄されて再作成される場合があります + + +(ライフサイクルと連携したアクティビティの遷移の詳細については、「<a href="{@docRoot}guide/components/activities.html#CoordinatingActivities">Activities</a>」のドキュメントをご覧ください)。 + +</p> +</ul> + +<p>他のサンプル コードについては、 <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a> の <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code +RemoteService.java}</a> クラスをご覧ください。</p> + + + + + +<h2 id="Lifecycle">バインドされたサービスのライフサイクルを管理する</h2> + +<p>サービスがすべてのクライアントからアンバインドされると、Android システムがそれを破棄します({@link android.app.Service#onStartCommand onStartCommand()} でも開始された場合を除く)。 +純粋にバインドされたサービスであれば、サービスのライフサイクルを管理する必要はありません。サービスがクライアントにバインドされているかどうかに基づいて Android システムがそれを管理します。 + +—</p> + +<p>ただし、{@link android.app.Service#onStartCommand +onStartCommand()} コールバック メソッドを実装する場合は、サービスは <em>開始された</em>とみなされるため、明示的に停止する必要があります。 +この場合、クライアントにバインドされているかどうかにかかわらず、サービスが {@link android.app.Service#stopSelf()} で自ら停止するまで、または他のコンポーネントが {@link +android.content.Context#stopService stopService()} を呼び出すまで実行し続けます。 + +</p> + +<p>さらに、サービスが開始されてバインドを許可する場合、システムが {@link android.app.Service#onUnbind onUnbind()} メソッドを呼び出すとき、次回クライアントがサービスにバインドするときに {@link android.app.Service#onRebind +onRebind()} への呼び出しを受け取りたい場合は、{@code true} を返すようにすることもできます({@link +android.app.Service#onBind onBind()} への呼び出しを受け取る代わりに)。{@link android.app.Service#onRebind +onRebind()} からは void が返されますが、クライアントは {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} コールバックで {@link android.os.IBinder} を受け取ります。下の図 1 は、ライフサイクルのこの種の論理を表しています。 + + + +</p> + + +<img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" /> +<p class="img-caption"><strong>図 1.</strong> 開始されたサービスでバインドを許可するサービスのライフサイクル +</p> + + +<p>開始されたサービスのライフサイクルの詳細については、「<a href="{@docRoot}guide/components/services.html#Lifecycle">サービス</a>」のドキュメントをご覧ください。</p> + + + + diff --git a/docs/html-intl/intl/ja/guide/components/fragments.jd b/docs/html-intl/intl/ja/guide/components/fragments.jd new file mode 100644 index 000000000000..31fb7f5020b2 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/fragments.jd @@ -0,0 +1,812 @@ +page.title=フラグメント +parent.title=アクティビティ +parent.link=activities.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>本書の内容</h2> + <ol> + <li><a href="#Design">デザインの指針</a></li> + <li><a href="#Creating">フラグメントを作成する</a> + <ol> + <li><a href="#UI">ユーザー インターフェースを追加する</a></li> + <li><a href="#Adding">フラグメントをアクティビティに追加する</a></li> + </ol> + </li> + <li><a href="#Managing">フラグメントを管理する</a></li> + <li><a href="#Transactions">フラグメントのトランザクションを実行する</a></li> + <li><a href="#CommunicatingWithActivity">アクティビティと通信する</a> + <ol> + <li><a href="#EventCallbacks">アクティビティへのイベント コールバックを作成する</a></li> + <li><a href="#ActionBar">アクションバーにアイテムを追加する</a></li> + </ol> + </li> + <li><a href="#Lifecycle">フラグメントのライフサイクルを処理する</a> + <ol> + <li><a href="#CoordinatingWithActivity">アクティビティのライフサイクルと連携する</a></li> + </ol> + </li> + <li><a href="#Example">例</a></li> + </ol> + + <h2>キークラス</h2> + <ol> + <li>{@link android.app.Fragment}</li> + <li>{@link android.app.FragmentManager}</li> + <li>{@link android.app.FragmentTransaction}</li> + </ol> + + <h2>関連ドキュメント</h2> + <ol> + <li><a href="{@docRoot}training/basics/fragments/index.html">Building a Dynamic UI with Fragments</a></li> + <li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Supporting Tablets +and Handsets</a></li> + </ol> +</div> +</div> + +<p>{@link android.app.Fragment} は、{@link android.app.Activity} でのユーザー インターフェースの挙動や部位を表すものです。 +1 つのアクティビティに複数のフラグメントを組み合わせてマルチペインの UI をビルドしたり、複数のアクティビティでフラグメントを再利用したりできます。 +フラグメントとは、アクティビティのモジュール型セクションのようなもので、独自のライフサイクルを持ち、独自の入力イベントを受信します。フラグメントはアクティビティの実行中に追加したり削除したりできます(別のアクティビティで再利用できる「サブ アクティビティ」のようなものです)。 + + +</p> + +<p>フラグメントは常にアクティビティに埋め込まれている必要があり、フラグメントのライフサイクルはホストのアクティビティのライフサイクルの影響を直接受けます。 +たとえば、アクティビティが一時停止しているとき、その中のすべてのフラグメントも一時停止し、アクティビティが破棄されると、すべてのフラグメントも破棄されます。 +ただし、アクティビティの実行中(<a href="{@docRoot}guide/components/activities.html#Lifecycle">ライフサイクル</a>で<em>再開</em>された状態)は、追加や削除といった操作は各フラグメントだけで行うことができます。 + +このようなフラグメントのトランザクションを実行するとき、アクティビティで管理されているバックスタックにそれを追加することもできます。アクティビティの各バックスタック エントリは、発生したフラグメントのトランザクションの記録になります。 + +— +バックスタックでは、[<em>戻る</em>] ボタンを押すとフラグメントのトランザクションを戻す(前に戻る)ことができます。 +</p> + +<p>アクティビティのレイアウトの一部としてフラグメントを追加すると、フラグメントはアクティビティのビュー階層の {@link +android.view.ViewGroup} に置かれ、フラグメントが自身のビュー レイアウトを定義します。フラグメントをアクティビティのレイアウトに挿入するには、アクティビティのレイアウト ファイルでフラグメントを {@code <fragment>} として定義するか、アプリケーション コードで既存の {@link android.view.ViewGroup} に追加します。 + + + +ただし、フラグメントは必ずしもアクティビティの一部になる必要はなく、アクティビティの目に見えないワーカーとして、フラグメント独自の UI なしで使用することもできます。 + +</p> + +<p>このドキュメントでは、アクティビティのバックスタックに追加した時のフラグメントの状態を維持する方法、アクティビティ内でアクティビティと他のフラグメントとイベントを共有する方法、アクティビティのアクションバーへの影響など、フラグメントを使用してアプリケーションをビルドする方法について説明します。 + + +</p> + + +<h2 id="Design">デザインの指針</h2> + +<p>Android では、タブレットなどの大画面でのよりダイナミックで柔軟な UI デザインに対応するため、Android 3.0(API レベル 11)でフラグメントが採用されました。 +タブレットの画面はハンドセットよりもかなり大きいため、UI コンポーネントを組み合わせたり入れ替えたりできる領域が広くなります。 + +フラグメントでは、ビュー階層に複雑な変更を加えることなく、そのようなデザインを実現できます。 +アクティビティのレイアウトをフラグメントに分割することで、アクティビティの外観を実行時に変更でき、それらの変更をアクティビティが管理するバックスタックに保持できます。 + +</p> + +<p>たとえば新しいアプリケーションでは、1 つのフラグメントを使って左側に記事の一覧を表示したり、別のフラグメントを使って右側に記事の内容を表示したりできます。両方のフラグメントが 1 つのアクティビティに横並びに表示され、それぞれのフラグメントには自身のライフサイクル メソッドがあり、それぞれのユーザー入力イベントを処理します。 +— + +つまり、1 つのアクティビティで記事を選択して、別のアクティビティで記事を閲覧するのではなく、図 1 のタブレットのレイアウトのように 1 つのアクティビティ内で記事を選択して閲覧できるようになります。 + +</p> + +<p>各フラグメントはモジュール型の、再利用可能なアクティビティ コンポーネントとしてデザインする必要があります。各フラグメントは独自のライフサイクル コールバックを使用して自身のレイアウトと挙動とを定義するため、1 つのフラグメントを複数のアクティビティに含めることができます。このことから、再利用可能なデザインを用いることに加えて、1 つのフラグメントを他のフラグメントから直接操作しないようにする必要があります。 + + +これは、モジュール型のフラグメントでは画面のサイズごとにフラグメントの組み合わせを変更できる点からも、特に重要です。 +タブレットとハンドセットの両方に対応したアプリケーションをデザインする場合、異なるレイアウト構成でフラグメントを再利用することで、利用可能な画面の領域に応じて最適な使い心地を実現できます。 + +たとえばハンドセットの場合、同一のアクティビティ内に 2 つ以上のフラグメントが収まりきらないときは、フラグメントを分割してシングルペインの UI を提示する必要があることもあります。 + +</p> + +<img src="{@docRoot}images/fundamentals/fragments.png" alt="" /> +<p class="img-caption"><strong>図 1.</strong> 1 つのアクティビティ内で、フラグメントで定義された 2 つの UI モジュールを組み合わせたタブレット用デザインと、それぞれを分けたハンドセット用デザインの例。 + +</p> + +<p>引き続きニュース アプリケーションの例を使うと、アプリケーションがタブレット サイズの端末で実行中は、 2 つのフラグメントを<em>アクティビティ A</em> に埋め込むことができます。—— +しかし、ハンドセット サイズの画面では両方のフラグメントを表示する領域が足りないため、<em>アクティビティ A</em> には記事の一覧のフラグメントだけが含まれます。記事を選択すると、記事を閲覧するための 2 つ目のフラグメントが含まれる<em>アクティビティ B</em> が開始されます。 + + +そのため、図 1 のようにアプリケーションはフラグメントを異なる組み合わせで再利用することで、タブレットとハンドセットの両方に対応できるようになります。 + +</p> + +<p>異なる画面構成ごとに異なるフラグメントの組み合わせを用いたアプリケーションのデザインの詳細については、「<a href="{@docRoot}guide/practices/tablets-and-handsets.html">Supporting Tablets and Handsets</a>」のガイドをご覧ください。 +</p> + + + +<h2 id="Creating">フラグメントを作成する</h2> + +<div class="figure" style="width:327px"> +<img src="{@docRoot}images/fragment_lifecycle.png" alt="" /> +<p class="img-caption"><strong>図 2.</strong> フラグメントのライフサイクル(アクティビティの実行中) +</p> +</div> + +<p>フラグメントを作成するには、{@link android.app.Fragment} のサブクラス(またはその既存のサブクラス)を作成する必要があります。 +{@link android.app.Fragment} クラスには、{@link android.app.Activity} に非常に似ているコードがあります。 +これには、{@link android.app.Fragment#onCreate onCreate()}、{@link android.app.Fragment#onStart onStart()}、{@link android.app.Fragment#onPause onPause()}、{@link android.app.Fragment#onStop onStop()} のようなアクティビティと同様のコールバック メソッドが含まれています。 + +実際に、既存の Android アプリケーションを変換してフラグメントを使用するには、アクティビティのコールバック メソッドから、フラグメントの各コールバック メソッドにコードを移動させるだけで。 + + +</p> + +<p>通常は、少なくとも次のライフサイクル メソッドを実装する必要があります。</p> + +<dl> + <dt>{@link android.app.Fragment#onCreate onCreate()}</dt> + <dd>フラグメントの作成時にシステムが呼び出します。実装内で、フラグメントが一時停止、停止、再開されたときに保持するフラグメントの必須コンポーネントを初期化する必要があります。 + +</dd> + <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt> + <dd>フラグメントが初めてユーザー インターフェースを描画するタイミングでシステムがこれを呼び出します。 +フラグメントの UI を描画するには、このメソッドからフラグメントのレイアウトのルートとなっている {@link android.view.View} を返す必要があります。 +フラグメントが UI を提示しない場合は、null を返すことができます。 +</dd> + <dt>{@link android.app.Activity#onPause onPause()}</dt> + <dd>ユーザーがフラグメントから離れたことを初めて示すときに、このメソッドを呼び出します(フラグメントが破棄されていない場合も含む)。 +通常はここで、現在のユーザー セッション後も維持する必要のある変更点を保存しておきます(ユーザーが戻ってこない可能性があるため)。 + +</dd> +</dl> + +<p>ほとんどのアプリケーションでは、各フラグメントで少なくともこれら 3 つのメソッドを実装する必要がありますが、フラグメントのライフサイクルのさまざまなステージを処理する際に使用する他のコールバック メソッドもいくつかあります。 + +すべてのライフサイクル コールバック メソッドについては、<a href="#Lifecycle">フラグメントのライフサイクルの処理</a>のセクションで説明します。 +</p> + + +<p>基本の {@link +android.app.Fragment} クラスの代わりに拡張できるサブクラスもいくつかあります。</p> + +<dl> + <dt>{@link android.app.DialogFragment}</dt> + <dd>フローティング ダイアログを表示します。{@link android.app.Activity} のダイアログ ヘルパー メソッド代わりにこのクラスを使用してダイアログを作成すると、アクティビティで管理されるフラグメントのバックスタックにフラグメント ダイアログを組み込むことができるため、ユーザーは終了したフラグメントに戻ることが可能になります。 + + +</dd> + + <dt>{@link android.app.ListFragment}</dt> + <dd>{@link android.app.ListActivity} と同様に、アダプタで管理されるアイテムのリストを表示します({@link +android.widget.SimpleCursorAdapter} など)。クリック イベントを処理するための {@link +android.app.ListFragment#onListItemClick(ListView,View,int,long) onListItemClick()} コールバックなど、リスト ビューを管理するメソッドがいくつか提供されます。 + +</dd> + + <dt>{@link android.preference.PreferenceFragment}</dt> + <dd>{@link android.preference.PreferenceActivity} と同様に、{@link android.preference.Preference} オブジェクトの階層をリストとして表示します。 +アプリケーションの「設定」アクティビティの作成時に便利です。 +</dd> +</dl> + + +<h3 id="UI">ユーザー インターフェースを追加する</h3> + +<p>通常、フラグメントはアクティビティのユーザー インターフェースの一部であり、独自のレイアウトをアクティビティに提示します。 +</p> + +<p>フラグメントのレイアウトを提供するには、{@link +android.app.Fragment#onCreateView onCreateView()} コールバック メソッドを実装する必要があります。これは、フラグメントがレイアウトを描画するタイミングで Android システムが呼び出します。 +このメソッドの実装では、フラグメントのレイアウトのルートである {@link android.view.View} を返す必要があります。 +</p> + +<p class="note"><strong>注:</strong> フラグメントは {@link +android.app.ListFragment} のサブクラスの場合、デフォルトの実装で {@link android.widget.ListView} が{@link android.app.Fragment#onCreateView onCreateView()} から返されるため、これを実装する必要はありません。 +</p> + +<p>{@link +android.app.Fragment#onCreateView onCreateView()} からレイアウトを返すには、XML で定義した<a href="{@docRoot}guide/topics/resources/layout-resource.html">レイアウト リソース</a>からインフレートできます。これを行うため、{@link android.app.Fragment#onCreateView onCreateView()} から {@link android.view.LayoutInflater} オブジェクトが提供されます。 + +</p> + +<p>たとえば、次の例では {@link android.app.Fragment} のサブクラスが {@code example_fragment.xml} ファイルからレイアウトをロードします。 +</p> + +<pre> +public static class ExampleFragment extends Fragment { + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.example_fragment, container, false); + } +} +</pre> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <h3>レイアウトを作成する</h3> + <p>上の例では、{@code R.layout.example_fragment} はアプリケーション リソースに保存されている {@code example_fragment.xml} という名前のレイアウト リソースへの参照です。 +XML でレイアウトを作成する方法の詳細いついては、「<a href="{@docRoot}guide/topics/ui/index.html">ユーザー インターフェース</a>」のドキュメントをご覧ください。 + +</p> +</div> +</div> + +<p>{@link android.app.Fragment#onCreateView +onCreateView()} に渡される {@code container} パラメータは、フラグメントのレイアウトが挿入される {@link android.view.ViewGroup} の親になります(アクティビティのレイアウトから)。 + +{@code savedInstanceState} パラメータは、フラグメントが再開された場合にフラグメントの前のインスタンスに関する情報を提供する {@link android.os.Bundle} です(状態の復元の詳細については、<a href="#Lifecycle">フラグメントのライフサイクルの処理</a>で説明します)。 + + +</p> + +<p>{@link android.view.LayoutInflater#inflate(int,ViewGroup,boolean) inflate()} メソッドは、次の 3 つの引数を受け取ります。 +</p> +<ul> + <li>拡張するレイアウトのリソース ID。</li> + <li>インフレートされたレイアウトの親となる {@link android.view.ViewGroup}。システムがインフレートされたレイアウトのルートビュー(親ビューが指定)にレイアウト パラメータ適用するには、{@code +container} を渡すことが重要です。 +</li> + <li>インフレート中に、インフレートされたレイアウトを {@link +android.view.ViewGroup}(2 つ目のパラメータ)にアタッチすべきかどうかを示すブール値(この場合、システムが既にインフレートされたレイアウトを {@code +container} に挿入しているため、false になります。true を渡すと、最終レイアウトに余分なビューグループが作成されます。 +—</li> +</ul> + +<p>ここまで、レイアウトを提供するフラグメントの作成方法について説明しました。次は、フラグメントをアクティビティに追加する必要があります。 +</p> + + + +<h3 id="Adding">フラグメントをアクティビティに追加する</h3> + +<p>通常、フラグメントはホスト アクティビティに UI の一部を提供し、アクティビティの全体的なビュー階層の一部として埋め込まれます。 +アクティビティのレイアウトにフラグメントを追加する方法は 2 つあります。 +</p> + +<ul> + <li><b>アクティビティのレイアウト ファイル内でフラグメントを宣言する</b> +<p>この場合、フラグメントがビューであるかのようにレイアウト プロパティを指定できます。 +以下は、2 つのフラグメントを持つアクティビティのレイアウト ファイルです。 +</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <fragment android:name="com.example.news.ArticleListFragment" + android:id="@+id/list" + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="match_parent" /> + <fragment android:name="com.example.news.ArticleReaderFragment" + android:id="@+id/viewer" + android:layout_weight="2" + android:layout_width="0dp" + android:layout_height="match_parent" /> +</LinearLayout> +</pre> + <p>{@code <fragment>} の {@code android:name} 属性は、{@link +android.app.Fragment} クラスを指定してレイアウトにインスタンスを作成します。</p> + +<p>システムがこのアクティビティ レイアウトを作成するとき、レイアウトで指定された各フラグメントのインスタンスを作成し、それぞれの {@link android.app.Fragment#onCreateView onCreateView()} メソッドを呼び出して、各フラグメントのレイアウトを取得します。 + +システムがフラグメントから返された{@link android.view.View} を {@code <fragment>} 要素の代わりに挿入します。 +</p> + +<div class="note"> + <p><strong>注:</strong> 各フラグメントには、アクティビティの再開時にフラグメントを復元するためにシステムが使用できる(そしてフラグメントをキャプチャして削除などのトランザクションを実行する際に使用できる)一意の識別子が必要です + +フラグメントの ID を提供するには、次の 3 つの方法があります。 +</p> + <ul> + <li>{@code android:id} 属性に一意の ID を提供する。</li> + <li>{@code android:tag} 属性に一意の文字列を提供する。</li> + <li>上記のいずれも提供しない場合、システムはコンテナビューの ID を使用します。 +</li> + </ul> +</div> + </li> + + <li><b>または、既存の {@link android.view.ViewGroup} にプログラムを使用してフラグメントを追加します</b>。 +<p>アクティビティの実行中は、いつでもフラグメントをアクティビティ レイアウトに追加できます。必要なのは、フラグメントを配置する場所に {@link +android.view.ViewGroup} を指定するだけです。 +</p> + <p>アクティビティ内にフラグメントのトランザクション(フラグメントの追加、削除、置換など)を作るには、{@link android.app.FragmentTransaction} からの API を使用する必要があります。 +{@link android.app.FragmentTransaction} のインスタンスは、{@link android.app.Activity} から次のようにして取得できます。 +</p> + +<pre> +FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()} +FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()}; +</pre> + +<p>次に、{@link +android.app.FragmentTransaction#add(int,Fragment) add()} メソッドを使用して、追加するフラグメントと挿入するビューを指定してフラグメントを追加できます。 +次に例を示します。</p> + +<pre> +ExampleFragment fragment = new ExampleFragment(); +fragmentTransaction.add(R.id.fragment_container, fragment); +fragmentTransaction.commit(); +</pre> + + <p>{@link android.app.FragmentTransaction#add(int,Fragment) add()} に渡される最初の引数はフラグメントを配置する {@link android.view.ViewGroup} でリソース ID で指定されており、2 つ目のパラメータは追加するフラグメントです。 + +</p> + <p>{@link android.app.FragmentTransaction} で変更を加えたら、{@link android.app.FragmentTransaction#commit} を呼び出して変更を適用する必要があります。 + +</p> + </li> +</ul> + + +<h4 id="AddingWithoutUI">UI のないフラグメントを追加する</h4> + +<p>上の例では、UI を提供するためにフラグメントをアクティビティに追加する方法を紹介しましたが、UI を提示せずにアクティビティのバックグラウンド動作を提供するためにフラグメントを使うこともできます。 + +</p> + +<p>UI のないフラグメントを追加するには、{@link +android.app.FragmentTransaction#add(Fragment,String)} を使用してアクティビティからフラグメントを追加します(ビュー ID ではなくフラグメントの一意の文字列である「タグ」を提供します)。 +これでフラグメントが追加されますが、アクティビティ レイアウトのビューには関連付けられていないため、{@link +android.app.Fragment#onCreateView onCreateView()} への呼び出しは受け取りません。 +そのため、このメソッドを実装する必要はありません。</p> + +<p>フラグメントに文字列のタグを提供するのは UI のないフラグメントの場合だけではありません。UI のあるフラグメントにも文字列のタグを提供することはできますが、UI のないフラグメントにとっては、文字列のタグがフラグメントを識別する唯一の手段になります。— +— +後でアクティビティからフラグメントを取得する場合は、 {@link android.app.FragmentManager#findFragmentByTag +findFragmentByTag()} を使用する必要があります。 +</p> + +<p>たとえば、フラグメントを UI を持たないバックグラウンド ワーカーとして使用するアクティビティの場合は、SDK サンプルに含まれている(Android SDK マネージャーで利用可能){@code +FragmentRetainInstance.java} のサンプルでシステムに <code><sdk_root>/APIDemos/app/src/main/java/com/example/android/apis/app/FragmentRetainInstance.java</code> として置かれているものをご覧ください。 + +</p> + + + +<h2 id="Managing">フラグメントを管理する</h2> + +<p>アクティビティのフラグメントを管理するには、{@link android.app.FragmentManager} を使用する必要があります。フラグメントを取得するには、アクティビティから {@link android.app.Activity#getFragmentManager()} を呼び出します。 +</p> + +<p>{@link android.app.FragmentManager} では、次の操作が可能です。</p> + +<ul> + <li>{@link +android.app.FragmentManager#findFragmentById findFragmentById()}(アクティビティ レイアウトで UI を提供するフラグメントの場合)や {@link android.app.FragmentManager#findFragmentByTag +findFragmentByTag()}(UI を提供しないフラグメントの場合)を使用して、アクティビティにあるフラグメントを取得する。 +</li> + <li>{@link +android.app.FragmentManager#popBackStack()} を使用してフラグメントをバックスタックから取り出す(ユーザーによる [<em>戻る</em>] コマンドをシミュレートする)。</li> + <li>{@link +android.app.FragmentManager#addOnBackStackChangedListener addOnBackStackChangedListener()} を使用して、バックスタックの変更に対するリスナを登録する。</li> +</ul> + +<p>これらのメソッドや他のメソッドの詳細については、{@link +android.app.FragmentManager} クラスのドキュメントをご覧ください。</p> + +<p>前のセクションで説明したように、{@link android.app.FragmentManager} を使用して {@link android.app.FragmentTransaction} を開くことで、フラグメントの追加や削除といったトランザクションを実行することもできます。 + +</p> + + +<h2 id="Transactions">フラグメントのトランザクションを実行する</h2> + +<p>アクティビティでのフラグメントの使用における優れた機能として、フラグメントを追加、削除、置換したり、ユーザー操作への応答にフラグメントを使用して他のアクションを実行したりできる点が挙げられます。 +アクティビティに加える変更はそれぞれ 1 つのトランザクションとして、{@link +android.app.FragmentTransaction} の API を使用して実行できます。 +各トランザクションはアクティビティが管理するバックスタックに保存でき、ユーザーはフラグメントの変更を元に戻すことができます(アクティビティ間で元に戻す動作と似ています)。 + +</p> + +<p>{@link android.app.FragmentTransaction} のインスタンスは、次のように {@link +android.app.FragmentManager} から作成できます。</p> + +<pre> +FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()}; +FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()}; +</pre> + +<p>各トランザクションは、同時に実行する一連の変更点です。{@link +android.app.FragmentTransaction#add add()}、{@link android.app.FragmentTransaction#remove remove()}、{@link android.app.FragmentTransaction#replace replace()} などのメソッドを使って、トランザクションで実行するすべての変更点をセットアップできます。 + +次に、トランザクションをアクティビティに適用するには、{@link android.app.FragmentTransaction#commit()} を呼び出す必要があります。 +</p> +</dl> + +<p>ただし、{@link +android.app.FragmentTransaction#commit()} を呼び出す前に、{@link +android.app.FragmentTransaction#addToBackStack addToBackStack()} を呼び出して、フラグメントのトランザクションのバックスタックにトランザクションを追加することもできます。 +このバックスタックはアクティビティによって管理され、ユーザーが [<em>戻る</em>] ボタンを押して前のフラグメントの状態に戻れるようにします。 +</p> + +<p>例として、フラグメントを別のフラグメントに置き換えて、バックスタックで前の状態を保持する方法を次に示します。 +</p> + +<pre> +// Create new fragment and transaction +Fragment newFragment = new ExampleFragment(); +FragmentTransaction transaction = getFragmentManager().beginTransaction(); + +// Replace whatever is in the fragment_container view with this fragment, +// and add the transaction to the back stack +transaction.replace(R.id.fragment_container, newFragment); +transaction.addToBackStack(null); + +// Commit the transaction +transaction.commit(); +</pre> + +<p>この例では、{@code R.id.fragment_container} ID で識別されるレイアウト コンテナに現在あるフラグメント(存在する場合)を {@code newFragment} が置き換えます。{@link +android.app.FragmentTransaction#addToBackStack addToBackStack()} を呼び出すと、置き換えのトランザクションがバックスタックに保存されるため、ユーザーはトランザクションを元に戻して、[<em>戻る</em>] ボタンを押すことで前のフラグメントに戻れるようになります。 + + +</p> + +<p>トランザクションに複数の変更を加えて({@link +android.app.FragmentTransaction#add add()} や {@link android.app.FragmentTransaction#remove +remove()} など)、{@link +android.app.FragmentTransaction#addToBackStack addToBackStack()} を呼び出した場合、{@link android.app.FragmentTransaction#commit commit()} を呼び出す前に適用されたすべての変更点が 1 つのトランザクションとしてバックスタックに追加され、[<em>戻る</em>] ボタンを押すとすべてが同時に元に戻るようになります。 + +</p> + +<p>次の場合を除き、{@link android.app.FragmentTransaction} に加える変更の順序は影響しません。 +</p> +<ul> + <li>{@link android.app.FragmentTransaction#commit()} は最後に呼び出す必要があります。</li> + <li>複数のフラグメントを同じコンテナに追加する場合、追加する順序がビュー階層に表示される順序になります。 +</li> +</ul> + +<p>フラグメントを削除するトランザクションの実行時に {@link android.app.FragmentTransaction#addToBackStack(String) +addToBackStack()} を呼び出さない場合、トランザクションの実行時にそのフラグメントは破棄され、ユーザーは操作を元に戻すことができなくなります。 +一方で、フラグメントの削除時に {@link android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} を呼び出した場合、フラグメントは<em>停止</em>状態になり、ユーザーが元に戻した時に再開します。 + + +</p> + +<p class="note"><strong>ヒント:</strong> それぞれのフラグメントのトランザクションでは、コミットする前に {@link android.app.FragmentTransaction#setTransition setTransition()} と呼ばれる遷移のアニメーションを適用できます。 + +</p> + +<p>{@link android.app.FragmentTransaction#commit()} を呼び出してもトランザクションはすぐには実行されません。 +具体的には、アクティビティの UI スレッド(「メイン」スレッド)で実行可能になったときにすぐに実行されるようスケジュールされます。 +ただし、必要であれば UI スレッドから {@link +android.app.FragmentManager#executePendingTransactions()} を呼び出して、{@link android.app.FragmentTransaction#commit()} から送信されたトランザクションをすぐに実行することもできます。 +通常、トランザクションが他のスレッドのジョブに依存していない限り、この操作は必要ありません。 +</p> + +<p class="caution"><strong>警告:</strong> {@link +android.app.FragmentTransaction#commit commit()} を使用したトランザクションをコミットできるのは、アクティビティが<a href="{@docRoot}guide/components/activities.html#SavingActivityState">状態を保存</a>する前(ユーザーがアクティビティを離れるとき)にのみに限定されます。 +それ以降にコミットしようとすると、例外がスローされます。 +これは、アクティビティの復元が必要な場合に、コミット後のステータスが失われてしまう可能性があるためです。 +コミットが失われてもよい場合は、{@link +android.app.FragmentTransaction#commitAllowingStateLoss()} を使用します。</p> + + + + +<h2 id="CommunicatingWithActivity">アクティビティと通信する</h2> + +<p>{@link android.app.Fragment} が {@link android.app.Activity} から独立したフラグメントとして実行されていて、複数のアクティビティ内で使用可能であっても、フラグメントの特定のインスタンスは、それが含まれるアクティビティに直接結び付いています。 + +</p> + +<p>具体的には、フラグメントは {@link +android.app.Fragment#getActivity()} を使用して {@link android.app.Activity} インスタンスにアクセスでき、アクティビティのレイアウトでビューを見つけるなどのタスクを簡単に実行できます。 +</p> + +<pre> +View listView = {@link android.app.Fragment#getActivity()}.{@link android.app.Activity#findViewById findViewById}(R.id.list); +</pre> + +<p>同様に、アクティビティが {@link +android.app.FragmentManager#findFragmentById findFragmentById()} や {@link +android.app.FragmentManager#findFragmentByTag findFragmentByTag()} を使って {@link android.app.FragmentManager} から {@link android.app.Fragment} への参照を取得することで、フラグメント内のメソッドを呼び出すこともできます。 +次に例を示します。</p> + +<pre> +ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment); +</pre> + + +<h3 id="EventCallbacks">アクティビティへのイベント コールバックを作成する</h3> + +<p>アクティビティとイベントを共有するフラグメントが必要になる場面もあります。これを実現するには、フラグメント内でコールバック インターフェースを定義して、ホスト アクティビティがそれを実装するよう要求します。 + +アクティビティがインターフェースを介してコールバックを受け取ると、必要に応じてレイアウト内の他のフラグメントと情報を共有します。 +</p> + +<p>たとえば、新しいアプリケーションでアクティビティ内に、記事のリストを表示するフラグメント(フラグメント A)と、記事を表示するフラグメント(フラグメント B)の 2 つのフラグメントがある場合、リストのアイテムが選択されたときに、フラグメント B に記事を表示するよう伝えるため、フラグメント A から選択されたことをアクティビティに伝える必要があります。— +— +ここでは、{@code OnArticleSelectedListener} インターフェースがフラグメント A で宣言されています。 +</p> + +<pre> +public static class FragmentA extends ListFragment { + ... + // Container Activity must implement this interface + public interface OnArticleSelectedListener { + public void onArticleSelected(Uri articleUri); + } + ... +} +</pre> + +<p>次に、フラグメントのホストであるアクティビティが {@code OnArticleSelectedListener} インターフェースを実装して {@code onArticleSelected()} をオーバーライドし、フラグメント B にフラグメント A からのイベントを通知します。ホスト アクティビティがこのインターフェースを確実に実装するようにするため、フラグメント A の {@link +android.app.Fragment#onAttach onAttach()} コールバック メソッド(フラグメントをアクティビティに追加するときにシステムが呼び出すメソッド)が、{@link android.app.Fragment#onAttach +onAttach()} に渡される {@link android.app.Activity} をキャストして {@code OnArticleSelectedListener} のインスタンスを登録します。 + + + + +</p> + +<pre> +public static class FragmentA extends ListFragment { + OnArticleSelectedListener mListener; + ... + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mListener = (OnArticleSelectedListener) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener"); + } + } + ... +} +</pre> + +<p>アクティビティがインターフェースを実装していない場合は、フラグメントは {@link java.lang.ClassCastException} をスローします。成功すると、{@code mListener} メンバーがアクティビティの {@code OnArticleSelectedListener} の実装への参照を保持でき、フラグメント A が {@code OnArticleSelectedListener} インターフェースで定義されたコールバック メソッドを呼び出すことでアクティビティとイベントを共有できるようになります。 + + + +たとえば、フラグメント A は {@link android.app.ListFragment} の拡張で、ユーザーがリストアイテムをクリックするたびに、システムがフラグメントの {@link android.app.ListFragment#onListItemClick +onListItemClick()} を呼び出し、それが{@code onArticleSelected()} を呼び出してアクティビティとイベントを共有します。 + + +</p> + +<pre> +public static class FragmentA extends ListFragment { + OnArticleSelectedListener mListener; + ... + @Override + public void onListItemClick(ListView l, View v, int position, long id) { + // Append the clicked item's row ID with the content provider Uri + Uri noteUri = ContentUris.{@link android.content.ContentUris#withAppendedId withAppendedId}(ArticleColumns.CONTENT_URI, id); + // Send the event and Uri to the host activity + mListener.onArticleSelected(noteUri); + } + ... +} +</pre> + +<p>{@link +android.app.ListFragment#onListItemClick onListItemClick()} に渡される {@code id} パラメータはクリックされたアイテムの行 ID で、アクティビティ(または他のフラグメント)がアプリケーションの {@link +android.content.ContentProvider} から記事を取得する際に使用します。 +</p> + +<p><!--To see a complete implementation of this kind of callback interface, see the <a +href="{@docRoot}resources/samples/NotePad/index.html">NotePad sample</a>. -->コンテンツ プロバイダの使用に関する詳細については、「<a href="{@docRoot}guide/topics/providers/content-providers.html">コンテンツ プロバイダ</a>」のドキュメントをご覧ください。 +</p> + + + +<h3 id="ActionBar">アクションバーにアイテムを追加する</h3> + +<p>フラグメントは、{@link android.app.Fragment#onCreateOptionsMenu(Menu,MenuInflater) onCreateOptionsMenu()} を実装することでアクティビティの<a href="{@docRoot}guide/topics/ui/menus.html#options-menu">オプション メニュー</a>(とその<a href="{@docRoot}guide/topics/ui/actionbar.html">アクション バー</a>)にメニュー アイテムを提供することができます。 +ただし、このメソッドが呼び出しを受け取るには、{@link +android.app.Fragment#onCreate(Bundle) onCreate()} の間に {@link +android.app.Fragment#setHasOptionsMenu(boolean) setHasOptionsMenu()} を呼び出して、フラグメントがオプション メニューにアイテムを追加することを示す必要があります(これを行わない場合、フラグメントは {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()} への呼び出しを受け取りません)。 + + +</p> + +<p>フラグメントから追加するアイテムはすべて、既存のメニュー アイテムに追加されます。 +また、メニュー アイテムが選択されたとき、フラグメントは {@link +android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} へのコールバックも受け取ります。 +</p> + +<p>また、{@link +android.app.Fragment#registerForContextMenu(View) registerForContextMenu()} を呼び出して、フラグメントのレイアウトにビューを登録してコンテキスト メニューを提供することもできます。ユーザーがコンテキスト メニューを開くと、フラグメントは {@link +android.app.Fragment#onCreateContextMenu(ContextMenu,View,ContextMenu.ContextMenuInfo) +onCreateContextMenu()} への呼び出しを受け取ります。 +ユーザーがアイテムを選択すると、フラグメントは {@link +android.app.Fragment#onContextItemSelected(MenuItem) onContextItemSelected()} への呼び出しを受け取ります。</p> + +<p class="note"><strong>注:</strong> 追加するメニュー アイテムごとにフラグメントは on-item-selected コールバックを受け取りますが、ユーザーがメニュー アイテムを選択したときに最初にそれぞれのコールバックを受け取るのはアクティビティになります。 + +アクティビティの on-item-selected コールバックの実装で、選択されたアイテムが処理されなかった場合、イベントはフラグメントのコールバックに渡されます。 +この挙動は、オプション メニューとコンテキスト メニューの両方に適用されます。 +</p> + +<p>メニューの詳細については、デベロッパー ガイドの「<a href="{@docRoot}guide/topics/ui/menus.html">メニュー</a>」と「<a href="{@docRoot}guide/topics/ui/actionbar.html">アクションバー</a>」をご覧ください。</p> + + + + +<h2 id="Lifecycle">フラグメントのライフサイクルを処理する</h2> + +<div class="figure" style="width:350px"> +<img src="{@docRoot}images/activity_fragment_lifecycle.png" alt="" /> +<p class="img-caption"><strong>図 3.</strong> フラグメントのライフサイクルに対するアクティビティのライフサイクルの影響。 +</p> +</div> + +<p>フラグメントのライフサイクルの管理は、アクティビティのライフサイクルの管理によく似ています。アクティビティと同様に、フラグメントには次の 3 つの状態があります。 +</p> + +<dl> + <dt><i>再開状態</i></dt> + <dd>フラグメントが実行中のアクティビティで表示されている。</dd> + + <dt><i>一時停止状態</i></dt> + <dd>他のアクティビティがフォアグラウンドにあり、フォーカスがあるが、このアクティビティも表示されている(フォアグラウンドにある別のアクティビティは半透明になっているか、全画面をカバーしていない)。 + +</dd> + + <dt><i>停止状態</i></dt> + <dd>フラグメントは表示されていない。ホスト アクティビティが停止状態か、フラグメントがアクティビティから削除されたが、バックスタックに追加されている。 +停止状態のフラグメントはまだ存続しています(すべての状態とメンバー情報がシステムで保持されています)。 +ただし、アクティビティが破棄されるとユーザーには表示されなくなり、フラグメントも破棄されます。 +</dd> +</dl> + +<p>さらに、アクティビティと同様に、アクティビティのプロセスが破棄されて、アクティビティが再作成されたときにフラグメントの状態を復元する必要がある場合は、 {@link +android.os.Bundle} を使用してフラグメントの状態を保持できます。 +フラグメントの {@link +android.app.Fragment#onSaveInstanceState onSaveInstanceState()} コールバックの間に状態を保存して、{@link android.app.Fragment#onCreate onCreate()}、{@link +android.app.Fragment#onCreateView onCreateView()}、{@link +android.app.Fragment#onActivityCreated onActivityCreated()} の間にそれを復元できます。 +状態の保存の詳細については、「<a href="{@docRoot}guide/components/activities.html#SavingActivityState">Activities</a>」のドキュメントをご覧ください。 + +</p> + +<p>アクティビティとフラグメントのライフサイクルの最も重要な違いは、バックスタックでのそれぞれの保存方法です。 +アクティビティは、デフォルトで停止状態の時にシステムが管理するアクティビティのバックスタックに置かれますが(<a href="{@docRoot}guide/components/tasks-and-back-stack.html">タスクとバックスタック</a> で説明したようにユーザーが [<em>戻る</em>] ボタンで前に戻ることができるように)、フラグメントの場合は、フラグメントを削除するトランザクションの間に {@link +android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} を呼び出してインスタンスを保存するよう明示的に要求した場合のみ、ホスト アクティビティが管理するバックスタックに置かれます。 + + + + +</p> + +<p>これ以外については、フラグメントのライフサイクルの管理は、アクティビティのライフサイクルの管理とほとんど同じです。 +そのため、<a href="{@docRoot}guide/components/activities.html#Lifecycle">アクティビティのライフサイクルの管理</a>におけるベスト プラクティスがフラグメントにも適用されます。 +もう 1 つ理解しておくべき事項は、アクティビティの寿命がどのようにフラグメントの寿命に影響を与えるかという点です。 +</p> + +<p class="caution"><strong>警告:</strong> {@link android.app.Fragment} 内に {@link android.content.Context} オブジェクトが必要な場合は、{@link android.app.Fragment#getActivity()} を呼び出すことができます。ただし、{@link android.app.Fragment#getActivity()} はフラグメントがアクティビティにアタッチされている場合にのみ呼び出すようにしてください。 + + +フラグメントがまだアタッチされていない場合や、ライフサイクルの終了時にデタッチされた場合は、{@link android.app.Fragment#getActivity()} は null を返します。 +</p> + + +<h3 id="CoordinatingWithActivity">アクティビティのライフサイクルと連携する</h3> + +<p>フラグメントが含まれるアクティビティのライフサイクルは、フラグメントのライフサイクルに直接影響し、アクティビティに対する各ライフサイクル コールバックは、各フラグメントに対して同様のコールバックをもたらします。 + +たとえば、アクティビティが {@link android.app.Activity#onPause} を受け取ると、アクティビティ内の各フラグメントが {@link android.app.Fragment#onPause} を受け取ります。 +</p> + +<p>ただし、フラグメントにはフラグメントの UI をビルドしたり破棄したりするアクションを実行する際のアクティビティとの独自のやり取りを処理する追加のライフサイクル コールバックがいくつかあります。これらの追加のコールバック メソッドは次のとおりです。 + +</p> + +<dl> + <dt>{@link android.app.Fragment#onAttach onAttach()}</dt> + <dd>フラグメントがアクティビティと関連付けられたときに呼び出されます(ここで {@link +android.app.Activity} が渡されます)。</dd> + <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt> + <dd>フラグメントに関連付けられたビュー階層を作成する際に呼び出されます。</dd> + <dt>{@link android.app.Fragment#onActivityCreated onActivityCreated()}</dt> + <dd>アクティビティの {@link android.app.Activity#onCreate +onCreate()} メソッドが戻ったときに呼び出されます。</dd> + <dt>{@link android.app.Fragment#onDestroyView onDestroyView()}</dt> + <dd>フラグメントに関連付けられたビュー階層が削除されたときに呼び出されます。</dd> + <dt>{@link android.app.Fragment#onDetach onDetach()}</dt> + <dd>フラグメントとアクティビティとの関連付けが解除されたときに呼び出されます。</dd> +</dl> + +<p>図 3 は、ホスト アクティビティの影響を受けたフラグメントのライフサイクルのフローを表しています。 +この図から、アクティビティの一連の状態によって、フラグメントが受け取るコールバック メソッドがどのように決められているかがわかります。 +たとえば、アクティビティが {@link +android.app.Activity#onCreate onCreate()} コールバックを受け取ると、アクティビティ内のフラグメントは {@link android.app.Fragment#onActivityCreated onActivityCreated()} コールバックまでを受け取ります。 +</p> + +<p>アクティビティが再開状態になると、アクティビティでのフラグメントの追加や削除を自由に行えます。 +つまり、アクティビティが再開された状態が、フラグメントのライフサイクルを独立して変更できる唯一の期間になります。 +</p> + +<p>ただし、アクティビティが再開状態でなくなると、フラグメントはアクティビティによって再度ライフサイクル間を通過することになります。 +</p> + + + + +<h2 id="Example">例</h2> + +<p>このドキュメントで解説した内容をすべて網羅するため、2 つのフラグメントを使用して 2 つのペインのレイアウトを作成するアクティビティの例を紹介します。 +次のアクティビティには、シェイクスピア劇のタイトル リストを表示するフラグメントと、リストから劇が選択されたときに劇のあらすじを表示するフラグメントがあります。 + +また、ここでは画面構成によって異なるフラグメント構成を提供する方法も示しています。 +</p> + +<p class="note"><strong>注:</strong> このアクティビティのすべてのソース コードは、<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.html">{@code +FragmentLayout.java}</a> で入手できます。 +</p> + +<p>メイン アクティビティでは、通常の方法で {@link +android.app.Activity#onCreate onCreate()} の間にレイアウトを適用します。</p> + +{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java main} + +<p>適用されるレイアウトは {@code fragment_layout.xml} です。</p> + +{@sample development/samples/ApiDemos/res/layout-land/fragment_layout.xml layout} + +<p>このレイアウトを使って、アクティビティがレイアウトをロードするとすぐにシステムが {@code TitlesFragment}(これが劇のタイトルをリストします)のインスタンスを作成します。このとき、{@link android.widget.FrameLayout} (劇のあらすじを表示するフラグメントの目的地)が画面右側を使用し、残りは空白の状態です。 + + +ご覧のように、フラグメントが {@link android.widget.FrameLayout} に置かれるのはユーザーがアイテムを選択してからになります。 +</p> + +<p>ただし、画面構成によっては、劇の一覧とあらすじを横並びに表示するほどの幅がない場合もあります。 +そのため、上記のレイアウトは横方向の画面構成の場合のみ使用され、{@code res/layout-land/fragment_layout.xml} に保存されます。 +</p> + +<p>画面が縦方向の場合、システムは次のレイアウトを適用して {@code res/layout/fragment_layout.xml} に保存します。 +</p> + +{@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout} + +<p>このレイアウトには、{@code TitlesFragment} のみが含まれます。つまり、端末が縦方向の場合、劇のタイトルのみが表示されます。 +そのため、この構成時にユーザーがリストのアイテムをクリックしたとき、アプリケーションは 2 つ目のフラグメントをロードする代わりに新しいアクティビティを開始してあらすじを表示します。 + +</p> + +<p>次に、フラグメントのクラスでこれをどう実現するのかを見ていきます。まず、{@code +TitlesFragment} はシェイクスピア劇のタイトル リストを表示します。このフラグメントは {@link +android.app.ListFragment} を拡張し、リスト ビューの動作の処理のほとんどを委ねます。</p> + +<p>このコードをよく見ると、ユーザーがリストのアイテムをクリックしたときの挙動が 2 つ考えられます。2 つのレイアウトのどちらがアクティブになっているかによって、新しいフラグメントを作成して表示することで同じアクティビティで詳細を表示するか({@link +android.widget.FrameLayout} にフラグメントを追加する)、新しいアクティビティを(フラグメントを表示できる場所に)開始するかのいずれかになります。 + +</p> + +{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java titles} + +<p>2 つ目のフラグメントである {@code DetailsFragment} は、{@code TitlesFragment} のリストで選択された劇のあらすじを表示します。 +</p> + +{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java details} + +<p>{@code TitlesFragment} クラスで説明したように、ユーザーがリストアイテムをクリックしたときに、現在のレイアウトに{@code R.id.details} ビュー({@code DetailsFragment} が属する場所)が<em>含まれていない</em>場合、アプリケーションは {@code DetailsActivity} のアクティビティを開始してアイテムのコンテンツを表示します。 + + +</p> + +<p>次の {@code DetailsActivity} では、画面が縦方向のときに単純に {@code DetailsFragment} を埋め込んで選択された劇のあらすじを表示します。 +</p> + +{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java +details_activity} + +<p>構成が横方向の場合はアクティビティは自ら終了するため、メイン アクティビティが引き継いで {@code DetailsFragment} を {@code TitlesFragment} の横に表示できます。これは、ユーザーが縦方向のときに {@code DetailsActivity} を開始し、その後横方向に回転した(ここで現在のアクティビティが再開される)ときに起こることがあります。 + + +</p> + + +<p>フラグメントを使用したその他のサンプルとこの例の完全なソース ファイルについては、<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">ApiDemos</a>(<a href="{@docRoot}resources/samples/get.html">SDK コンポーネントのサンプル</a>から入手可能)にある API デモサンプルをご覧ください。 + +</p> + + diff --git a/docs/html-intl/intl/ja/guide/components/fundamentals.jd b/docs/html-intl/intl/ja/guide/components/fundamentals.jd new file mode 100644 index 000000000000..46e98689a3ec --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/fundamentals.jd @@ -0,0 +1,480 @@ +page.title=アプリケーションの基礎 +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>本書の内容</h2> +<ol> +<li><a href="#Components">アプリのコンポーネント</a> + <ol> + <li><a href="#ActivatingComponents">コンポーネントをアクティベートする</a></li> + </ol> +</li> +<li><a href="#Manifest">マニフェスト ファイル</a> + <ol> + <li><a href="#DeclaringComponents">コンポーネントを宣言する</a></li> + <li><a href="#DeclaringRequirements">アプリの要件を宣言する</a></li> + </ol> +</li> +<li><a href="#Resources">アプリのリソース</a></li> +</ol> +</div> +</div> + +<p>Android アプリは Java プログラミング言語で記述されています。APKAndroid SDK ツールがコードを—データとリソース ファイルと共に、 +—APK <i>(Android パッケージ)にコンパイルします。</i>これは、 +{@code .apk} という接尾語の付いたアーカイブ ファイルです。1 つの APK ファイルにはAndroid アプリのすべてのコンテンツが含まれており、Android 端末はアプリをインストールする際にこのファイルを使用します。 +</p> + +<p>端末にインストールすると、各 Android アプリはそれぞれのセキュリティ サンドボックス内で動作します。 </p> + +<ul> + <li>Android オペレーティング システムはマルチユーザーの Linux システムであり、各アプリが異なるユーザーになります。 +</li> + +<li>デフォルトで、システムは各アプリに一意の Linux ユーザー ID を割り当てます(ID はシステムのみが使用し、アプリは ID を関知しません)。 +アプリが割り当てられたユーザー ID のみがアプリ内のすべてのファイルにアクセスできるよう、システムがパーミッションを設定します。 + </li> + +<li>各プロセスにはそれぞれ独自の仮想マシン(VM)があるため、アプリのコードは他のアプリとは分離して実行します。 +</li> + +<li>デフォルトで、すべてのアプリは独自の Linux プロセス上で実行します。Android はアプリのコンポーネントのいずれかを実行する必要があるときにプロセスを開始し、それが必要なくなったときや、システムが他のアプリ用にメモリを回復させる必要があるときにプロセスをシャットダウンします。 + +</li> +</ul> + +<p>このようにして、Android システムは<em>最小権限の原則</em>を実装しています。つまり、デフォルトでは各アプリにはコンポーネントの動作に必要な分だけのアクセス権が与えられます。 + +これにより、パーミッションの与えられていないシステムの一部にアプリはアクセスできないという非常に安全性の高い環境が作り出されます。 +</p> + +<p>ただし、アプリが他のアプリとデータを共有したり、システムのサービスにアクセスしたりする方法もあります。 +</p> + +<ul> + <li>2 つのアプリで同一の Linux ユーザー ID を共有して、お互いのファイルにアクセスできるようにすることも可能です。 +システム リソースを節約するため、同じユーザー ID を持つアプリを同じ Linux プロセス上で実行し、同じ VM を共有するよう設定することもできます(アプリを同じ証明書で署名する必要があります)。 + +</li> + <li>アプリから、ユーザーの連絡先、SMS メッセージ、マウント可能なストレージ(SD カード)、カメラ、Bluetooth といった端末データにアクセスするためのパーミッションを要求できます。 +アプリのすべてのパーミッションは、インストール時にユーザーから付与される必要があります。 +</li> +</ul> + +<p>以上が、システム内の Android アプリの基本的な仕組みです。続いて、このドキュメントでは次の内容について説明します。 +</p> +<ul> + <li>アプリを定義するコア フレームワーク コンポーネント。</li> + <li>コンポーネントを宣言し、アプリの端末機能に必要なマニフェスト ファイル。 +</li> + <li>アプリでさまざまな端末構成の動作を最適化できるようにする、アプリコードから分離されたリソース。 +</li> +</ul> + + + +<h2 id="Components">アプリのコンポーネント</h2> + +<p>アプリのコンポーネントは、Android アプリに不可欠な構成要素です。各コンポーネントは、システムがアプリにアクセスするためのさまざまなエントリ ポイントになります。すべてのコンポーネントがユーザーの実際のエントリ ポイントになるわけではなく、中にはお互いに依存関係にあるものもありますが、それぞれが独自のエンティティとして存在し、特定の役割を担っています。各コンポーネントはアプリの全体的な動作を定義する固有の構成要素となっています。 + + +— +</p> + +<p>アプリのコンポーネントには、4 つのタイプがあります。それぞれのタイプは、まったく異なる目的を果たし、コンポーネントの作成や破棄方法を定義するライフサイクルもそれぞれ異なります。 +</p> + +<p>アプリのコンポーネントのタイプは次の 4 つです。</p> + +<dl> + +<dt><b>アクティビティ</b></dt> + +<dd>アクティビティ <i>は</i> 1 つのユーザー インターフェースで 1 つの画面を表すものです。たとえば、メール アプリには新着メールの一覧を表示する 1 つのアクティビティと、メールを作成するアクティビティ、メールを閲覧するアクティビティがそれぞれ別にあります。 + +メールアプリでは、複数のアクティビティが一体となって結合したユーザー操作を実現しますが、それぞれは他のものから独立しています。 + +それにより、別のアプリで複数のアクティビティの中から、1 つのアクティビティを開始できるようになります(メールアプリが許可している場合)。 +たとえば、カメラアプリでは写真を他のユーザーと共有するために、メール アプリの新規メールを作成するアクティビティを開始できます。 + + +<p>アクティビティは {@link android.app.Activity} のサブクラスとして実装されます。詳細については、デベロッパー ガイドの「<a href="{@docRoot}guide/components/activities.html">Activities</a>」をご覧ください。 + +</p> +</dd> + + +<dt><b>サービス</b></dt> + +<dd>サービス <i>は、</i> 長期間の操作やリモート プロセスを処理するためにバックグラウンドで実行するコンポーネントです。 +サービスは、ユーザー インターフェースを提供しません。 +たとえば、サービスはユーザーが別のアプリを使用している間にバックグラウンドで音楽を再生したり、ユーザーが別のアクティビティを操作している間にそれを妨げることなくネットワークからデータを取得したりします。 + +アクティビティなどの別のコンポーネントは、サービスを開始して実行したり、それをバインドしたりして操作することもできます。 + + +<p>サービスは {@link android.app.Service} のサブクラスとして実装されます。詳細については、デベロッパー ガイドの「<a href="{@docRoot}guide/components/services.html">サービス</a>」をご覧ください。 + +</p> +</dd> + + +<dt><b>コンテンツ プロバイダ</b></dt> + +<dd>コンテンツ プロバイダ <i>は</i> 共有されているアプリデータを管理します。データは、ファイル システム、SQLite データベース、ウェブ、アプリがアクセスできる、あらゆる永続性のストレージに保存できます。 + +コンテンツ プロバイダを介して、他のアプリがデータをクエリしたり、修正したりすることもできます(コンテンツ プロバイダが許可している場合)。 +たとえば、Android システムではユーザーの連絡先情報を管理するコンテンツ プロバイダを提供しています。 +このように、適切なパーミッションさえあれば、アプリからコンテンツ プロバイダの一部({@link +android.provider.ContactsContract.Data}など)に問い合わせて、特定の人物に関する情報を読み取ったり書き込んだりできます。 + + +<p>コンテンツ プロバイダは、アプリで非公開扱いの共有されていないデータを閲覧したり書き込んだりする場合にも役立ちます。 +たとえば、<a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> のサンプル アプリでは、コンテンツ プロバイダを使用してメモを保存します。 +</p> + +<p>コンテンツ プロバイダは {@link android.content.ContentProvider} のサブクラスとして実装され、他のアプリがトランザクションを実行できるようにする API の標準セットを実装する必要があります。 + +詳細については、デベロッパー ガイドの「<a href="{@docRoot}guide/topics/providers/content-providers.html">Contetns Providers</a>」をご覧ください。 +</p> +</dd> + + +<dt><b>ブロードキャスト レシーバー</b></dt> + +<dd>ブロードキャスト レシーバー <i>は</i> システム全体のブロードキャスト アナウンスに応答するコンポーネントです。 +たとえば、画面がオフになった、バッテリ残量が低い、写真が撮影されたなど、システムに起因するブロードキャストはたくさんあります。アプリでもブロードキャストを開始でき、たとえば他のアプリに、一部のデータが端末にダウンロードされ、利用可能になったことを伝えることもできます。— + +— +ブロードキャスト レシーバーがユーザー インターフェースを表示することはありませんが、<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">ステータスバー通知を作成</a>して、ブロードキャスト イベントの発生時にユーザーに警告できます。 + +一般的には、ブロードキャスト レシーバーは他のコンポーネントへの単なる「入り口」であり、最小限の操作を行うことが前提となっています。 +たとえば、イベントに基づいた何らかの作業を実行するサービスを開始する場合などに適しています。 + + +<p>ブロードキャスト レシーバーは、{@link android.content.BroadcastReceiver} のサブクラスとして実装され、各ブロードキャストは {@link android.content.Intent} オブジェクトとして配信されます。 +詳細については、{@link android.content.BroadcastReceiver} クラスをご覧ください。 +</p> +</dd> + +</dl> + + + +<p>Android ならではのシステムデザインによって、どのアプリケーションからでも別のアプリケーションを開始できます。 +たとえば、ユーザーが端末のカメラで写真を撮影できるようにする場合、既にその機能を備えた別のアプリがあることを想定して、写真を撮影するアクティビティを自身で開発する代わりに、アプリがそれを使用できます。 + +カメラアプリを組み込んだり、コードにリンクしたりする必要もなく、単純に写真を撮影するカメラアプリのアクティビティを開始するだけです。 + + +完了後、写真はアプリに戻り、それを使用することもできます。ユーザー側には、カメラがアプリの一部であるかのように見えます。 +</p> + +<p>システムがコンポーネントを開始すると、そのアプリのプロセスを開始し(まだ実行していない場合)、コンポーネントが必要とするクラスをインスタンス化します。 +たとえば、アプリで写真を撮影するカメラアプリのアクティビティを開始すると、そのアクティビティはアプリのプロセスではなく、カメラアプリのプロセスで実行します。そのため、他のシステムのアプリとは異なり、Android アプリのエントリ ポイントは 1 つではありません(たとえば、{@code main()} 関数はありません)。 + + + +</p> + +<p>システムは、他のアプリへのアクセスを制限するファイル許可を使用して各アプリを別々のプロセスで実行するため、アプリから直接他のアプリのコンポーネントはアクティベートできませんが、Android システムはそれが可能です。 + +そのため、他のアプリのコンポーネントをアクティベートするには、特定のコンポーネントを開始する<em>インテント</em>を指定するメッセージをシステムに配信する必要があります。 + +その後、システムが代わりにコンポーネントをアクティベートします。</p> + + +<h3 id="ActivatingComponents">コンポーネントをアクティベートする</h3> + +<p>4 つのコンポーネント タイプのなかで、アクティビティ、サービス、ブロードキャスト レシーバーの 3 つは、<em>インテント</em>と呼ばれる非同期メッセージによってアクティベートされます。コンポーネントがアプリに属していても他のものに属していても、インテントにより実行時に個別のコンポーネントがお互いに結び付けられます(他のコンポーネントからのアクションを要求するメッセンジャーのようなものです)。—— + + + +</p> + +<p>インテントは {@link android.content.Intent} オブジェクトを使用して作成されます。このオブジェクトは特定のコンポーネントや特定の<em>タイプ</em>のコンポーネントをアクティベートするようにメッセージを定義します。インテントはそれぞれ明示的、暗黙的のいずれかになります。— + +</p> + +<p>アクティビティとサービスでは、インテントが実行するアクション(「閲覧」したり「送信」したりする)を定義し、操作に使うデータ(特に、開始されるコンポーネントが知っておく必要があるデータ)の URI を指定することもできます。 + +たとえば、インテントはアクティビティに画像を表示したり、ウェブページを開いたりするアクティビティに対して要求を伝達します。 +場合によっては、結果を受け取るアクティビティを開始でき、この場合にアクティビティが返す結果も {@link android.content.Intent} になります(たとえば、ユーザーが個人の連絡先を取り出し、それを返してくれるインテントを発行できます。返されたインテントには選択された連絡先を指す URI が含まれています)。 +— + + +</p> + +<p>ブロードキャスト レシーバーの場合、インテントは単純にブロードキャストするアナウンスを定義します(たとえば、端末のバッテリ残量が少ないことを示すブロードキャストには、「バッテリが少ない」ことを示す既知のアクション文字列が含まれます)。 + +</p> + +<p>他のコンポーネント タイプであるコンテンツ プロバイダは、インテントではアクティベートされず、{@link android.content.ContentResolver} からの要求の対象となったときにアクティベートされます。 +コンテンツリゾルバが、コンテンツプロバイダを使ってすべてのトランザクションを直接処理することで、プロバイダを使ってトランザクションを実行しているコンポーネントは処理する必要がなくなり、代わりに {@link +android.content.ContentResolver} オブジェクトのメソッドを呼び出します。 + +これによりコンテンツ プロバイダと情報を要求しているコンポーネントとの間に(セキュリティ目的で)抽象的な層ができます。 +</p> + +<p>各コンポーネント タイプのアクティベート用に、個別のメソッドが用意されています。</p> +<ul> + <li>アクティビティを開始する(または新しい作業を与える)場合は、{@link android.content.Intent} を {@link android.content.Context#startActivity +startActivity()} や {@link android.app.Activity#startActivityForResult startActivityForResult()} (アクティビティに結果を求める場合)に渡します。 + +</li> + <li>サービスを開始する(または継続中のサービスに新しい指示を与える)には、{@link android.content.Intent} を {@link android.content.Context#startService +startService()} に渡します。 +または、{@link android.content.Intent} を {@link android.content.Context#bindService bindService()} に渡してサービスにバインドできます。 +</li> + <li>ブロードキャストを開始するには、{@link android.content.Intent} を {@link android.content.Context#sendBroadcast(Intent) sendBroadcast()}、{@link +android.content.Context#sendOrderedBroadcast(Intent, String) sendOrderedBroadcast()}、{@link +android.content.Context#sendStickyBroadcast sendStickyBroadcast()} などのメソッドに渡します。 +</li> + <li>コンテンツ プロバイダへのクエリを実行するには、{@link android.content.ContentResolver} の {@link +android.content.ContentProvider#query query()} を呼び出します。</li> +</ul> + +<p>インテントの使用に関する詳細については、「<a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a>」のドキュメントをご覧ください。 +特定のコンポーネントのアクティベートの詳細については、 +<a href="{@docRoot}guide/components/activities.html">アクティビティ</a>、<a href="{@docRoot}guide/components/services.html">サービス</a>、{@link +android.content.BroadcastReceiver}、<a href="{@docRoot}guide/topics/providers/content-providers.html">コンテンツ プロバイダ</a> のドキュメントでも説明しています。</p> + + +<h2 id="Manifest">マニフェスト ファイル</h2> + +<p>Android システムがコンポーネントを開始する前に、システムはアプリの {@code AndroidManifest.xml} ファイル(「マニフェスト」ファイル)を読み取って、コンポーネントの存在を認識する必要があります。 + +アプリはこのファイルですべてのコンポーネントを宣言し、このファイルはアプリ プロジェクトのディレクトリのルートに置く必要があります。 +</p> + +<p>マニフェストはアプリのコンポーネントを宣言する他にも、次のようにさまざまな役割があります。 +</p> +<ul> + <li>インターネット アクセスや、ユーザーの連絡先への読み取りアクセスなど、アプリに必要なユーザー パーミッションを識別する。 +</li> + <li>アプリが使用する API に基づいた、アプリが必要とする最小 <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API レベル</a>を宣言する。 +</li> + <li>カメラ、Bluetooth サービス、マルチタッチ スクリーンなど、アプリで使用されるか必要とされるハードウェア機能やソフトウェア機能を宣言する。 +</li> + <li><a href="http://code.google.com/android/add-ons/google-apis/maps-overview.html">Google マップ ライブラリ</a>など、アプリにリンクする必要のある API ライブラリ(Android フレームワーク API は除く)。 + +</li> + <li>その他の役割</li> +</ul> + + +<h3 id="DeclaringComponents">コンポーネントを宣言する</h3> + +<p>マニフェストの主なタスクは、システムにアプリ コンポーネントに関する情報を与えることです。たとえば、マニフェスト ファイルではアクティビティを次のように宣言できます。 + </p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<manifest ... > + <application android:icon="@drawable/app_icon.png" ... > + <activity android:name="com.example.project.ExampleActivity" + android:label="@string/example_label" ... > + </activity> + ... + </application> +</manifest></pre> + +<p><code><a +href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> 要素では、{@code android:icon} 属性でアプリを特定するアイコンのリソースを指します。 + +</p> + +<p><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 要素では、{@code android:name} 属性で{@link +android.app.Activity} サブクラスの完全修飾k裏スパイウェア名を指定し、{@code android:label} 属性でアクティビティのユーザーに表示するラベルとして使用する文字列を指定しています。 + +</p> + +<p>すべてのアプリ コンポーネントは、次の方法で宣言する必要があります。</p> +<ul> + <li><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> アクティビティ用の要素 +</li> + <li><code><a +href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code> サービス用の要素 +</li> + <li><code><a +href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code> ブロードキャスト レシーバー用の要素 +</li> + <li><code><a +href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code> コンテンツ プロバイダ用の要素 +</li> +</ul> + +<p>ソースに含まれていながら、マニフェスト ファイルでは定義されていないアクティビティ、サービス、コンテンツ プロバイダはシステムには見えないため、実行されることはありません。 +ただし、ブロードキャスト レシーバーはマニフェストで宣言するか、コードで動的に作成({@link android.content.BroadcastReceiver} オブジェクトとして)して {@link android.content.Context#registerReceiver registerReceiver()} を呼び出すことでシステムに登録できます。 + + + +</p> + +<p>アプリのマニフェスト ファイルの構築方法の詳細については、「<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml File</a>」のドキュメントをご覧ください。 + </p> + + + +<h3 id="DeclaringComponentCapabilities">コンポーネントの機能を宣言する</h3> + +<p><a href="#ActivatingComponents">コンポーネントをアクティベートする</a>で説明したように、{@link android.content.Intent} を使用してアクティビティ、サービス、ブロードキャスト レシーバーを開始できます。 +開始するには、インテントでターゲットのコンポーネントの名前を(コンポーネントのクラス名を使って)明示的に指定する必要があります。 +ただし、インテントの本来の能力は、<em>暗黙的インテント</em>の概念にあります。 +暗黙的インテントは、単に実行するアクションのタイプを記述し(どのデータ上でアクションを実行するかも任意で記述できます)、それによりシステムがそのアクションを実行できる端末上のコンポーネントを見つけて開始できます。 + + +インテントで記述されたアクションを実行できるコンポーネントが複数ある場合は、使用するコンポーネントを 1 つ選択できます。 +</p> + +<p>システムは、端末の他のアプリのマニフェスト ファイルに提供されたインテント フィルタが受け取った + <i>インテントを比較して、</i> インテントに応答できるコンポーネントを識別します。 +</p> + +<p>アプリのマニフェストでアクティビティを宣言するとき、任意でアクティビティの機能を宣言するインテント フィルタを含めて、他のアプリからのインテントに応答できるようにできます。 + +<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> 要素を、コンポーネントを宣言している要素の子として追加することで、コンポーネントのインテント フィルタを宣言できます。 +</p> + +<p>たとえば、新規メールを作成するアクティビティを持つメールアプリをビルドした場合、次のように「送信」インテント(新規メールを送信するための)に応答するインテント フィルタを宣言できます。 +</p> +<pre> +<manifest ... > + ... + <application ... > + <activity android:name="com.example.project.ComposeEmailActivity"> + <intent-filter> + <action android:name="android.intent.action.SEND" /> + <data android:type="*/*" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + </application> +</manifest> +</pre> + +<p>次に、別のアプリが {@link +android.content.Intent#ACTION_SEND} アクションを持つインテントを作成し、{@link android.app.Activity#startActivity +startActivity()} に渡す場合、ユーザーがメールを下書きして送信できるよう、システムがアクティビティを開始する場合があります。 +</p> + +<p>インテント フィルタの作成の詳細については、「<a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a>」のドキュメントをご覧ください。 +</p> + + + +<h3 id="DeclaringRequirements">アプリの要件を宣言する</h3> + +<p>Android が搭載された端末は数多くありますが、すべての端末が同じ機能や性能を備えているわけではありません。 +アプリに必要な機能を搭載していない端末にアプリをインストールしてしまわないよう、アプリがサポートする端末のタイプについてプロファイルで明確に定義し、マニフェスト ファイルで端末の要件やソフトウェア要件を宣言しておくことが重要です。 + + +これらの宣言のほとんどはただの情報で、システムがそれを読み取ることはありませんが、Google Play などの外部サービスはそれを読み取って、ユーザーが端末からアプリを検索したときにフィルタを提供します。 + +</p> + +<p>たとえば、アプリでカメラを使用する必要があり、Android 2.1 で採用された API(<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API レベル</a> 7)を使用する場合、次のようにマニフェスト ファイルでそれを要件として宣言する必要があります。 +</p> + +<pre> +<manifest ... > + <uses-feature android:name="android.hardware.camera.any" + android:required="true" /> + <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" /> + ... +</manifest> +</pre> + +<p>カメラの<em>ない</em>端末で、Android バージョンが 2.1 <em>以下</em>の場合は、Google Play からアプリをインストールできません。 +</p> + +<p>ただし、アプリでカメラを使用するが、それが<em>必須</em>ではないということを宣言することもできます。 +この場合、アプリで <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#required">{@code required}</a> 属性を {@code "false"} に設定し、端末にカメラがあるかどうかを実行時に確認して、必要に応じてすべてのカメラ機能を無効にする必要があります。 + +</p> + +<p>異なる端末でのアプリの互換性を管理する方法については、「<a href="{@docRoot}guide/practices/compatibility.html">Device Compatibility</a>」をご覧ください。 + +</p> + + + +<h2 id="Resources">アプリのリソース</h2> + +<p>Android アプリは、コードだけで構成されているわけではありません。ソース コードから分離された画像、オーディオ ファイル、その他アプリの外観に関連するあらゆるリソースが必要です。たとえば、アクティビティのアニメーション、メニュー、スタイル、色、レイアウトなどを XML ファイルで定義する必要があります。— + + +アプリのリソースを使用すると、コードを修正することなく別のリソースセットを提供することで、アプリのあらゆる特性を簡単にアップデートできるようになります。これにより、さまざまな端末の設定用(別の言語や画面サイズなど)にアプリを最適化できます。 +— +— +</p> + +<p>Android プロジェクトに含めるすべてのリソースに対し、SDK ビルド ツールが一意の整数 ID を定義し、アプリコードや XML で定義された他のリソースからリソースにそれを使って参照できます。 + +たとえば、アプリに {@code +logo.png} という名前の画像ファイルがある場合({@code res/drawable/} ディレクトリ内に保存)、SDK ツールが {@code R.drawable.logo} という名前のリソース ID を生成し、これを使って画像を参照してユーザー インターフェースに挿入できます。 + +</p> + +<p>リソースとソース コードを分離して提供する方法の最も重要な側面は、さまざまな端末設定に合わせて別のリソースを提供できるという点です。 + +たとえば、XML で UI 文字列を定義することで、その文字列を他の言語に翻訳して、それらの文字列を別のファイルに保存しておくことができます。 +それを、リソースのディレクトリ名に付けた言語の<em>修飾子</em>(フランス語の文字列値なら {@code res/values-fr/} のように)とユーザーの言語設定に基づいて、Android システムによって UI に適切な言語の文字列が適用されます。 + + +</p> + +<p>Android では代替リソース用に多様な<em>修飾子</em>をサポートしています。修飾子は、リソースのディレクトリ名に含める短い文字列で、そのリソースを使用する端末構成を定義するものです。 + +例をもう 1 つ挙げると、端末の画面の向きやサイズによって、アクティビティのレイアウトを複数作成する必要があります。 + +たとえば、端末が縦方向(縦長)の場合、ボタンの付いたレイアウトを縦に並べ、端末が横方向(横長)の場合はボタンを横並びにする、といった場合です。 + +画面の方向によってレイアウトを変更するには、2 つの異なるレイアウトを定義して、それぞれのレイアウトのディレクトリ名に適切な修飾子を適用します。 + +そうすることで、現在の端末の向きによってシステムが自動的に適切なレイアウトを適用できます。 +</p> + +<p>アプリケーションに含めることのできるリソースの種類や、異なる端末設定用の代替リソースの作成方法については、「<a href="{@docRoot}guide/topics/resources/providing-resources.html">リソースの提供</a>」をご覧ください。 +</p> + + + +<div class="next-docs"> +<div class="col-6"> + <h2 class="norule">こちらもご覧ください。</h2> + <dl> + <dt><a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a> + </dt> + <dd>{@link android.content.Intent} API を使用して、アクティビティやサービスなどのアプリのコンポーネントをアクティベートする方法や、アプリのコンポーネントを他のアプリで利用できるようにする方法について説明しています。 + +</dd> + <dt><a href="{@docRoot}guide/components/activities.html">Activities</a></dt> + <dd>ユーザー インターフェースを使って独特のアプリケーション画面を提供する {@link android.app.Activity} + クラスのインスタンスの作成方法について説明しています。</dd> + <dt><a href="{@docRoot}guide/topics/resources/providing-resources.html">リソースの提供</a></dt> + <dd>特定の端末構成に対して代替リソースを提供する方法など、Android アプリでアプリのリソースをアプリコードから分離する仕組みについて説明しています。 + + + </dd> + </dl> +</div> +<div class="col-6"> + <h2 class="norule">関連ドキュメント</h2> + <dl> + <dt><a href="{@docRoot}guide/practices/compatibility.html">Device Compatibility</a></dt> + <dd>あらゆるタイプの端末での Android の動作と、端末ごとにアプリを最適化したり、別の端末でのアプリの利用を制限したりする方法について説明しています。 + +</dd> + <dt><a href="{@docRoot}guide/topics/security/permissions.html">System Permissions</a></dt> + <dd>アプリが特定の API を使用するのにユーザーの同意を必要とするパーミッション システムを使用して、アプリから特定の API へのアクセスを Android が制限する仕組みについて説明しています。 +</dd> + </dl> +</div> +</div> + diff --git a/docs/html-intl/intl/ja/guide/components/index.jd b/docs/html-intl/intl/ja/guide/components/index.jd new file mode 100644 index 000000000000..803f99b2ebd2 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/index.jd @@ -0,0 +1,57 @@ +page.title=アプリ<br>コンポーネント +page.landing=true +page.landing.intro=Android のアプリケーション フレームワークでは、再利用可能なコンポーネント セットを使用して豊富な内容を備えた斬新なアプリを作成できます。このセクションでは、アプリの構成要素を定義するコンポーネントのビルド方法と、インテントを使用してそれらをつなぎ合わせる方法について説明します。 +page.metaDescription=Android のアプリケーション フレームワークでは、再利用可能なコンポーネント セットを使用して豊富な内容を備えた斬新なアプリを作成できます。このセクションでは、アプリの構成要素を定義するコンポーネントのビルド方法と、インテントを使用してそれらをつなぎ合わせる方法について説明します。 +page.landing.image=images/develop/app_components.png +page.image=images/develop/app_components.png + +@jd:body + +<div class="landing-docs"> + + <div class="col-6"> + <h3>ブログの記事</h3> + + <a href="http://android-developers.blogspot.com/2012/05/using-dialogfragments.html"> + <h4>DialogFragments の使用</h4> + <p>この投稿では、DialogFragments を v4 サポート ライブラリで使用して(Honeycomb 以前の端末での下方互換性のため)ダイアログを編集したり、インターフェースを使用して呼び出し元の Activity に結果を返したりする方法について説明します。</p> + </a> + + <a href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html"> + <h4>すべてに Fragments を</h4> + <p>本日、同じ Fragments API を利用できる静的なライブラリが公開され、Android 1.6 以降でもフラグメントを使用してタブレット対応のユーザー インターフェースを作成できるようになりました。 </p> + </a> + + <a href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html"> + <h4>マルチスレッドでパフォーマンス向上</h4> + <p>応答の速いアプリケーションを作成する上で重要なのは、メイン UI スレッドが最小限の作業を行うようにすることです。 +アプリケーションのハングにつながる可能性のある長期的なタスクは、別のスレッドで処理するようにします。 +</p> + </a> + </div> + + <div class="col-6"> + <h3>トレーニング</h3> + + <a href="http://developer.android.com/training/basics/activity-lifecycle/index.html"> + <h4>アクティビティのライフサイクルの管理</h4> + <p>このレッスンでは、各 Activity インスタンスが受け取る重要なライフサイクル コールバック メソッドについて、それらを使用してユーザーの予期する内容でアクティビティを動作させる方法と、アクティビティがそれらを必要としないときに、システムのリソースを消費しないようにする方法について学習します。 + +</p> + </a> + + <a href="http://developer.android.com/training/basics/fragments/index.html"> + <h4>フラグメントで動的 UI を構築</h4> + <p>このレッスンでは、Android 1.6 以降の旧バージョンを実行する端末に対応しながら、フラグメントを使用して動きのある使用感を実現し、異なる画面サイズでのアプリの操作感を最適化する方法について説明します。 + +</p> + </a> + + <a href="http://developer.android.com/training/sharing/index.html"> + <h4>コンテンツの共有</h4> + <p>このレッスンでは、Intent API と ActionProvider オブジェクトを使用して、アプリケーション間でコンテンツを送受信する際の一般的な方法について説明します。 +</p> + </a> + </div> + +</div> diff --git a/docs/html-intl/intl/ja/guide/components/intents-filters.jd b/docs/html-intl/intl/ja/guide/components/intents-filters.jd new file mode 100644 index 000000000000..fe78eca74f24 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/intents-filters.jd @@ -0,0 +1,899 @@ +page.title=インテントとインテント フィルタ +page.tags="IntentFilter" +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>本書の内容</h2> +<ol> + <li><a href="#Types">インテントのタイプ</a></li> + <li><a href="#Building">インテントを作成する</a> + <ol> + <li><a href="#ExampleExplicit">明示的インテントの例</a></li> + <li><a href="#ExampleSend">暗黙的インテントの例</a></li> + <li><a href="#ForceChooser">アプリチューザを表示する</a></li> + </ol> + </li> + <li><a href="#Receiving">暗黙的インテントを受け取る</a> + <ol> + <li><a href="#ExampleFilters">フィルタの例</a></li> + </ol> + </li> + <li><a href="#PendingIntent">ペンディング インテントを使用する</a></li> + <li><a href="#Resolution">インテント解決</a> + <ol> + <li><a href="#ActionTest">アクションのテスト</a></li> + <li><a href="#CategoryTest">カテゴリのテスト</a></li> + <li><a href="#DataTest">データのテスト</a></li> + <li><a href="#imatch">インテントのマッチング</a></li> + </ol> + </li> +</ol> + +<h2>関連ドキュメント</h2> +<ol> +<li><a href="{@docRoot}training/basics/intents/index.html">Interacting with Other Apps</a></li> +<li><a href="{@docRoot}training/sharing/index.html">Sharing Content</a></li> +</ol> + +</div> +</div> + + + + +<p>{@link android.content.Intent} は、他の<a href="{@docRoot}guide/components/fundamentals.html#Components">アプリ コンポーネント</a>からのアクションを要求するときに使用するメッセージング オブジェクトです。インテントを使用することでコンポーネント間の通信を促進する方法はいくつかありますが、基本的な使用例は次の 3 つです。 + + +</p> + +<ul> +<li><b>アクティビティを開始するには:</b> +<p>{@link android.app.Activity} はアプリ内の 1 つの画面を表します。{@link android.app.Activity} の新しいインスタンスを開始するには、{@link android.content.Intent} を {@link android.content.Context#startActivity startActivity()} に渡します。 + +{@link android.content.Intent} は、開始するアクティビティを記述し、必要なデータすべてを含んでいます。 +</p> + +<p>アクティビティの完了時に結果を受け取る場合は、{@link android.app.Activity#startActivityForResult +startActivityForResult()} を呼び出します。 +アクティビティは、結果を別の {@link android.content.Intent} オブジェクトとして、アクティビティの {@link +android.app.Activity#onActivityResult onActivityResult()} コールバック内に受け取ります。詳細については、「<a href="{@docRoot}guide/components/activities.html">Activities</a>」のガイドをご覧ください。 + +</p></li> + +<li><b>サービスを開始するには:</b> +<p>{@link android.app.Service} は、ユーザー インターフェースを持たず、バックグラウンドで操作を実行するコンポーネントです。 +サービスを開始して 1 回限りの操作を実行する(ファイルのダウンロードなど)には、{@link android.content.Intent} を {@link android.content.Context#startService startService()} に渡します。 + +{@link android.content.Intent} は、開始するサービスを記述し、必要なデータすべてを含んでいます。 +</p> + +<p>クライアントサーバーのインターフェースでサービスがデザインされている場合、{@link android.content.Intent} を {@link +android.content.Context#bindService bindService()}</code> に渡して、他のコンポーネントからのサービスにバインドできます。 +詳細については、「<a href="{@docRoot}guide/components/services.html">サービス</a>」のガイドをご覧ください。</p></li> + +<li><b>ブロードキャストを配信するには:</b> +<p>ブロードキャストは、アプリが受け取ることのできるメッセージです。システムは、システムの起動や端末の充電開始など、さまざまなシステム イベントを配信します。他のアプリにブロードキャストを配信するには、{@link android.content.Intent} を {@link android.content.Context#sendBroadcast(Intent) sendBroadcast()}、{@link android.content.Context#sendOrderedBroadcast(Intent, String) +sendOrderedBroadcast()}、{@link +android.content.Context#sendStickyBroadcast sendStickyBroadcast()} のいずれかに渡します。 + + + +</p> +</li> +</ul> + + + + +<h2 id="Types">インテントのタイプ</h2> + +<p>インテントには 2 つのタイプがあります。</p> + +<ul> +<li><b>明示的インテント</b>は、開始するコンポーネントを名前(完全修飾クラス名)で指定します。 +通常は開始するアクティビティやサービスのクラス名がわかっているため、明示的インテントを使用してアプリ内のコンポーネントを開始します。 +たとえば、ユーザー操作に応答して新しいアクティビティを開始したり、バックグラウンドでファイルをダウンロードするサービスを開始したりします。 + +</li> + +<li><b>暗黙的インテント</b>では、特定のコンポーネントを指定せず、代わりに実行する全般的な動作を宣言することで、他のアプリからコンポーネントを処理できるようにします。 +たとえば、マップ上にユーザーの位置を表示する場合、暗黙的インテントを使って、特定の場所をマップ上に表示できる別のアプリにその操作を要求します。 + +</li> +</ul> + +<p>暗黙的インテントを使用してアクティビティやサービスを開始する際、システムによってただちに {@link android.content.Intent} オブジェクトで指定されたアプリ コンポーネントが開始されます。 +</p> + +<div class="figure" style="width:446px"> +<img src="{@docRoot}images/components/intent-filters@2x.png" width="446" alt="" /> +<p class="img-caption"><strong>図 1.</strong> 暗黙的インテントが他のアクティビティを開始するようシステム内に配信される仕組みを表しています。<b>[1]</b> <em>Activity A</em> がアクションの記述を使って {@link android.content.Intent} を作成し、それを {@link +android.content.Context#startActivity startActivity()} に渡します。<b>[2]</b> Android システムがすべてのアプリに対してインテントに一致するインテント フィルタを検索します。 + + +一致するものが見つかったら、<b>[3]</b> システムが {@link +android.app.Activity#onCreate onCreate()} メソッドを呼び出して、{@link android.content.Intent} に渡すことで、そのアクティビティ(<em>Activity B</em>)を開始します。 + +</p> +</div> + +<p>暗黙的インテントを作成するとき、Android システムはインテントの内容を、端末上の他のアプリの <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">マニフェスト ファイル</a>で定義された <em>インテント フィルタ</em> と比較して、開始すべきコンポーネントを見つけます。 + +インテントがインテント フィルタに一致した場合、システムがそのコンポーネントを開始して、{@link android.content.Intent} を配信します。 +複数のインテント フィルタが競合する場合、ユーザーが仕様するアプリを選択できるようシステムによってダイアログが表示されます。 +</p> + +<p>インテント フィルタは、コンポーネントが受け取りたいインテントのタイプを指定する式で、アプリのマニフェスト ファイルに含まれています。 + +たとえば、アクティビティのインテント フィルタを宣言すると、特定のインテント タイプを持つアクティビティを他のアプリから直接開始できるようになります。同様に、アクティビティでインテント フィルタを宣言<em>しない</em>場合は、明示的インテントでのみアクティビティを開始できます。 + + +</p> + +<p class="caution"><strong>警告:</strong> アプリの安全性を保つため、{@link android.app.Service} を開始するときは常に明示的インテントを使用し、サービスでインテント フィルタを宣言しないようにしてください。 + +暗黙的インテントを使ってサービスを開始すると、どのサービスがインテントに応答するかを把握できず、ユーザーにはどのサービスが開始するのかがわからないため、セキュリティ上の危険が伴います。 + +Android 5.0(API レベル 21)以降では、暗黙的インテントで {@link android.content.Context#bindService bindService()} を呼び出すと、システムから例外がスローされます。 + +</p> + + + + + +<h2 id="Building">インテントを作成する</h2> + +<p>{@link android.content.Intent} オブジェクトには Android システムが開始するコンポーネントを決定する際に使用する情報(インテントを受け取るべき正確なコンポーネント名やコンポーネントのカテゴリなど)に加えて、受け取る側のコンポーネントがアクションを適切に実行するために使用する情報(実行するアクションと、実行対象のデータなど)が含まれています。 + + +</p> + + +<p>{@link android.content.Intent} に含まれる主な情報は次のとおりです。</p> + +<dl> + +<dt><b>コンポーネント名</b></dt> +<dd>開始するコンポーネントの名前です。 + +<p>これは省略可能ですが、インテントを<b>明示的</b>にするためには不可欠な情報です。つまり、コンポーネント名で定義されたアプリ コンポーネントにのみ、インテントが配信されます + +コンポーネント名がない場合、インテントは<b>暗黙的</b>になり、他のインテント情報(下記で説明するアクション、データ、カテゴリなど)に基づいてインテントを受け取るべきコンポーネントをシステムが決定します + +—そのため、アプリ内の特定のコンポーネントを開始する必要がある場合は、コンポーネント名を指定する必要があります。 +</p> + +<p class="note"><strong>注:</strong> {@link android.app.Service} を開始するときは、<strong>常にコンポーネント名を指定</strong>する必要があります。 +指定しない場合、どのサービスがインテントに応答するかを把握できず、ユーザーにはどのサービスが開始するのかがわからなくなります。 +</p> + +<p>{@link android.content.Intent} のフィールドは {@link android.content.ComponentName} オブジェクトで、アプリのパッケージ名など、ターゲットのコンポーネントの完全修飾クラス名を使用して指定できます(例: {@code com.example.ExampleActivity})。 + + +コンポーネント名は、{@link +android.content.Intent#setComponent setComponent()}、{@link android.content.Intent#setClass +setClass()}、{@link android.content.Intent#setClassName(String, String) setClassName()}、{@link android.content.Intent} コンストラクタなどを使用して設定できます。 +</p> + +</dd> + +<p><dt><b>アクション</b></dt> +<dd>実行する全体的なアクションを指定する文字列です(<em>閲覧</em>や<em>選択</em>など)。 + +<p>ブロードキャスト インテントの場合、これが発生済みで報告済みのアクションになります。ほとんどのアクションは、残りのインテントがどのように構成されているか、特にデータやエクストラに含まれている内容によって決まります。 +— + + +<p>インテントによって自身のアプリで使用する(または他のアプリで使用して自身のアプリのコンポーネントを呼び出す)独自のアクションを指定できますが、通常は {@link android.content.Intent} クラスや他のフレームワーク クラスで定義されたアクション定数を使用します。 + +アクティビティを開始する際の一般的なアクションをいくつか次に示します。 +</p> + +<dl> +<dt>{@link android.content.Intent#ACTION_VIEW}</dt> + <dd>ギャラリー アプリで表示する写真や、マップアプリで表示する住所など、アクティビティ内にユーザーに表示する情報がある場合は、{@link + android.content.Context#startActivity startActivity()} を使ってインテントにこのアクションを使用します。 + +</dd> + +<dt>{@link android.content.Intent#ACTION_SEND}</dt> + <dd>これは「共有」インテントとしても知られており、メールアプリやソーシャル シェアリング アプリなどの他のアプリ経由でユーザーが共有できるデータがある場合に、{@link + android.content.Context#startActivity startActivity()} でインテントに使用します。 +</dd> +</dl> + +<p>全体的なアクションを定義するその他の定数については、{@link android.content.Intent} クラスのリファレンスをご覧ください。 +システムの設定アプリで特定の画面を開くアクションの {@link android.provider.Settings} など、他のアクションは Android フレームワークの別の場所で定義されます。 + +</p> + +<p>インテントのアクションは、{@link android.content.Intent#setAction +setAction()} や {@link android.content.Intent} コンストラクタを使って指定できます。</p> + +<p>独自のアクションを定義したら、接頭辞としてアプリのパッケージ名を必ず含めます。 +次に例を示します。</p> +<pre>static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";</pre> +</dd> + +<dt><b>データ</b></dt> +<dd>アクションの実行対象であるデータや、データの MIME タイプを参照する URI({@link android.net.Uri} オブジェクト)です。 +提供されるデータタイプは、インテントのアクションによって決まります。たとえば、アクションが {@link android.content.Intent#ACTION_EDIT} の場合、データには編集するドキュメントの URI が含まれます。 + + + +<p>インテントの作成時、URI だけでなくデータタイプ(MINE タイプ)を指定することが重要な場面が多くあります。たとえば、画像を表示できるアクティビティの場合、URI 形式は似ていてもオーディオ ファイルは再生できません。そのため、データの MIME タイプを指定することで、Android システムがインテントを受け取るのに最適なコンポーネントを見つけることができます。ただし、MIME タイプは URI から推測できることもあります。特にデータが {@code content:} URI の場合は、データが端末上にあり、{@link android.content.ContentProvider} に制御されるデータであることを示し、データの MIME タイプがシステムから見えるようになります。 + + + + + +— + +</p> + +<p>データ URI のみを設定するには、{@link android.content.Intent#setData setData()} を呼び出します。MIME タイプのみを設定するには、{@link android.content.Intent#setType setType()} を呼び出します。 +必要であれば、{@link +android.content.Intent#setDataAndType setDataAndType()} を使って両方を明示的に設定することもできます。 +</p> + +<p class="caution"><strong>警告:</strong> URI と MIME タイプの両方を設定する場合は、お互いの値を無効にしてしまわないよう、{@link android.content.Intent#setData setData()} と {@link android.content.Intent#setType setType()} を<strong>呼び出さないで</strong>ください。URI と MIME タイプの両方を設定する場合は、常に {@link android.content.Intent#setDataAndType setDataAndType()} を使用してください。 + + + +</p> +</dd> + +<p><dt><b>カテゴリ</b></dt> +<dd>インテントを処理するコンポーネントの種類に関する追加情報が含まれた文字列です。 +カテゴリの記述は、インテントにいくつでも含めることができますが、ほとんどのインテントではカテゴリは必須ではありません。一般的なカテゴリの例を次に示します。 + + + +<dl> +<dt>{@link android.content.Intent#CATEGORY_BROWSABLE}</dt> + <dd>ターゲットのアクティビティは、ウェブブラウザから開始して画像やメール メッセージなど、リンクで参照されたデータを表示できます。 +— + </dd> +<dt>{@link android.content.Intent#CATEGORY_LAUNCHER}</dt> + <dd>このアクティビティはタスクの初期のアクティビティで、システムのアプリケーション ランチャーの一覧に表示されます。 + + </dd> +</dl> + +<p>カテゴリの全一覧は、{@link android.content.Intent} クラスの説明をご覧ください。 +</p> + +<p>カテゴリは、{@link android.content.Intent#addCategory addCategory()} を使って指定できます。</p> +</dd> +</dl> + + +<p>上記のプロパティ(コンポーネント名、アクション、データ、カテゴリ)は、インテントの特性の定義を表しています。 +これらのプロパティを読み取ることで、Android システムはどのアプリ コンポーネントを開始すべきかを解決できます。 +</p> + +<p>ただし、インテントにはアプリ コンポーネントの解決に影響を与えない追加情報を含めることもできます。 +インテントに含めることのできる情報は次のとおりです。</p> + +<dl> +<dt><b>エクストラ</b></dt> +<dd>要求されたアクションの実行に必要な追加情報のキーと値のペアです。データの URI の特定の種類を使用するアクションがあるのと同様に、特定のエクストラを使用するアクションもあります。 + + +<p>エクストラはさまざまな {@link android.content.Intent#putExtra putExtra()} を使って追加でき、それぞれがキー名と値の 2 つのパラメータを受け入れます。また、すべてのエクストラ データを使って {@link android.os.Bundle} オブジェクトを作成し、{@link +android.content.Intent#putExtras putExtras()} を使って {@link android.os.Bundle} を {@link android.content.Intent} に挿入することもできます。 + + +</p> + +<p>たとえば、{@link android.content.Intent#ACTION_SEND} を使ってメールを送信するインテントを作成するとき、{@link android.content.Intent#EXTRA_EMAIL} キーを使って「宛先」の受信者を指定したり、{@link android.content.Intent#EXTRA_SUBJECT} を使って「件名」を指定したりできます。 + + +</p> + +<p>{@link android.content.Intent} クラスは多くの標準データタイプの {@code EXTRA_*} 定数を指定できます。 +独自のエクストラ キーを宣言する必要がある場合は(アプリが受け取るインテント用に)、アプリのパッケージ名を接頭辞として必ず含めます。 + +次に例を示します。</p> +<pre>static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";</pre> +</dd> + +<dt><b>フラグ</b></dt> +<dd>{@link android.content.Intent} クラスで定義されるフラグは、インテントのメタデータとして機能します。 +フラグは、Android システムにアクティビティの起動方法(アクティビティがどの<a href="{@docRoot}guide/components/tasks-and-back-stack.html">タスク</a>に属するかなど)や、起動後の取り扱い方法(最近のアクティビティの一覧に含めるかどうかなど)を指示します。 + + + + +<p>詳細については、{@link android.content.Intent#setFlags setFlags()} メソッドをご覧ください。</p> +</dd> + +</dl> + + + + +<h3 id="ExampleExplicit">明示的インテントの例</h3> + +<p>明示的インテントは、アプリ内の特定のアクティビティやサービスなど、特定のアプリ コンポーネントを起動する際に使用するものです。明示的インテントを作成するには、{@link android.content.Intent} オブジェクトでコンポーネント名を定義します。他のインテント プロパティはすべて省略可能です。 + + +—</p> + +<p>たとえば、アプリでウェブからファイルをダウンロードするサービスを {@code DownloadService} という名前でビルドした場合、次のコードでそれを開始できます。 +</p> + +<pre> +// Executed in an Activity, so 'this' is the {@link android.content.Context} +// The fileUrl is a string URL, such as "http://www.example.com/image.png" +Intent downloadIntent = new Intent(this, DownloadService.class); +downloadIntent.setData({@link android.net.Uri#parse Uri.parse}(fileUrl)); +startService(downloadIntent); +</pre> + +<p>{@link android.content.Intent#Intent(Context,Class)} コンストラクタがアプリに {@link android.content.Context} を、コンポーネントに {@link java.lang.Class} オブジェクトを提供します。 + +このようにして、このインテントはアプリの {@code DownloadService} クラスを明示的に開始します。 +</p> + +<p>サービスのビルドと開始の詳細については、「<a href="{@docRoot}guide/components/services.html">サービス</a>」のガイドをご覧ください。 +</p> + + + + +<h3 id="ExampleSend">暗黙的インテントの例</h3> + +<p>暗黙的インテントは、端末上のどんなアプリでも実行できるアクションを指定します。 +暗黙的インテントは、自身のアプリではそのアクションを実行できないが、他のアプリでは実行可能であり、どのアプリを使うかをユーザーに選ばせたい場合に便利です。 +</p> + +<p>たとえば、他のユーザーと共有できるようにするコンテンツがある場合は、{@link android.content.Intent#ACTION_SEND} アクションを使ってインテントを作成し、共有するコンテンツを指定するエクストラを追加します。 + +そのインテントで {@link android.content.Context#startActivity startActivity()} を呼び出すと、ユーザーはどのアプリでコンテンツを共有するかを選択できます。 + +</p> + +<p class="caution"><strong>警告:</strong> {@link android.content.Context#startActivity +startActivity()} に送る暗黙的インテントを処理できるアプリがユーザーが<em>持っていない</em>場合もあります。 +その場合、呼び出しは失敗し、アプリはクラッシュします。アクティビティが必ずインテントを受け取るようにするには、{@link android.content.Intent} オブジェクトで {@link android.content.Intent#resolveActivity +resolveActivity()} を呼び出します。 +結果が null 以外の場合は、インテントを処理できるアプリが少なくとも 1 つはあることを意味し、{@link android.content.Context#startActivity startActivity()} を安全に呼び出すことができます。 + +結果が null の場合は、そのインテントは使用せず、可能であればそのインテントを発行する機能を無効にする必要があります。 + +</p> + + +<pre> +// Create the text message with a string +Intent sendIntent = new Intent(); +sendIntent.setAction(Intent.ACTION_SEND); +sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage); +sendIntent.setType("text/plain"); + +// Verify that the intent will resolve to an activity +if (sendIntent.resolveActivity(getPackageManager()) != null) { + startActivity(sendIntent); +} +</pre> + +<p class="note"><strong>注:</strong> この場合、URI は使用されませんが、エクストラに含まれるコンテンツを指定するためインテントのデータタイプは宣言されます。 +</p> + + +<p>{@link android.content.Context#startActivity startActivity()} が呼び出されたとき、システムによってすべてのインストール済みアプリの中にこのタイプのインテント({@link android.content.Intent#ACTION_SEND} アクションとテキスト/プレーン データが含まれるインテント)を処理できるものがあるかどうかが確認されます + + +インテントを処理できるアプリが 1 つしかない場合は、そのアプリがすぐに開いてインテントを受け取ります。 +インテントを処理できるアクティビティが複数ある場合、ユーザーが使用するアプリを選択できるダイアログが表示されます。 +</p> + + +<div class="figure" style="width:200px"> + <img src="{@docRoot}images/training/basics/intent-chooser.png" alt=""> + <p class="img-caption"><strong>図 2.</strong> チューザのダイアログ</p> +</div> + +<h3 id="ForceChooser">アプリチューザを表示する</h3> + +<p>暗黙的インテントに応答するアプリが 2 つ以上ある場合、ユーザーは使用するアプリを選択でき、そのアプリをアクションに対するデフォルトの選択肢にすることができます。 + +これは、ウェブ ページを開いたり、(1 つのカメラを選ぶ傾向にあるユーザーが) +写真を撮影したりといったアクションの実行時に、ユーザーが今後同じアプリの使用を希望するような場合に便利です(ユーザーは常に同じウェブブラウザを使用する傾向があります)。 +</p> + +<p>ただし、インテントに応答するアプリが複数あって、ユーザーが毎回別のアプリを使用する可能性がある場合は、チューザのダイアログを明示的に表示する必要があります。 +チューザのダイアログでは、 +アクションのたびに使用するアプリをユーザーに選択させます(ユーザーはアクションのデフォルトのアプリを選択できません)。 +たとえば、アプリが {@link +android.content.Intent#ACTION_SEND} アクションを使って「共有」を実行するとき、 ユーザーが現在の状況によって別のアプリを使用して共有する場合もあるため、図 2 のようにチューザのダイアログは常に表示する必要があります。 +</p> + + + + +<p>チューザを表示するには、{@link +android.content.Intent#createChooser createChooser()} を使用して {@link android.content.Intent} を作成し、{@link +android.app.Activity#startActivity startActivity()} に渡します。次に例を示します。</p> + +<pre> +Intent sendIntent = 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 the chooser dialog +Intent chooser = Intent.createChooser(sendIntent, title); + +// Verify the original intent will resolve to at least one activity +if (sendIntent.resolveActivity(getPackageManager()) != null) { + startActivity(chooser); +} +</pre> + +<p>これにより、{@link +android.content.Intent#createChooser createChooser()} メソッドに渡されたインテントに応答するアプリのリストを示すダイアログが表示され、 +指定されたテキストがダイアログのタイトルになります。</p> + + + + + + + + + +<h2 id="Receiving">暗黙的インテントを受け取る</h2> + +<p>アプリが受け取ることのできる暗黙的インテントを通知するには、<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">マニフェスト ファイル</a>で <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> 要素を使ってアプリのコンポーネントごとに 1 つ以上のインテント フィルタを宣言します。各インテント フィルタは、インテントのアクション、データ、カテゴリに基づいて受け入れるインテントのタイプを指定します。 + + + +インテントがいずれかのインテント フィルタを通過した場合のみ、システムが暗黙的インテントをアプリのコンポーネントに配信します。 +</p> + +<p class="note"><strong>注:</strong> 明示的インテントは、コンポーネントが宣言しているインテント フィルタに関係なく、常にターゲットに配信されます。 +</p> + +<p>アプリのコンポーネントは固有のジョブそれぞれに対して個別のフィルタを宣言する必要があります。たとえば、画像キャラリーのアプリの 1 つのアクティビティには、画像を表示するフィルタと、画像を編集するフィルタの 2 つがあります。 + +アクティビティが開始すると、{@link android.content.Intent} を調べて {@link android.content.Intent} にある情報に基づいてどのように動作するかを決定します(編集コントロールを表示するかどうかなど)。 + +</p> + +<p>各インテント フィルタは、アプリのマニフェスト ファイルの <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> 要素で定義され、これは対応するアプリのコンポーネント(<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 要素など)にネストされます。 + + +<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> 内で、次の 3 つの要素のなかで 1 つ以上を使用して、受け入れるインテントのタイプを指定できます。 + +</p> + +<dl> +<dt><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a></dt> + <dd>{@code name} 属性で、受け入れるインテントのアクションを宣言します。値は、クラス定数ではなく、アクションのリテラル文字列値である必要があります。 +</dd> +<dt><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a></dt> + <dd>データ URI (<code>scheme</code>、<code>host</code>、<code>port</code>、<code>path</code> など) や MIME タイプのさまざまな側面を指定する 1 つ以上の属性を使用して、受け入れるデータのタイプを宣言します。 + +</dd> +<dt><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a></dt> + <dd>{@code name} 属性で、受け入れるインテントのカテゴリを宣言します。値は、クラス定数ではなく、アクションのリテラル文字列値である必要があります。 + + + <p class="note"><strong>注:</strong> 暗黙的インテントを受け取るには、インテント フィルタに {@link android.content.Intent#CATEGORY_DEFAULT} カテゴリを<strong>含める</strong>必要があります。 + +{@link android.app.Activity#startActivity startActivity()} メソッドと {@link android.app.Activity#startActivityForResult startActivityForResult()}メソッドはすべてのインテントを、{@link android.content.Intent#CATEGORY_DEFAULT} カテゴリを宣言しているものとして処理します。 + + + + インテント フィルタでカテゴリを宣言していない場合、暗黙的インテントはアクティビティに紐付けされません。 +</p> + </dd> +</dl> + +<p>次に、データ タイプがテキストの場合に、{@link android.content.Intent#ACTION_SEND} インテントを受け取るインテント フィルタを使用したアクティビティ宣言の例を示します。 +</p> + +<pre> +<activity android:name="ShareActivity"> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="text/plain"/> + </intent-filter> +</activity> +</pre> + +<p><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a>、<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a>、<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a> のなかで 2 つ以上のインスタンスを含むフィルタを作成することもできます。その場合、コンポーネントがそれらのフィルタ要素のすべての組み合わせを処理できることを確認しておきます。 + + + + +</p> + +<p>複数のタイプのインテントに対応しながら、アクション、データ、カテゴリタイプの特定の組み合わせのみを処理する場合は、複数のインテント フィルタを作成する必要があります。 +</p> + + +<div class="sidebox-wrapper"> +<div class="sidebox"> +<h2>コンポーネントへのアクセスを制限する</h2> +<p>インテント フィルタを使用して他のアプリでコンポーネントを開始できないようにする方法は安全ではありません。 +インテント フィルタでは暗黙的インテントの特定の種類にのみ応答するようコンポーネントを制限しますが、開発者がコンポーネントを決定する場合は、明示的インテントを使用して別のアプリからアプリのコンポーネントを開始できるようになります。アプリのコンポーネントを<em>自身のアプリでのみ</em>開始できるようにする必要がある場合は、そのコンポーネントの <a href="{@docRoot}guide/topics/manifest/activity-element.html#exported">{@code +exported}</a> 属性を{@code "false"} に設定します。 + + + + +</p> +</div> +</div> + +<p>暗黙的インテントは、3 つの要素それぞれへのインテントを比較して、フィルタでテストされます。 +コンポーネントに配信されるには、インテントが 3 つのテストすべてを通過する必要があります。一致しないものが 1 つでも場合、Android システムはインテントをコンポーネントに配信しません。 + +ただし、コンポーネントは複数のインテント フィルタを保持していることもあるため、1 つのインテント フィルタを通過できなかったインテントでも、別のフィルタを通過できる場合があります。システムによるインテント解決の詳細は、次のセクションの<a href="#Resolution">インテントの解決</a>で説明します。 + + +</p> + +<p class="caution"><strong>警告:</strong> 他のアプリの {@link android.app.Service} で誤って実行されないように、自身のサービスは常に明示的インテントを使用して開始し、サービスではインテント フィルタは宣言しないでください。 + +</p> + +<p class="note"><strong>注:</strong> すべてのアクティビティにおいて、インテント フィルタはマニフェスト ファイルで宣言する必要があります。ただし、ブロードキャスト レシーバーのフィルタは、{@link android.content.Context#registerReceiver(BroadcastReceiver, IntentFilter, String, +Handler) registerReceiver()} を呼び出すことで動的に登録できます。 + + +その後、レシーバーの登録を解除するには、{@link +android.content.Context#unregisterReceiver unregisterReceiver()} を使用します。これにより、アプリが実行中の特定の期間だけ、アプリが特定のブロードキャストをリッスンできるようになります。 + +</p> + + + + + + + +<h3 id="ExampleFilters">フィルタの例</h3> + +<p>インテント フィルタの動作をより深く理解するため、ソーシャル シェアリング アプリのマニフェスト ファイルからの次のスニペットをご覧ください。 +</p> + +<pre> +<activity android:name="MainActivity"> + <!-- This activity is the main entry, should appear in app launcher --> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> + +<activity android:name="ShareActivity"> + <!-- This activity handles "SEND" actions with text data --> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="text/plain"/> + </intent-filter> + <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data --> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <action android:name="android.intent.action.SEND_MULTIPLE"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="application/vnd.google.panorama360+jpg"/> + <data android:mimeType="image/*"/> + <data android:mimeType="video/*"/> + </intent-filter> +</activity> +</pre> + +<p>1 つ目のアクティビティである {@code MainActivity} は、アプリのメイン エントリ ポイントで、ユーザーがランチャー アイコンから初めてアプリを起動したときに開くアクティビティです。— +</p> +<ul> + <li>{@link android.content.Intent#ACTION_MAIN} アクションが、これがメインのエントリ ポイントで、インテント データはないことを示しています。 +</li> + <li>{@link android.content.Intent#CATEGORY_LAUNCHER} カテゴリが、このアクティビティのアイコンをシステムのアプリ ランチャーに配置する必要があることを示しています。 +<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 要素が {@code icon} を使ってアイコンを指定しない場合、システムは <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> 要素からのアイコンを使用します。 + +</li> +</ul> +<p>アクティビティをアプリ ランチャーに表示するには、この 2 つをペアリングする必要があります。</p> + +<p>2 つ目のアクティビティである {@code ShareActivity} が、テキストやメディア コンテンツの共有を促します。 +ユーザーは {@code MainActivity} に移動することでこのアクティビティに入ることもありますが、2 つのインテント フィルタのいずれかに一致する暗黙的インテントを発行する別のアプリから直接 {@code ShareActivity} に入ることもできます。 + +</p> + +<p class="note"><strong>注:</strong> MIME タイプ(<a href="https://developers.google.com/panorama/android/">{@code +application/vnd.google.panorama360+jpg}</a>)は、パノラマ写真を指定する特別なデータタイプで、<a href="{@docRoot}reference/com/google/android/gms/panorama/package-summary.html">Google +panorama</a> API を使って処理できます。 + +</p> + + + + + + + + + + + + + +<h2 id="PendingIntent">ペンディング インテントを使用する</h2> + +<p>{@link android.app.PendingIntent} オブジェクトは、{@link +android.content.Intent} オブジェクトのラッパーです。{@link android.app.PendingIntent} の主な目的は、別のアプリケーションに {@link android.content.Intent} をアプリ自身のプロセスから実行したように使用できるパーミッションを付与することです。 + + +</p> + +<p>ペンディング インテントの主な使用例には、次のようなものがあります。</p> +<ul> + <li><a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">通知</a> を使ってユーザーがアクションを実行するときに実施するインテントを宣言する(Android システムの {@link android.app.NotificationManager} が {@link android.content.Intent} を実行します)。 + + + <li> +<a href="{@docRoot}guide/topics/appwidgets/index.html">アプリのウィジェット</a> を使ってユーザーがアクションを実行するときに実施するインテントを宣言する(ホーム画面のアプリが {@link android.content.Intent} を実行します)。 + + <li>今後の指定された時間に実施するインテントを宣言する(Android システムの {@link android.app.AlarmManager} が {@link android.content.Intent} を実行します)。 + +</ul> + +<p>各 {@link android.content.Intent} オブジェクトはアプリの特定のタイプのコンポーネント({@link android.app.Activity}、{@link android.app.Service}、{@link android.content.BroadcastReceiver} のいずれか)で処理されることを前提としているため、{@link android.app.PendingIntent} も同様の前提で作成する必要があります。 + + +ペンディング インテントを使用する場合、アプリはインテントの実行時に {@link android.content.Context#startActivity +startActivity()} などの呼び出しを行いません。 +代わりに、{@link android.app.PendingIntent} の作成時にそれぞれのクリエーター メソッドを呼び出して目的のコンポーネント タイプを宣言する必要があります。 +</p> + +<ul> + <li>{@link android.app.Activity} を開始する {@link android.content.Intent} の場合は、{@link android.app.PendingIntent#getActivity PendingIntent.getActivity()}。 +</li> + <li>{@link android.app.Service} を開始する {@link android.content.Intent} の場合は、{@link android.app.PendingIntent#getService PendingIntent.getService()}。 +</li> + <li>{@link android.content.BroadcastReceiver} を開始する {@link android.content.Intent} の場合は、{@link android.app.PendingIntent#getBroadcast PendingIntent.getBroadcast()}。 +</li> +</ul> + +<p>アプリが他のアプリからペンディング インテントを<em>受け取る</em>場合を除いて、{@link android.app.PendingIntent} の作成時に必要となる {@link android.app.PendingIntent} メソッドはほぼ上記の 3 つのみです。 + +</p> + +<p>各メソッドが現在のアプリの {@link android.content.Context}、ラップする {@link android.content.Intent}、インテントの使用方法を指定する 1 つ以上のフラグ(インテントを 2 回以上できるかどうかなど)を受け取ります。 + +</p> + +<p>ペンディング インテントの使用に関する詳細については、 +「<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">通知</a>」や「<a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a>」など、それぞれの使用例の API ガイドをご覧ください。 +</p> + + + + + + + +<h2 id="Resolution">インテント解決</h2> + + +<p>システムがアクティビティを開始する暗黙的インテントを受け取ると、次の 3 つの側面に基づいてインテントをインテント フィルタと比較し、そのインテントに最適なアクティビティを検索します。 +</p> + +<ul> + <li>インテントのアクション + <li>インテントのデータ(URI とデータタイプの両方) + <li>インテントのカテゴリ +</ul> + +<p>次のセクションでは、インテント フィルタがアプリのマニフェスト ファイルでどのように宣言されているかという観点から、インテントが適切なコンポーネントに紐付けられる方法について説明します。 +</p> + + +<h3 id="ActionTest">アクションのテスト</h3> + +<p>受け入れるインテントのアクションを指定するには、インテント フィルタでゼロ個以上の <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> 要素を宣言します。 +次に例を示します。</p> + +<pre> +<intent-filter> + <action android:name="android.intent.action.EDIT" /> + <action android:name="android.intent.action.VIEW" /> + ... +</intent-filter> +</pre> + +<p>このフィルタを通過するには、{@link android.content.Intent} で指定されたアクションが、フィルタにリストされたアクションのいずれかに一致する必要があります。 +</p> + +<p>フィルタのリストにアクションが 1 つもない場合は、インテントに一致するものがないため、すべてのインテントがテストに失敗します。 +ただし、{@link android.content.Intent} がアクションを指定していない場合は、テストに合格します(フィルタに少なくとも 1 つのアクションが含まれている必要があります)。 + +</p> + + + +<h3 id="CategoryTest">カテゴリのテスト</h3> + +<p>受け入れるインテントのカテゴリを指定するには、インテント フィルタでゼロ個以上の <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> 要素を宣言します。 +次に例を示します。</p> + +<pre> +<intent-filter> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + ... +</intent-filter> +</pre> + +<p>インテントがカテゴリのテストに合格するには、{@link android.content.Intent} 内のすべてのカテゴリが、フィルタ内のカテゴリに一致する必要があります。 +インテント フィルタでは、{@link android.content.Intent} で指定されたカテゴリよりも多くのカテゴリが宣言されている場合もあるため、すべてが {@link android.content.Intent} に一致しなくてもテストには合格します。— + +そのため、カテゴリのないインテントは、フィルタで宣言されているカテゴリに関係なく、常にこのテストに合格することになります。 +</p> + +<p class="note"><strong>注:</strong> Androidは自動的に、{@link +android.content.Context#startActivity startActivity()} と {@link +android.app.Activity#startActivityForResult startActivityForResult()} に渡されるすべての暗黙的インテントに {@link android.content.Intent#CATEGORY_DEFAULT} カテゴリを自動的に適用します。そのため、アクティビティで暗黙的インテントを受け取りたい場合は、前出の {@code <intent-filter>} の例のように、アクティビティのインテント フィルタに {@code "android.intent.category.DEFAULT"} のカテゴリを含める必要があります。 + + + + +</p> + + + +<h3 id="DataTest">データのテスト</h3> + +<p>受け入れるインテント データを指定するには、インテント フィルタでゼロ個以上の <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code +<data>}</a> 要素を宣言します。 +次に例を示します。</p> + +<pre> +<intent-filter> + <data android:mimeType="video/mpeg" android:scheme="http" ... /> + <data android:mimeType="audio/mpeg" android:scheme="http" ... /> + ... +</intent-filter> +</pre> + +<p>各 <code><a href="{@docRoot}guide/topics/manifest/data-element.html"><data></a></code> 要素では、URI 構造とデータタイプ(MIME メディア タイプ)を指定できます。 +URI の各パートには、{@code scheme}、{@code host}、{@code port}、{@code path} の個別の属性があります。— +— + +</p> + +<p style="margin-left: 2em">{@code <scheme>://<host>:<port>/<path>}</p> + +<p> +次に例を示します。 +</p> + +<p style="margin-left: 2em">{@code content://com.example.project:200/folder/subfolder/etc}</p> + +<p>この URI では、スキームが {@code content}、ホストが {@code com.example.project}、ポートが {@code 200}、パスが {@code folder/subfolder/etc} です。 + +</p> + +<p>これらの各属性は <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> 要素では省略可能ですが、一次従属があります。 +</p> +<ul> + <li>スキームが指定されていない場合、ホストは無視されます。</li> + <li>ホストが指定されていない場合、ポートは無視されます。</li> + <li>スキームとホストの両方が指定されていない場合、パスは無視されます。</li> +</ul> + +<p>インテントの URI をフィルタの URI 仕様に比較するときは、フィルタに含まれる URI の一部でのみ比較されます。 +次に例を示します。</p> +<ul> + <li>フィルタでスキームのみが指定されている場合、そのスキームを持つすべての URI がフィルタに一致します。 +</li> + <li>フィルタでスキームと認証局が指定されていて、パスが指定されていない場合、パスにかかわらず同じスキームと認証局を持つすべての URI がフィルタを通過します。 +</li> + <li>フィルタでスキーム、認証局、パスが指定されている場合、同じスキーム、認証局、パスを持つ URI のみがフィルタを通過します。 +</li> +</ul> + +<p class="note"><strong>注:</strong> パスの指定では、ワイルドカードのアスタリスク(*)を使ってパス名の部分一致のみを要求することもできます。 +</p> + +<p>データのテストでは、インテントの URI と MIME タイプの両方を、フィルタで指定された URI と MIME タイプと比較します。 +規則は次のとおりです。 +</p> + +<ol type="a"> +<li>URI も MIME タイプも含まないインテントは、フィルタで URI や MIME タイプが指定されていない場合のみテストをパスします。 +</li> + +<li>URI を含んでいて MIME タイプを含んでいないインテント(明示的にも含まれておらず、URI からも推測できない)場合は、URI がフィルタの URI 形式に一致し、フィルタが MIME タイプを指定していない場合のみテストをパスします。 + +</li> + +<li>MIME タイプを含んでいて、URI を含んでいないインテントは、フィルタのリストに同じ MIME タイプがあり、URI 形式が指定されていない場合のみテストをパスします。 +</li> + +<li>URI と MINE タイプの両方を含む(明示的か、URI からの推測)インテントは、MIME タイプがフィルタのリストにあるタイプに一致した場合のみ、テストの MIME タイプのパートをパスします。 + +テストの URI のパートは、URI がフィルタの URI に一致するか、{@code content:} URI か {@code file:} URI があって URI が指定されていない場合にパスできます。つまり、フィルタにリストに MIME タイプ<em>のみ</em>がある場合、コンポーネントは {@code content:} データと {@code file:} データをサポートすると推定されます。 + + + +</p></li> +</ol> + +<p> +この最後の規則(d)は、コンポーネントがファイルやコンテンツ プロバイダからのローカル データを取得できるという予測を反映しています。そのため、フィルタにはデータタイプのみをリストして、{@code content:} スキームや {@code file:} スキームを明示的に指定する必要はありません。これは一般的なケースです。 + + + +たとえば、次の <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> 要素は、コンポーネントがコンテンツ プロバイダからの画像データを取得し、それを表示できることを Android に伝えています。 + + +</p> + +<pre> +<intent-filter> + <data android:mimeType="image/*" /> + ... +</intent-filter></pre> + +<p> +利用可能なデータはほとんどコンテンツプロバイダによって投入されることから、データタイプが指定されていて URI 指定されていないデータが最も一般的です + +</p> + +<p> +もうひとつ一般的な設定として、スキームと データタイプを使ったフィルタがあります。たとえば、次の <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> 要素は、アクションを実行するためにコンポーネントがネットワークから動画データを取得できることを Android に伝えています。 + + + +</p> + +<pre> +<intent-filter> + <data android:scheme="http" android:type="video/*" /> + ... +</intent-filter></pre> + + + +<h3 id="imatch">インテントのマッチング</h3> + +<p>インテントをインテント フィルタにマッチングする目的には、アクティベートするターゲットを発見するということだけでなく、端末上のコンポーネントのセットに関連する何かを発見するという目的があります。 + +たとえば、ホーム アプリは {@link android.content.Intent#ACTION_MAIN} アクションと {@link android.content.Intent#CATEGORY_LAUNCHER} カテゴリを指定するインテント フィルタを持つすべてのアクティビティを見つけることで、アプリ ランチャーを設定します。 + + +</p> + +<p>アプリケーションでも、同様の方法でインテントのマッチングを使用できます。{@link android.content.pm.PackageManager} には特定のインテントを受け入れることのできるすべてのコンポーネントを返す一連の {@code query...()} メソッドと、インテントに応答できる最適なコンポーネントを返す同様のシリーズの {@code resolve...()} メソッドがあります。 + + + +たとえば、{@link android.content.pm.PackageManager#queryIntentActivities +queryIntentActivities()} は引数として渡されたインテントを実行できるすべてのアクティビティの一覧を返し、{@link +android.content.pm.PackageManager#queryIntentServices +queryIntentServices()} は同様のサービスの一覧を返します。いずれのメソッドでもコンポーネントのアクティベートは行われず、応答できるものを列挙するだけです。 + + + +ブロードキャスト レシーバー用にも、同様のメソッド {@link android.content.pm.PackageManager#queryBroadcastReceivers +queryBroadcastReceivers()} があります。 + +</p> + + + + diff --git a/docs/html-intl/intl/ja/guide/components/loaders.jd b/docs/html-intl/intl/ja/guide/components/loaders.jd new file mode 100644 index 000000000000..bc936774f721 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/loaders.jd @@ -0,0 +1,494 @@ +page.title=ローダ +parent.title=アクティビティ +parent.link=activities.html +@jd:body +<div id="qv-wrapper"> +<div id="qv"> + <h2>本書の内容</h2> + <ol> + <li><a href="#summary">Loader API の概要</a></li> + <li><a href="#app">アプリケーションでローダを使用する</a> + <ol> + <li><a href="#requirements"></a></li> + <li><a href="#starting">ローダを開始する</a></li> + <li><a href="#restarting">ローダを再開する</a></li> + <li><a href="#callback">LoaderManager コールバックを使用する</a></li> + </ol> + </li> + <li><a href="#example">例</a> + <ol> + <li><a href="#more_examples">その他の例</a></li> + </ol> + </li> + </ol> + + <h2>キークラス</h2> + <ol> + <li>{@link android.app.LoaderManager}</li> + <li>{@link android.content.Loader}</li> + + </ol> + + <h2>関連サンプル</h2> + <ol> + <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html"> +LoaderCursor</a></li> + <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> +LoaderThrottle</a></li> + </ol> + </div> +</div> + +<p>Android 3.0 で導入されたローダによって、アクティビティやフラグメントでのデータの非同期ロードが簡単になりました。 +ローダには、次の 3 つの特徴があります。</p> + <ul> + <li>すべての {@link android.app.Activity} と {@link +android.app.Fragment} で使用できる。</li> + <li>非同期のデータロードを提供する。</li> + <li>データのソースを監視し、コンテンツが変更されたときに新しい結果を配信する。 +</li> + <li>設定の変更後に再作成されると、自動的に最後のローダのカーソルに再接続するため、 +再度データを問い合わせる必要がない。 +</li> + </ul> + +<h2 id="summary">Loader API の概要</h2> + +<p>アプリケーションでローダを使用するのに必要になりそうなクラスやインターフェースは複数あります。 +次の表で、それらの概要をまとめました。</p> + +<table> + <tr> + <th>クラス/インターフェース</th> + <th>説明</th> + </tr> + <tr> + <td>{@link android.app.LoaderManager}</td> + <td>1 つ以上の {@link +android.content.Loader} インスタンスを管理するための、{@link android.app.Activity} や {@link android.app.Fragment} に関連した抽象クラスです。 +これにより、アプリケーションは {@link android.app.Activity} や {@link android.app.Fragment} のライフサイクルと連動して長時間の操作を管理できるようになります。最も一般的なのは、{@link android.content.CursorLoader} で使用する方法ですが、アプリケーションでは他のタイプのデータのロード用に、独自のローダを自由に作成することもできます。 + + + + + <br /> + <br /> + 1 つのアクティビティやフラグメントごとに、{@link android.app.LoaderManager} は 1 つだけ存在しますが、{@link android.app.LoaderManager} は複数のローダを持つことができます。 +</td> + </tr> + <tr> + <td>{@link android.app.LoaderManager.LoaderCallbacks}</td> + <td>クライアントが {@link +android.app.LoaderManager} とやり取りするためのコールバック インターフェースです。たとえば、{@link +android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} コールバック メソッドを使用してと新しいローダを作成します。 +</td> + </tr> + <tr> + <td>{@link android.content.Loader}</td> + <td>非同期のデータロードを実行する抽象クラスです。これは、ローダの基本クラスです。 +通常は {@link +android.content.CursorLoader} を使用しますが、独自のサブクラスを実装することもできます。ローダがアクティブな間は、データのソースを管理し、コンテンツが変更されたときに新しい結果を配信します。 + + </td> + </tr> + <tr> + <td>{@link android.content.AsyncTaskLoader}</td> + <td>処理を行うための {@link android.os.AsyncTask} を提供する抽象的なローダです。</td> + </tr> + <tr> + <td>{@link android.content.CursorLoader}</td> + <td>{@link android.content.ContentResolver} に問い合わせて {@link +android.database.Cursor} を返す{@link android.content.AsyncTaskLoader} のサブクラスです。 +これは、カーソルのクエリ用に標準的な方法で {@link +android.content.Loader} プロトコルを実装するクラスで、アプリケーションの UI をブロックせずにバックグラウンドでカーソルのクエリを実行するように、{@link android.content.AsyncTaskLoader} を基に構築されています。{@link +android.content.ContentProvider} からデータを非同期的にロードする際は、フラグメントの API やアクティビティの API 経由でマネージド クエリを実行するのではなく、このローダを使用するのが最適です。 + + + +</td> + </tr> +</table> + +<p>上の表のクラスとインターフェースは、アプリケーションでローダを実装する際に使用する必須コンポーネントです。 +作成するローダごとにこれらすべてが必要になるわけではありませんが、{@link +android.app.LoaderManager} への参照は、ローダを初期化したり {@link +android.content.CursorLoader} などの {@link android.content.Loader} を実装したりするには {@link +android.app.LoaderManager} への参照が常に必要になります。 +次のセクションでは、アプリケーションでのこれらのクラスとインターフェースの使用方法を説明します。 +</p> + +<h2 id ="app">アプリケーションでローダを使用する</h2> +<p>このセクションでは、Android アプリケーションのローダの使用方法について説明します。通常、ローダを使用するアプリケーションには次の内容が含まれます。 +</p> +<ul> + <li>{@link android.app.Activity} または {@link android.app.Fragment}。</li> + <li>{@link android.app.LoaderManager} のインスタンス。</li> + <li>{@link +android.content.ContentProvider} でサポートされているデータをロードする {@link android.content.CursorLoader}。あるいは、{@link android.content.Loader} や{@link android.content.AsyncTaskLoader} の独自のサブクラスを実装して他のソースからデータをロードすることもできます。 + +</li> + <li>{@link android.app.LoaderManager.LoaderCallbacks} の実装。ここで、新しいローダを作成して既存のローダへの参照を管理します。 + +</li> +<li>{@link +android.widget.SimpleCursorAdapter} などのローダのデータを表示する方法。</li> + <li>{@link android.content.CursorLoader} を使用するときの、{@link android.content.ContentProvider} などのデータ ソース。 +</li> +</ul> +<h3 id="starting">ローダを開始する</h3> + +<p>{@link android.app.LoaderManager} は 1 つ以上の {@link +android.content.Loader} インスタンスを {@link android.app.Activity} や {@link android.app.Fragment} 内で管理します。 +1 つのアクティビティやフラグメントごとに、{@link +android.app.LoaderManager} は 1 つだけ存在します。</p> + +<p>通常は、アクティビティの {@link +android.app.Activity#onCreate onCreate()} メソッドか、フラグメントの {@link android.app.Fragment#onActivityCreated onActivityCreated()} メソッド内で {@link android.content.Loader} を初期化します。 + +その方法は次のとおりです。 +</p> + +<pre>// Prepare the loader. Either re-connect with an existing one, +// or start a new one. +getLoaderManager().initLoader(0, null, this);</pre> + +<p>{@link android.app.LoaderManager#initLoader initLoader()} メソッドが次のパラメータを受け取ります。 +</p> +<ul> + <li>ローダを識別する一意の ID。この例では、ID は 0 です。</li> +<li>ローダの構築時に提供する任意の引数(この例では <code>null</code>)。 +</li> + +<li>{@link android.app.LoaderManager} がローダのイベントを報告する際に呼び出す {@link android.app.LoaderManager.LoaderCallbacks} の実装。 +この例では、ローカルクラスが {@link +android.app.LoaderManager.LoaderCallbacks} インターフェースを実装するため、自身の {@code this} に参照を渡します。 + +</li> +</ul> +<p>{@link android.app.LoaderManager#initLoader initLoader()} の呼び出しによって、ローダが初期化され、アクティブになります。 +結果には次の 2 つの可能性があります。</p> +<ul> + <li>ID で指定されたローダが既に存在する場合は、最後に作成されたローダが再利用されます。 +</li> + <li>ID で指定したローダが存在<em>しない</em>場合、{@link android.app.LoaderManager#initLoader initLoader()} が {@link android.app.LoaderManager.LoaderCallbacks} メソッドの {@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} をトリガーします。ここで、インスタンスを作成して新しいローダを返すコードを実装します。詳細については、<a href="#onCreateLoader">onCreateLoader</a> のセクションをご覧ください。 + + + +</li> +</ul> +<p>いずれの場合でも、その {@link android.app.LoaderManager.LoaderCallbacks} の実装はローダに関連付けられ、ローダの状態が変化したときに呼び出されます。 + +この呼び出しの時点で、呼び出し側が開始された状態にあり、要求されたローダが既に存在し、データを生成済みの場合は、システムはただちに {@link +android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()} を呼び出す({@link android.app.LoaderManager#initLoader initLoader()} の間に)ため、それに備えておく必要があります。 + + + +このコールバックの詳細については、<a href="#onLoadFinished"> +onLoadFinished</a> をご覧ください。</p> + +<p>{@link android.app.LoaderManager#initLoader initLoader()} メソッドは作成された {@link android.content.Loader} を返しますが、そこへの参照はキャプチャしないことに注意してください。 + +{@link android.app.LoaderManager} は自動的にローダの生存状態を管理します。 +{@link android.app.LoaderManager} は必要に応じて開始と停止を行いし、ローダとそれに関連付けられたコンテンツの状態を管理します。 + +このことからもわかるように、ローダと直接やり取りすることはほとんどありません(ローダの動作を微調整するローダ メソッドの使用例については、<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> のサンプルをご覧ください)。 + +特定のイベントが発生したときにローディングの処理に干渉することを目的に、{@link +android.app.LoaderManager.LoaderCallbacks} を使用することがよくあります。 + +このトピックの詳細については、<a href="#callback">LoadManager コールバックを使用する</a>をご覧ください。</p> + +<h3 id="restarting">ローダを再開する</h3> + +<p>上記のように {@link android.app.LoaderManager#initLoader initLoader()} を使用する場合、指定した ID があれば既存のローダを使用し、なければ新たに作成します。 + +ただし、古いデータを破棄して最初からやり直したいこともあります。 +</p> + +<p>古いデータを破棄するには、{@link +android.app.LoaderManager#restartLoader restartLoader()} を使用します。たとえば、この {@link android.widget.SearchView.OnQueryTextListener} を実装すると、ユーザーのクエリが変化したときにローダが再開されます。 + +新しい検索フィルタを使用して新しいクエリを実行できるように、ローダは再開される必要があります。 +</p> + +<pre> +public boolean onQueryTextChanged(String newText) { + // Called when the action bar search text has changed. Update + // the search filter, and restart the loader to do a new query + // with this filter. + mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; + getLoaderManager().restartLoader(0, null, this); + return true; +}</pre> + +<h3 id="callback">LoaderManager コールバックを使用する</h3> + +<p>{@link android.app.LoaderManager.LoaderCallbacks} はクライアントが {@link android.app.LoaderManager} とやり取りできるようにするコールバック インターフェースです。 + </p> +<p>特に、{@link android.content.CursorLoader} のローダでは、停止後もデータを保持しておくことが望まれます。 +これにより、アプリケーションがアクティビティやフラグメントの {@link android.app.Activity#onStop +onStop()} メソッドや {@link android.app.Activity#onStart onStart()} メソッド全体でデータを維持することができるので、ユーザーがアプリケーションに戻ったときにデータの再ロードを待つ必要がありません。 + + +新しいローダを作成するタイミングを知りたいときや、ローダのデータの使用を停止するタイミングをアプリケーションに伝えるときは、{@link android.app.LoaderManager.LoaderCallbacks} メソッドを使用します。 + +</p> + +<p>{@link android.app.LoaderManager.LoaderCallbacks} には次のメソッドが含まれています。 +</p> +<ul> + <li>{@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} — 指定された ID の新しい {@link android.content.Loader} をインスタンス化して返します。 + +</li></ul> +<ul> + <li> {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}— 前に作成されたローダがロードを完了した時に呼び出されます。 + +</li></ul> +<ul> + <li>{@link android.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()} — 前に作成されたローダがリセットされ、データが利用不可になったときに呼び出されます。 + + +</li> +</ul> +<p>これらのメソッドについては、次のセクションで詳しく説明します。</p> + +<h4 id ="onCreateLoader">onCreateLoader</h4> + +<p>ローダにアクセスしようとしたとき(たとえば、{@link +android.app.LoaderManager#initLoader initLoader()} 経由など)、ID で指定したローダが存在するかどうかを確認されます。 +存在しない場合は、{@link +android.app.LoaderManager.LoaderCallbacks} メソッドの {@link +android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} をトリガーします。ここで、新しいローダを作成します。 +通常は、{@link +android.content.CursorLoader} になりますが、独自の {@link +android.content.Loader} サブクラスを実装することもできます。 </p> + +<p>この例では、{@link +android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} +コールバック メソッドが {@link android.content.CursorLoader} を作成します。{@link android.content.CursorLoader}は、そのコンストラクタ メソッドを使用して構築する必要があり、{@link +android.content.ContentProvider} へのクエリを実行するのに必要なすべての情報が必要になります。 + +具体的に必要な情報は次のとおりです。</p> +<ul> + <li><em>uri</em> — 取得するコンテンツの URI。 </li> + <li><em>projection</em> — 返す列のリスト。<code>null</code> を渡すとすべての列が返されるため、効率的ではありません。 + </li> + <li><em>selection</em> — SQL WHERE 句の書式で返す行を宣言するフィルタ(WHERE 自体は除く)。 +<code>null</code> を渡すと指定した URI のすべての行が返されます。 + </li> + <li><em>selectionArgs</em> — selection に ? を含めると、selection に表示される順序で <em>selectionArgs</em> の値に置き換えられます。 + +この値は、Strings 配列でバインドされます。 </li> + <li><em>sortOrder</em> — SQL +ORDER BY 句(ORDER 自体は除く)の形式で行を順序付けします。<code>null</code> を渡すとデフォルトのソート順序が使用されるため、順序が付けられない場合があります。 +</li> +</ul> +<p>次に例を示します。</p> +<pre> + // If non-null, this is the current filter the user has provided. +String mCurFilter; +... +public Loader<Cursor> onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. + Uri baseUri; + if (mCurFilter != null) { + baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, + Uri.encode(mCurFilter)); + } else { + baseUri = Contacts.CONTENT_URI; + } + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + + Contacts.DISPLAY_NAME + " != '' ))"; + return new CursorLoader(getActivity(), baseUri, + CONTACTS_SUMMARY_PROJECTION, select, null, + Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); +}</pre> +<h4 id="onLoadFinished">onLoadFinished</h4> + +<p>このメソッドは、前に作成したローダがロードを完了したときに呼び出されます。このメソッドは、このローダが提供した最後のデータが解放される前に呼び出されることが保証されています。 + +この時点で、すべての古いデータを削除する必要がありますが(まもなく解放されるため)、データの所有者はローダでありローダが処理するため、自身でデータを解放しないようにしてください。 + +</p> + + +<p>アプリケーションがもうデータを使用していないことを検知すると、ローダがデータを解放します。 +たとえば、データが {@link +android.content.CursorLoader} からのカーソルの場合は、自身で {@link +android.database.Cursor#close close()} を呼び出さないようにしてください。カーソルが {@link android.widget.CursorAdapter} に置かれている場合は、古い {@link android.database.Cursor} がクローズされないように {@link +android.widget.SimpleCursorAdapter#swapCursor swapCursor()} メソッドを使用する必要があります。 + +次に例を示します。</p> + +<pre> +// This is the Adapter being used to display the list's data.<br +/>SimpleCursorAdapter mAdapter; +... + +public void onLoadFinished(Loader<Cursor> loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); +}</pre> + +<h4 id="onLoaderReset">onLoaderReset</h4> + +<p>このメソッドは、前に作成されたローダがリセットされ、データが利用できなくなったときに呼び出されます。 +このコールバックにより、データが解放されるタイミングがわかり、そのデータへの参照を削除できます。 + </p> +<p>この実装では、<code>null</code> の値を使用して {@link android.widget.SimpleCursorAdapter#swapCursor swapCursor()} を呼び出します。 + +</p> + +<pre> +// This is the Adapter being used to display the list's data. +SimpleCursorAdapter mAdapter; +... + +public void onLoaderReset(Loader<Cursor> loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); +}</pre> + + +<h2 id="example">例</h2> + +<p>以下は、連絡先のコンテンツ プロバイダに対するクエリの結果が含まれた {@link android.widget.ListView} を表示する {@link +android.app.Fragment} の完全な実装の例です。 +{@link +android.content.CursorLoader} を使用してプロバイダへのクエリを管理しています。</p> + +<p>この例にあるように、アプリケーションがユーザーの連絡先にアクセスするには、マニフェストに {@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS} の許可を含める必要があります。 + +</p> + +<pre> +public static class CursorLoaderListFragment extends ListFragment + implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> { + + // This is the Adapter being used to display the list's data. + SimpleCursorAdapter mAdapter; + + // If non-null, this is the current filter the user has provided. + String mCurFilter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText("No phone numbers"); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + // Create an empty adapter we will use to display the loaded data. + mAdapter = new SimpleCursorAdapter(getActivity(), + android.R.layout.simple_list_item_2, null, + new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, + new int[] { android.R.id.text1, android.R.id.text2 }, 0); + setListAdapter(mAdapter); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + // Place an action bar item for searching. + MenuItem item = menu.add("Search"); + item.setIcon(android.R.drawable.ic_menu_search); + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + SearchView sv = new SearchView(getActivity()); + sv.setOnQueryTextListener(this); + item.setActionView(sv); + } + + public boolean onQueryTextChange(String newText) { + // Called when the action bar search text has changed. Update + // the search filter, and restart the loader to do a new query + // with this filter. + mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; + getLoaderManager().restartLoader(0, null, this); + return true; + } + + @Override public boolean onQueryTextSubmit(String query) { + // Don't care about this. + return true; + } + + @Override public void onListItemClick(ListView l, View v, int position, long id) { + // Insert desired behavior here. + Log.i("FragmentComplexList", "Item clicked: " + id); + } + + // These are the Contacts rows that we will retrieve. + static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { + Contacts._ID, + Contacts.DISPLAY_NAME, + Contacts.CONTACT_STATUS, + Contacts.CONTACT_PRESENCE, + Contacts.PHOTO_ID, + Contacts.LOOKUP_KEY, + }; + public Loader<Cursor> onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. + Uri baseUri; + if (mCurFilter != null) { + baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, + Uri.encode(mCurFilter)); + } else { + baseUri = Contacts.CONTENT_URI; + } + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + + Contacts.DISPLAY_NAME + " != '' ))"; + return new CursorLoader(getActivity(), baseUri, + CONTACTS_SUMMARY_PROJECTION, select, null, + Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); + } + + public void onLoadFinished(Loader<Cursor> loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); + } + + public void onLoaderReset(Loader<Cursor> loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); + } +}</pre> +<h3 id="more_examples">その他の例</h3> + +<p><strong>ApiDemos</strong> には、ローダの使用方法を示す他のサンプルがいくつか用意されています。 +</p> +<ul> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html"> +LoaderCursor</a> — 上記のスニペットの完全バージョン。 +</li> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> — スロットリングを使用して、データの変更時にコンテンツ プロバイダのクエリ数を軽減する方法の例です。 +</li> +</ul> + +<p>SDK サンプルのダウンロードとインストールの詳細については、<a href="http://developer.android.com/resources/samples/get.html">Getting the Samples</a> をご覧ください。 + </p> + diff --git a/docs/html-intl/intl/ja/guide/components/processes-and-threads.jd b/docs/html-intl/intl/ja/guide/components/processes-and-threads.jd new file mode 100644 index 000000000000..691a5f471880 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/processes-and-threads.jd @@ -0,0 +1,411 @@ +page.title=プロセスとスレッド +page.tags=lifecycle,background + +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>本書の内容</h2> +<ol> +<li><a href="#Processes">プロセス</a> + <ol> + <li><a href="#Lifecycle">プロセスのライフサイクル</a></li> + </ol> +</li> +<li><a href="#Threads">スレッド</a> + <ol> + <li><a href="#WorkerThreads">ワーカー スレッド</a></li> + <li><a href="#ThreadSafe">スレッド セーフのメソッド</a></li> + </ol> +</li> +<li><a href="#IPC">プロセス間通信(IPC)</a></li> +</ol> + +</div> +</div> + +<p>アプリケーション コンポーネントが開始し、アプリケーションに他に実行中のコンポーネントがない場合、Android システムは実行用のシングル スレッドを持つアプリケーション用の新しい Linux プロセスを開始します。 + +デフォルトでは、同じアプリケーションのすべてのコンポーネントは同じプロセスとスレッド(「メイン」 スレッドと呼ばれます)で実行します。 +アプリケーション コンポーネントが開始したときに、既にそのアプリケーションのプロセスが存在する場合(アプリケーションからの他のコンポーネントが存在するため)、コンポーネントはそのプロセス内で開始し、同じ実行用のスレッドを使用します。 + +ただし、アプリケーション内の別のコンポーネントを別のプロセスで実行するよう調整でき、あらゆるプロセスに対して追加のスレッドを作成できます。 + +</p> + +<p>このドキュメントでは、Android アプリケーションでプロセスとスレッドがどのように動作するかについて説明します。</p> + + +<h2 id="Processes">プロセス</h2> + +<p>デフォルトでは、同じアプリケーションのすべてのコンポーネントは同じプロセスで実行し、ほとんどのアプリケーションでこの動作を変更する必要はありません。 +ただし、特定のコンポーネントが属するプロセスを管理する必要がある場合は、マニフェスト ファイルでそれを行うことができます。 +</p> + +<p>コンポーネント要素の各タイプのマニフェスト エントリ(<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a>、<a href="{@docRoot}guide/topics/manifest/service-element.html">{@code +<service>}</a>、<a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code +<receiver>}</a>、<a href="{@docRoot}guide/topics/manifest/provider-element.html">{@code +<provider>}</a>)は、コンポーネントを実行するプロセスを指定できる {@code android:process} 属性をサポートしています。— +—この属性を設定して、各コンポーネントが独自のプロセスで実行するようにしたり、一部のコンポーネントで同じプロセスを共有し、残りのコンポーネントでは別のプロセスを使用するようにしたりできます。 +また、{@code android:process} を設定すると、異なるアプリケーションのコンポーネントを同じプロセスで実行させることもできます。この場合、アプリケーションが同じ Linux ユーザー ID を共有していて、同じ証明書で署名されている必要があります。 +— + +</p> + +<p><a href="{@docRoot}guide/topics/manifest/application-element.html">{@code +<application>}</a> 要素も {@code android:process} 属性をサポートしており、すべてのコンポーネントに適用されるデフォルトの値を設定します。 +</p> + +<p>メモリの空きが少なくなり、早急にユーザーに提供する必要のあるプロセスが必要とする場合は、Android がプロセスをどこかの時点でシャットダウンするよう決定する場合があります。 +破棄されたプロセスで実行しているアプリケーション コンポーネントは、結果的に破棄されます。 +プロセスは、それらのコンポーネントの処理が再度発生したときに再開されます。 +</p> + +<p>破棄するプロセスを決定する際、Android システムはユーザーへの相対的な重要度を測ります。 +たとえば、画面に見えているアクティビティをホストするプロセスよりも、もう画面に見えていないアクティビティをホストするプロセスの方が先にシャットダウンされることになります。 +そのため、プロセスを停止するかどうかは、そのプロセスで実行しているコンポーネントの状態によって決まります。 +ここから、停止するプロセスを決定する規則について詳しく説明していきます。 + </p> + + +<h3 id="Lifecycle">プロセスのライフサイクル</h3> + +<p>Android システムは、可能な限り長期間アプリケーション プロセスを維持しようとしますが、新たに重要なプロセスが発生した際には、メモリを回収するために古いプロセスをいずれは削除する必要が生じます。 +どのプロセスを維持して、どのプロセスを強制終了するかを決定するため、システムはプロセスで実行しているコンポーネントとコンポーネントの状態に基づいて、各プロセスを「重要度の階層」に位置付けします。 + + +まず、重要度の最も低いプロセスが除去され、その後システム リソースを回復できるまで重要度の低い順に除去していきます。 + +</p> + +<p>重要度の階層には 5 つのレベルがあります。次の一覧では、さまざまなプロセスのタイプを重要度の高い順に表しています(1 つ目のプロセスが<em>最も重要度が高く</em>、<em>最後に強制終了</em>されます)。 + +</p> + +<ol> + <li><b>フォアグラウンド プロセス</b> + <p>ユーザーが現在行っている操作に必要なプロセスです。次の条件のいずれかにあてはまる場合、そのプロセスはフォアグラウンドにあるとみなされます。 +</p> + + <ul> + <li>ユーザーが操作している {@link android.app.Activity} のホストになっている({@link +android.app.Activity} の{@link android.app.Activity#onResume onResume()} メソッドが呼び出された)。 +</li> + + <li>ユーザーが操作しているアクティビティにバインドされている {@link android.app.Service} のホストになっている。 +</li> + + <li>「フォアグラウンド」 で実行中の {@link android.app.Service} のホストになっている(サービスが {@link android.app.Service#startForeground startForeground()} を呼び出した)。— + + + <li>{@link android.app.Service#onCreate onCreate()}、{@link android.app.Service#onStart +onStart()}、{@link android.app.Service#onDestroy onDestroy()} のいずれかのライフサイクル コールバックを実行している {@link android.app.Service} のホストになっている。 +</li> + + <li>{@link + android.content.BroadcastReceiver#onReceive onReceive()} メソッドを実行している {@link android.content.BroadcastReceiver} のホストになっている。</li> + </ul> + + <p>通常は、2~3 個のフォアグラウンド プロセスが存在します。フォアグラウンド プロセスは、それらすべてを実行できなくなるほどメモリが少なくなると、最終手段として強制終了されます。 +—通常はその時点で、端末がメモリのページング状態に達しているため、ユーザー インターフェースのレスポンシブを維持するには一部のフォアグラウンド プロセスを強制終了する必要があります。 + +</p></li> + + <li><b>可視プロセス</b> + <p>フォアグラウンド コンポーネントはないものの、ユーザーに対して画面上に表示される内容に影響を与える可能性のあるプロセスです。 +次の条件のいずれかにあてはまる場合、そのプロセスは可視プロセスであるとみなされます。 +</p> + + <ul> + <li>フォアグラウンドにないが、ユーザーに表示されている {@link android.app.Activity} のホストになっている({@link android.app.Activity#onPause onPause()} メソッドが呼び出された)。 +たとえば、フォアグラウンドのアクティビティがダイアログを開始したときに、前のアクティビティがその背後に見えている場合などがあります。 + +</li> + + <li>可視(またはフォアグラウンドの)アクティビティにバインドされている {@link android.app.Service} のホストになっている。 +</li> + </ul> + + <p>可視プロセスは非常に重要度が高いため、フォアグラウンド プロセスの実行を維持するのに必要な場合のみ、強制終了されます。 + </p> + </li> + + <li><b>サービス プロセス</b> + <p>{@link +android.content.Context#startService startService()} メソッドで開始されたサービスを実行するプロセスで、上の 2 つのカテゴリに分類されないものです。 +サービス プロセスは、ユーザーに表示される内容には直接関係ありませんが、ユーザーにとって必要な操作を実行している場合が多いため(バックグラウンドで音楽を再生したり、ネットワーク経由でデータをダウンロードしたりなど)、フォアグラウンド プロセスと可視プロセスのすべてと合わせて、それらを継続するのにメモリが不足した場合のみ強制終了されます。 + + + </p> + </li> + + <li><b>バックグラウンド プロセス</b> + <p>現在ユーザーに表示されていないアクティビティを有するプロセスです(アクティビティの {@link android.app.Activity#onStop onStop()} メソッドが呼び出された)。 +ユーザーの操作性に直接影響を与えるものではなく、フォアグラウンド プロセス、可視プロセス、サービス プロセス用にメモリを回収する必要があればいつでも強制終了されます。 + + +通常はバックグラウンドで実行するプロセスは多数あるため、最近ユーザーに表示されたアクティビティのあるプロセスを最後に強制終了するよう、LRU(最小使用頻度)リストに入れられます。 + +アクティビティがライフサイクル メソッドを正確に実装し、現在の状態を保存する場合は、そのプロセスを強制終了しても、ユーザーがそのアクティビティに戻ったときに、アクティビティがすべての視覚的状態を復元するため、ユーザーの操作性に視覚的な影響はありません + + +。状態の保存と復元の詳細については、「<a href="{@docRoot}guide/components/activities.html#SavingActivityState">Activities</a>」のドキュメントをご覧ください。 +</p> + </li> + + <li><b>空のプロセス</b> + <p>アクティブなアプリケーション コンポーネントが 1 つも含まれていないプロセスです。このようなプロセスは、プロセスをキャッシュしておくことのみを目的として保持され、次回コンポーネントを実行する際の起動時間を向上させることができます。 + +システムは、プロセスのキャッシュと下層のカーネル キャッシュとの間の全体的なシステム リソースのバランスを整える目的でこれらのシステムを頻繁に強制終了します。 +</p> + </li> +</ol> + + + <p>Android では、プロセスで現在アクティブなコンポーネントの重要度に基づいて、あてはまるランクのなかで最も高いランクにプロセスを位置付けます。 +たとえば、サービス アクティビティと可視アクティビティの両方のホストとなっているプロセスは、サービス プロセスではなく、可視プロセスとして位置付けられます。 +</p> + + <p>さらに、他のプロセスから依存されているプロセスの位置付けが上がる場合があります。他のプロセスのために動作しているプロセスは、その対象プロセスよりも下に位置付けられることはありません。 +— +たとえば、プロセス A のコンテンツ プロバイダが、プロセス B のクライアントのために動作している場合や、プロセス A のサービスがプロセス B のコンポーネントにバインドされている場合、プロセス A の重要度は常にプロセス B 以上であるとみなされます。 + +</p> + + <p>サービスを実行するプロセスは、バックグラウンドのアクティビティを持つプロセスよりも上に位置付けされるため、長時間の操作を開始するアクティビティでは、特に、操作がアクティビティよりも長く続く場合、ワーカー スレッドを作成するよりもその操作の<a href="{@docRoot}guide/components/services.html">サービス</a>を開始する方がよいと考えられます。たとえば、ウェブサイトに写真をアップロードするアクティビティでは、ユーザーがアクティビティから離れた後もアップロードをバックグラウンドで続行できるよう、アップロードを実行するサービスを開始することをお勧めします。サービスを使用することで、アクティビティの状況に変わらず、その操作に「サービス プロセス」以上の優先度が保証されることになります。 + + + + + +同じ理由から、ブロードキャスト レシーバーでもスレッドに長時間の処理を置くのではなく、サービスを採用するようお勧めします。 +</p> + + + + +<h2 id="Threads">スレッド</h2> + +<p>アプリケーション起動の際、システムは アプリケーション実行用のスレッドを作成します。これは、「メイン スレッド」と呼ばれます。 +このスレッドは、イベント(描画イベントを含む)を適切なユーザー インターフェース ウィジェットに送信する役割を担うため非常に重要です。 +また、これはアプリケーションが Android UI ツールキット({@link +android.widget} と {@link android.view} パッケージからのコンポーネント)からのコンポーネントとやり取りをするスレッドでもあります。 +そのため、メイン スレッドは UI スレッドと呼ばれることもあります。 +</p> + +<p>コンポーネントのインスタンスごとに別のスレッドが作成されることは<em>ありません</em>。同じプロセスで実行するすべてのコンポーネントは UI スレッドでインスタンス化され、スレッドから送られた各コンポーネントをシステムが呼び出します。 + +結果的に、システムのコールバック(ユーザー操作を報告する {@link android.view.View#onKeyDown onKeyDown()} やライフサイクル コールバック メソッドなど)に応答するメソッドは常にプロセスの UI スレッドで実行することになります。 + +</p> + +<p>たとえば、ユーザーが画面上のボタンをタッチすると、アプリの UI スレッドがタッチ イベントをウィジェットに送信し、ウィジェットがそのタッチされた状態を設定してイベント キューに無効化の要求を投稿します。 + +UI スレッドが要求をキューから取り出し、ウィジェットに自身を描画するよう通知します。 +</p> + +<p>アプリがユーザー操作に応答して集中的な動作を実行する場合、アプリケーションを正しく実装していない限りこのシングル スレッド モデルではパフォーマンスの低下につながる可能性があります。 +具体的には、すべてが UI スレッドで行われている場合、長ネットワークへのアクセスやデータベースへの問い合わせといった時間のかかる操作を実行すると UI 全体をブロックしてしまいます。スレッドがブロックされると、描画イベントを含むすべてのイベントを送信できなくなります。 + + +ユーザー側には、アプリケーションがハングしたように見えます。 +さらには、UI スレッドが数秒以上(現時点では 5 秒以上)ブロックされると、ユーザーに<a href="http://developer.android.com/guide/practices/responsiveness.html">「アプリケーションが応答していません」</a>のダイアログが表示されます。 + +ユーザーはアプリケーションを停止するか、不快な場合はアンインストールしてしまう可能性があります。 +</p> + +<p>また、Android UI ツールキットはスレッド セーフ<em>ではありません</em>。そのため、ワーカー スレッドから UI を操作できません。すべての操作は、UI スレッドから行う必要があります。 +— +そのため、Android のシングル スレッド モデルには 2 つの明快なルールがあります。</p> + +<ol> +<li>UI スレッドをブロックしない +<li>UI スレッド以外から Android UI ツールキットにアクセスしない +</ol> + +<h3 id="WorkerThreads">ワーカー スレッド</h3> + +<p>上記で説明したシングル スレッド モデルにより、アプリケーションの UI の応答性のためにも UI スレッドをブロックしないことが不可欠です。 +即座に実行する必要のない操作の場合は、別のスレッド(「バックグラウンド」スレッドや「ワーカー」スレッド)で実行するようにする必要があります。 + +</p> + +<p>例として、別のスレッドから画像をダウンロードして {@link android.widget.ImageView} に表示するクリック リスナのコードの一部を次に示します。 +</p> + +<pre> +public void onClick(View v) { + new Thread(new Runnable() { + public void run() { + Bitmap b = loadImageFromNetwork("http://example.com/image.png"); + mImageView.setImageBitmap(b); + } + }).start(); +} +</pre> + +<p>ここでは、ネットワークの操作を処理する新しいスレッドを作成しているため、一見問題ないように見えます。 +ただし、これは<em>UI スレッド以外から Android UI ツールキットにアクセスしない</em>というシングルスレッド モデルの 2 つ目のルールに違反しています。このサンプルは、UI スレッドではなくワーカー スレッドから {@link +android.widget.ImageView} を変更しています。— +結果として、未定義かつ予想外の動作を引き起こし、追跡が難しく時間のかかる作業になってしまいます。 +</p> + +<p>この問題を修正するため、Android には UI スレッド以外からのアクセス方法がいくつか用意されています。 +使用できるメソッドは次のとおりです。</p> + +<ul> +<li>{@link android.app.Activity#runOnUiThread(java.lang.Runnable) +Activity.runOnUiThread(Runnable)}</li> +<li>{@link android.view.View#post(java.lang.Runnable) View.post(Runnable)}</li> +<li>{@link android.view.View#postDelayed(java.lang.Runnable, long) View.postDelayed(Runnable, +long)}</li> +</ul> + +<p>たとえば、上記のコードは {@link +android.view.View#post(java.lang.Runnable) View.post(Runnable)} メソッドを使用して修正できます。</p> + +<pre> +public void onClick(View v) { + new Thread(new Runnable() { + public void run() { + final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png"); + mImageView.post(new Runnable() { + public void run() { + mImageView.setImageBitmap(bitmap); + } + }); + } + }).start(); +} +</pre> + +<p>これで、この実装がスレッドセーフになりました。ネットワーク操作は別のスレッドから実行され、{@link android.widget.ImageView} は UI スレッドから操作されます。 +</p> + +<p>ただし、操作が複雑になるにつれて、この種のコードも複雑化してメンテナンスも難しくなります。 +ワーカー スレッドとのより複雑なやり取りを処理するため、ワーカー スレッドで {@link android.os.Handler} を使うと、UI スレッドから配信されたメッセージを処理できます。 + +ただし、最善なのは{@link android.os.AsyncTask} クラスを拡張することであり、これにより UI を操作する必要のあるワーカー スレッドのタスクの実行を簡素化できます。 +</p> + + +<h4 id="AsyncTask">AsyncTask を使用する</h4> + +<p>{@link android.os.AsyncTask} では、ユーザー インターフェースに非同期の処理を実行できます。 +スレッドやハンドラを自身で処理する必要なく、ワーカー スレッドの操作をブロックし、結果を UI スレッドに発行します。 +</p> + +<p>これを使用するには、{@link android.os.AsyncTask} をサブクラス化し、バックグラウンド スレッドのプール内で実行する {@link +android.os.AsyncTask#doInBackground doInBackground()} コールバック メソッドを実装する必要があります。 +UI を更新するには、{@link +android.os.AsyncTask#onPostExecute onPostExecute()} を実装します。これは {@link +android.os.AsyncTask#doInBackground doInBackground()} からの結果を配信し、UI スレッド内で実行されるため、UI を安全に更新できます。その後、UI スレッドから {@link android.os.AsyncTask#execute execute()} を呼び出してタスクを実行できます。 + +</p> + +<p>たとえば、次のように {@link android.os.AsyncTask} を使って前出の例を実装できます。 +</p> + +<pre> +public void onClick(View v) { + new DownloadImageTask().execute("http://example.com/image.png"); +} + +private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { + /** The system calls this to perform work in a worker thread and + * delivers it the parameters given to AsyncTask.execute() */ + protected Bitmap doInBackground(String... urls) { + return loadImageFromNetwork(urls[0]); + } + + /** The system calls this to perform work in the UI thread and delivers + * the result from doInBackground() */ + protected void onPostExecute(Bitmap result) { + mImageView.setImageBitmap(result); + } +} +</pre> + +<p>ワーカー スレッドで処理される作業と、UI スレッドで処理される作業が分けられたため、UI は安全に、コードはシンプルになりました。 +</p> + +<p>このクラスの使用方法をより深く理解するには {@link android.os.AsyncTask} に目を通す必要がありますが、ここに、その仕組みについて簡単に挙げておきます。 +</p> + +<ul> +<li>ジェネリックを使ってパラメータのタイプ、進捗の値、タスクの最終値を指定できます +</li> +<li>{@link android.os.AsyncTask#doInBackground doInBackground()} メソッドがワーカー スレッド上で自動的に実行されます +</li> +<li>{@link android.os.AsyncTask#onPreExecute onPreExecute()}、{@link +android.os.AsyncTask#onPostExecute onPostExecute()}、{@link +android.os.AsyncTask#onProgressUpdate onProgressUpdate()}はすべて UI スレッドで呼び出されます</li> +<li>{@link android.os.AsyncTask#doInBackground doInBackground()} から返される値は、{@link android.os.AsyncTask#onPostExecute onPostExecute()} に送られます +</li> +<li>{@link android.os.AsyncTask#publishProgress publishProgress()} は、{@link +android.os.AsyncTask#doInBackground doInBackground()} でいつでも呼び出すことができます。UI スレッドで {@link +android.os.AsyncTask#onProgressUpdate onProgressUpdate()} を実行できます</li> +<li>いつでも、どのスレッドからでもタスクをキャンセルできます</li> +</ul> + +<p class="caution"><strong>警告:</strong> ワーカー スレッドの使用時に発生する可能性のあるもう 1 つの問題として、<a href="{@docRoot}guide/topics/resources/runtime-changes.html">実行時の設定が変更</a>された(ユーザーが画面の向きを変えた場合など)ことによってアクティビティが予期せず再起動され、ワーカー スレッドが破棄されてしまうことがあります。 + +このような再起動の間タスクを維持する方法、アクティビティが破棄されたときの正しいタスクのキャンセル方法については、<a href="http://code.google.com/p/shelves/">Shelves</a> のサンプル アプリケーションのソース コードをご覧ください。 + +</p> + + +<h3 id="ThreadSafe">スレッド セーフのメソッド</h3> + +<p> 状況によっては、実装したメソッドが複数のスレッドから呼び出されることがあり、その場合はメソッドがスレッドセーフになるよう作成する必要があります。 + </p> + +<p>主に、<a href="{@docRoot}guide/components/bound-services.html">バインドされたサービス</a>のメソッドなど、リモートで呼び出されるメソッドなどがこれに該当します。—{@link android.os.IBinder} に実装されたメソッドへの呼び出しが、{@link android.os.IBinder IBinder} を実行しているプロセスと同じプロセスで発生した場合、メソッドは呼び出し側のスレッドで実行されます。ただし、呼び出しが別のプロセスで起こった場合は、メソッドはシステムが {@link android.os.IBinder +IBinder} と同じプロセスに保持するスレッドのプールから選ばれたスレッドで実行されます(プロセスの UI スレッドでは実行されません)。 + + + +たとえば、サービスの {@link android.app.Service#onBind onBind()} メソッドがサービスのプロセスの UI スレッドから呼び出されるのに対して、{@link android.app.Service#onBind +onBind()} が返すオブジェクトで実装されたメソッド(RPC メソッドを実装するサブクラスなど)は、プール内のスレッドから呼び出されます。 + + +サービスは複数のクライアントを持てるため、複数のプール スレッドが同じ {@link android.os.IBinder IBinder} メソッドを同時に動かすことができます。このため、{@link android.os.IBinder +IBinder} メソッドはスレッドセーフになるよう実装する必要があります。 +</p> + +<p> 同様に、コンテンツ プロバイダは他のプロセスから送られたデータ要求を受け取ることができます。{@link android.content.ContentResolver} クラスと {@link android.content.ContentProvider} クラスによってプロセス間通信がどのように管理されているかが見えなくなりますが、それらの要求に応答する {@link +android.content.ContentProvider} メソッド({@link +android.content.ContentProvider#query query()}、 {@link android.content.ContentProvider#insert +insert()}、{@link android.content.ContentProvider#delete delete()}、{@link +android.content.ContentProvider#update update()}、{@link android.content.ContentProvider#getType +getType()})は、プロセスの UI スレッドではなく、コンテンツ プロバイダのプロセスにあるスレッドのプールから呼び出されます。 + + +——これらのメソッドは同時に複数のスレッドから呼び出される可能性があるため、先ほどと同様にスレッドセーフになるよう実装する必要があります。 + </p> + + +<h2 id="IPC">プロセス間通信(IPC)</h2> + +<p>Android では、リモート プロシージャ コール(RPC)を使ったプロセス間通信のメカニズムを備えており、メソッドはアクティビティや他のアプリケーション コンポーネントから呼び出された後に、リモート(別のプロセス)で実行され、結果を呼び出し側に返します。 + + +これにより、メソッドの呼び出しとそのデータをオペレーティング システムが理解できるレベルまで分解し、ローカル プロセスとアドレス空間からリモート プロセスとアドレス空間にそれを送信して、そこで呼び出しが再度組み立てて、再現します。 + +その後、戻り値が逆方向に伝達されます。 +Android ではこれらの IPC トランザクションを実行するためのすべてのコードが用意されているため、開発者は RPC のプログラミング インターフェースの定義と実装に集中できます。 + </p> + +<p>IPC を実行するには、アプリケーションが {@link +android.content.Context#bindService bindService()} を使ってサービスにバインドされている必要があります。詳細については、デベロッパー ガイドの「<a href="{@docRoot}guide/components/services.html">サービス</a>」をご覧ください。</p> + + +<!-- +<h2>Beginner's Path</h2> + +<p>For information about how to perform work in the background for an indefinite period of time +(without a user interface), continue with the <b><a +href="{@docRoot}guide/components/services.html">Services</a></b> document.</p> +--> diff --git a/docs/html-intl/intl/ja/guide/components/recents.jd b/docs/html-intl/intl/ja/guide/components/recents.jd new file mode 100644 index 000000000000..81626e1f2925 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/recents.jd @@ -0,0 +1,256 @@ +page.title=オーバービュー画面 +page.tags="recents","overview" + +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + + <h2>本書の内容</h2> + <ol> + <li><a href="#adding">オーバービュー画面にタスクを追加する</a> + <ol> + <li><a href="#flag-new-doc">インテント フラグを使用してタスクを追加する</a></li> + <li><a href="#attr-doclaunch">アクティビティの属性を使用してタスクを追加する</a></li> + </ol> + </li> + <li><a href="#removing">タスクを削除する</a> + <ol> + <li><a href="#apptask-remove">AppTask クラスを使用してタスクを削除する</a></li> + <li><a href="#retain-finished">完了したタスクを保持する</a></li> + </ol> + </li> + </ol> + + <h2>キークラス</h2> + <ol> + <li>{@link android.app.ActivityManager.AppTask}</li> + <li>{@link android.content.Intent}</li> + </ol> + + <h2>サンプル コード</h2> + <ol> + <li><a href="{@docRoot}samples/DocumentCentricApps/index.html">ドキュメント中心のアプリ</a></li> + </ol> + +</div> +</div> + +<p>オーバービュー画面(別名、最近使った画面、最近使ったタスクリスト、最近使ったアプリ)は、最近アクセスした<a href="{@docRoot}guide/components/activities.html">アクティビティ</a>や<a href="{@docRoot}guide/components/tasks-and-back-stack.html">タスク</a>の一覧を示すシステムレベルの UI です。 + +ユーザーはリスト内をナビゲートして再開するタスクを選択したり、スワイプしてタスクをリストから削除したりできます。 + +Android 5.0(API レベル 21)のリリースでは、異なるドキュメントを持つ同一アクティビティ内の複数のインスタンスが、1 つのタスクとしてオーバービュー画面に表示される場合があります。 +たとえば、Google ドライブには複数の Google ドキュメントごとのタスクが表示される場合があります。 +オーバービュー画面には、各ドキュメントが 1 つのタスクとして表示されます。 +</p> + +<img src="{@docRoot}images/components/recents.png" alt="" width="284" /> +<p class="img-caption"><strong>図 1.</strong> オーバービュー画面に表示されている 3 つの Google ドライブ ドキュメントが、それぞれ別のタスクを表しています。 +</p> + +<p>通常、オーバービュー画面にタスクとアクティビティを提示する方法はシステムが定義できるよう許可し、この動作を変更する必要はありません。 +ただし、アクティビティをいつ、どのようにオーバービュー画面に表示するかをアプリで決定することもできます。 +{@link android.app.ActivityManager.AppTask} クラスを使ってタスクを管理でき、{@link android.content.Intent} クラスのアクティビティ フラグを使うとアプリをオーバービュー画面に追加、削除するタイミングを指定できます。 + + +また、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"> +<activity></a></code> 属性を使ってマニフェストで動作を設定することもできます。</p> + +<h2 id="adding">オーバービュー画面にタスクを追加する</h2> + +<p>{@link android.content.Intent} クラスのフラグを使用してタスクを追加すると、ドキュメントをいつ、どのようにオーバービュー画面で開いたり、再度開いたりできるかを細かく制御できます。 +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 属性を使用すると、常に新しいタスクでドキュメントを開くか、ドキュメントの既存のタスクを再利用するかを選択できます。 + + +</p> + +<h3 id="flag-new-doc">インテント フラグを使用してタスクを追加する</h3> + +<p>アクティビティの新しいドキュメントを作成するときは、{@link android.app.ActivityManager.AppTask} クラスの {@link android.app.ActivityManager.AppTask#startActivity(android.content.Context, android.content.Intent, android.os.Bundle) startActivity()} メソッドを呼び出し、アクティビティを起動するインテントを渡します。 + + +論理的な改行を挿入して、システムがアクティビティをオーバービュー画面の新しいタスクとして扱えるようにするには、{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} フラグを、アクティビティを起動する {@link android.content.Intent} の {@link android.content.Intent#addFlags(int) addFlags()} メソッドに渡します。 + + +</p> + +<p class="note"><strong>注:</strong> {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} フラグは、Android 5.1(API レベル 21)で廃止された {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET} を置き換えるものです。 + +</p> + +<p>新しいドキュメントの作成時に {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} フラグを設定すると、システムは常にターゲット アクティビティの新しいタスクをルートとして作成するようになります。この設定によって、同じドキュメントを複数のタスクで開くことが可能になります。 + +これをメインのアクティビティが行う方法を、次のコードで示し舞うs。 +</p> + +<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html"> +DocumentCentricActivity.java</a></p> +<pre> +public void createNewDocument(View view) { + final Intent newDocumentIntent = newDocumentIntent(); + if (useMultipleTasks) { + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + } + startActivity(newDocumentIntent); + } + + private Intent newDocumentIntent() { + boolean useMultipleTasks = mCheckbox.isChecked(); + final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class); + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet()); + return newDocumentIntent; + } + + private static int incrementAndGet() { + Log.d(TAG, "incrementAndGet(): " + mDocumentCounter); + return mDocumentCounter++; + } +} +</pre> + +<p class="note"><strong>注:</strong> {@code FLAG_ACTIVITY_NEW_DOCUMENT} フラグを使って起動されたアクティビティには、マニフェスト ファイルで {@code android:launchMode="standard"} 属性の値(デフォルト)が設定されている必要があります。 + +</p> + +<p>メイン アクティビティが新しいアクティビティを起動するとき、システムはアクティビティのインテント コンポーネント名とインテント データに一致するインテントを持つ既存のタスクを検索します。 +タスクが見つからない場合や、インテントに {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} フラグに含まれている場合は、新しいタスクがアクティビティのルートとして作成されます。 + +タスク見つかった場合は、そのタスクをフロントに移動して、新しいインテントを {@link android.app.Activity#onNewIntent onNewIntent()} に渡します。新しいアクティビティがインテントを受け取り、次の例のようにオーバービュー画面に新しいドキュメントを作成します。 + + +</p> + +<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html"> +NewDocumentActivity.java</a></p> +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_new_document); + mDocumentCount = getIntent() + .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0); + mDocumentCounterTextView = (TextView) findViewById( + R.id.hello_new_document_text_view); + setDocumentCounterText(R.string.hello_new_document_counter); +} + +@Override +protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this activity + is reused to create a new document. + */ + setDocumentCounterText(R.string.reusing_document_counter); +} +</pre> + + +<h3 id="#attr-doclaunch">アクティビティの属性を使用してタスクを追加する</h3> + +<p>アクティビティのマニフェストで、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> の属性の<a href="{@docRoot}guide/topics/manifest/activity-element.html#dlmode">{@code android:documentLaunchMode}</a> を使ってアクティビティを常に新しいタスクで起動するよう指定することもできます。 + + +この属性には 4 つの値があり、ユーザーがアプリケーションでドキュメントを開くときに次のような効果を生みます。 +</p> + +<dl> + <dt>「{@code intoExisting}」</dt> + <dd>アクティビティがそのドキュメントの既存のタスクを再利用します。これは、<a href="#flag-new-doc">インテント フラグを使用してタスクを追加する</a>で説明したように、{@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} フラグを<em>設定せずに</em>、{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} フラグを設定した場合と同じです。 + + +</dd> + + <dt>「{@code always}」</dt> + <dd>ドキュメントが既に開いている場合でも、アクティビティがドキュメントの新しいタスクを作成します。これは、{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} フラグと {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} フラグの両方を設定した場合と同じです。 + +</dd> + + <dt>「{@code none”}」</dt> + <dd>アクティビティはドキュメントの新しいタスクを作成しません。オーバービュー画面はデフォルトでアクティビティがタスクを作成したかのように処理し、アプリの 1 つのタスクを表示して、ユーザーが最後に呼び出したアクティビティから再開します。 + +</dd> + + <dt>「{@code never}」</dt> + <dd>アクティビティはドキュメントの新しいタスクを作成しません。この値を設定すると、{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} フラグと {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} フラグのいずれかが設定されている場合にその動作をオーバーライドし、オーバービュー画面にはアプリの 1 つのタスクが表示され、ユーザーが最後に呼び出したアクティビティから再開します。 + + + +</dd> +</dl> + +<p class="note"><strong>注:</strong> {@code none} と {@code never} の値以外の場合、アクティビティを {@code launchMode="standard"} を使って定義する必要があります。 +属性が指定されていない場合は、{@code documentLaunchMode="none"} が使用されます。 +</p> + +<h2 id="removing">タスクを削除する</h2> + +<p>デフォルトで、アクティビティの完了時にドキュメントのタスクはオーバービュー画面から自動的に削除されます。 +この動作は、{@link android.app.ActivityManager.AppTask} クラスで {@link android.content.Intent} フラグを使うか、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"> +<activity></a></code> 属性を使ってオーバーライドできます。 +</p> + +<p><code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 属性の <a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">{@code android:excludeFromRecents}</a> を {@code true} に設定すると、タスクを常にオーバービュー画面から完全に除外することができます。 + + +</p> + +<p>アプリがオーバービュー画面に表示できるタスクの最大数を設定するには、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 属性の <a href="{@docRoot}guide/topics/manifest/activity-element.html#maxrecents">{@code android:maxRecents}</a> に整数値を設定します。 + + +デフォルトでは 16 に設定されています。タスクの最大数に達すると、最も古いタスクがオーバービュー画面から削除されます。 +{@code android:maxRecents} の最大値は 50(低メモリの端末では 25)で、1 未満の値は無効です。 +</p> + +<h3 id="#apptask-remove">AppTask クラスを使用してタスクを削除する</h3> + +<p>オーバービュー画面に新しいタスクを作成するアクティビティで {@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()} を呼び出すと、タスクを削除して関連アクティビティのすべてを終了させるタイミングを指定できます。 + +</p> + +<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html"> +NewDocumentActivity.java</a></p> +<pre> +public void onRemoveFromRecents(View view) { + // The document is no longer needed; remove its task. + finishAndRemoveTask(); +} +</pre> + +<p class="note"><strong>注:</strong> {@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()} メソッドを使用すると、次のセクションで説明する {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} タグの使用がオーバーライドされます。 + + +</p> + +<h3 id="#retain-finished">完了したタスクを保持する</h3> + +<p>アクティビティの終了後もオーバービュー画面にタスクを保持する場合は、{@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} フラグを、アクティビティを起動するインテントの {@link android.content.Intent#addFlags(int) addFlags()} メソッドに渡します。 + +</p> + +<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html"> +DocumentCentricActivity.java</a></p> +<pre> +private Intent newDocumentIntent() { + final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class); + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | + android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); + newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet()); + return newDocumentIntent; +} +</pre> + +<p><code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 属性の <a href="{@docRoot}guide/topics/manifest/activity-element.html#autoremrecents">{@code android:autoRemoveFromRecents}</a> を {@code false} に設定することでも同じ効果を得られます。 + + +ドキュメントのアクティビティのデフォルト値は {@code true}、通常のアクティビティでは {@code false} になります。 +この属性を使用すると、前のセクションで説明した {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} フラグがオーバーライドされます。 +</p> + + + + + + + diff --git a/docs/html-intl/intl/ja/guide/components/services.jd b/docs/html-intl/intl/ja/guide/components/services.jd new file mode 100644 index 000000000000..fa946dbc94b2 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/services.jd @@ -0,0 +1,813 @@ +page.title=サービス +@jd:body + +<div id="qv-wrapper"> +<ol id="qv"> +<h2>本書の内容</h2> +<ol> +<li><a href="#Basics">基本</a></li> +<ol> + <li><a href="#Declaring">マニフェストでサービスを宣言する</a></li> +</ol> +<li><a href="#CreatingAService">開始されたサービスを作成する</a> + <ol> + <li><a href="#ExtendingIntentService">IntentService クラスを拡張する</a></li> + <li><a href="#ExtendingService">Service クラスを拡張する</a></li> + <li><a href="#StartingAService">サービスを開始する</a></li> + <li><a href="#Stopping">サービスを停止する</a></li> + </ol> +</li> +<li><a href="#CreatingBoundService">バインドされたサービスを作成する</a></li> +<li><a href="#Notifications">ユーザーに通知を送信する</a></li> +<li><a href="#Foreground">サービスをフォアグラウンドで実行する</a></li> +<li><a href="#Lifecycle">サービスのライフサイクルを管理する</a> +<ol> + <li><a href="#LifecycleCallbacks">ライフサイクル コールバックを実装する</a></li> +</ol> +</li> +</ol> + +<h2>キークラス</h2> +<ol> + <li>{@link android.app.Service}</li> + <li>{@link android.app.IntentService}</li> +</ol> + +<h2>サンプル</h2> +<ol> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.html">{@code + ServiceStartArguments}</a></li> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code + LocalService}</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ol> +<li><a href="{@docRoot}guide/components/bound-services.html">バインドされたサービス</a></li> +</ol> + +</div> + + +<p>{@link android.app.Service} は、バックグラウンドで長時間動作して作業を行い、ユーザー インターフェースを表示しないアプリケーション コンポーネントです。 +別のアプリケーション コンポーネントがサービスを開始し、ユーザーが他のアプリケーションに切り替えた場合でも、サービスはバックグラウンドで実行し続けることができます。 + +さらに、コンポーネントをサービスにバインドして操作したり、プロセス間通信(IPC)を実行したりすることも可能です。 +たとえば、サービスはネットワーク トランザクションの処理、音楽の再生、ファイルの I/O の実行、コンテンツ プロバイダとのやり取りなどのすべてをバックグラウンドで行うことができます。 + +</p> + +<p>サービスには、基本的に次の 2 つの形式があります。</p> + +<dl> + <dt>開始されたサービス</dt> + <dd>アプリケーション コンポーネント(アクティビティなど)が {@link android.content.Context#startService startService()} を呼び出して開始したときに、サービスが「開始された」状態になります。 +一旦開始されると、たとえ開始したコンポーネントが破棄されても、サービスは無期限に実行できます。 +通常、開始されたサービスは 1 つの操作を実行するだけで、呼び出し元に結果を返すことはありません。たとえば、サービスはネットワーク上でファイルのダウンロードやアップロードを行います。 + +操作が完了すると、サービスは自身で停止する必要があります。 +</dd> + <dt>バインドされたサービス</dt> + <dd>アプリケーション コンポーネントが {@link +android.content.Context#bindService bindService()} を呼び出してサービスにバインドすると、サービスは「バインドされた」状態になります。バインドされたサービスは、コンポーネントがサービスを操作したり、要求を送信したり、結果を取得したり、さらにはプロセス間通信(IPC)でもそれを行えるクライアントサーバー型インターフェースを提供します。 + +バインドされたサービスは、他のアプリケーション コンポーネントがそれにバインドしている限り実行し続けます。 +サービスには同時に複数のコンポーネントがバインドできますが、すべてがアンバインドされると、サービスは破棄されます。 +</dd> +</dl> + +<p>このドキュメントではこの 2 種類のサービスそれぞれの概要について説明しますが、サービスは開始された状態(無期限に実行)、バインドされた状態のどちらの方法でも動作できます。これは、2 つのコールバック メソッドを実装するかどうかの問題で、{@link +android.app.Service#onStartCommand onStartCommand()} ではコンポーネントにサービスの開始を許可し、{@link +android.app.Service#onBind onBind()} ではバインドを許可することになります。 + +</p> + +<p>アプリケーションが開始された、バインドされた、またはその両方かであるかどうかにかかわらず、どんなコンポーネントでもアクティビティを使用できるのと同じように、{@link android.content.Intent} を使って開始することで、どんなアプリケーション コンポーネントでもサービスを使用できます。 + +—ただし、マニフェスト ファイルでサービスを非公開として宣言して、他のアプリケーションからのアクセスをブロックすることもできます。 +詳細については、<a href="#Declaring">マニフェストでサービスを宣言する</a>で説明します。 + +</p> + +<p class="caution"><strong>警告:</strong> サービスは、そのホスト プロセスのメインスレッドで実行します。サービスが自身のスレッドを作成することは<strong>なく</strong>、別のプロセスで実行されることも<strong>ありません</strong>(別の方法を指定しない限り)。 +— +つまり、サービスが CPU を集中的に使ったり、ブロック操作を行ったりするような場合(MP3 の再生やネットワーク作業)は、サービス内に新しいスレッドを作成してその作業を行う必要があります。 + +別のスレッドを使うことで、「アプリケーションが応答していません (ANR)」のエラーが発生するリスクを軽減でき、アプリケーションのメインスレッドをアクティビティのユーザー操作専用にすることができます。 + +</p> + + +<h2 id="Basics">基本</h2> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <h3>サービスとスレッド、どちらを使用すべきか。</h3> + <p>サービスは、ユーザーがアプリケーションを操作していない間もバックグラウンドで実行できるコンポーネントにすぎません。 +そのような必要性がある場合に限り、サービスを作成します。 +</p> + <p>ユーザーがアプリケーションを操作している間だけ、メインスレッド外で作業を行う必要がある場合は、サービスではなくスレッドを作成することをお勧めします。 +たとえば、アクティビティを実行している間だけ音楽を再生する場合は、{@link android.app.Activity#onCreate onCreate()} にスレッドを作成し、{@link +android.app.Activity#onStart onStart()} で実行を開始して、{@link android.app.Activity#onStop +onStop()} で停止します。 + +また、従来の {@link java.lang.Thread} クラスの代わりに {@link android.os.AsyncTask} や {@link android.os.HandlerThread} を使用する方法もあります。 +スレッドの詳細については、「<a href="{@docRoot}guide/components/processes-and-threads.html#Threads">プロセスとスレッド</a>」のドキュメントをご覧ください。 +</p> + <p>サービスを使用する際は、デフォルトではアプリケーションのメインスレッドで実行されるため、集中的な作業やブロック操作を行う場合はサービス内に新しいスレッドを作成する必要があることに注意してください。 + +</p> +</div> +</div> + +<p>サービスを作成するには、{@link android.app.Service} のサブクラス(またはその既存のサブクラス)を作成する必要があります。 +実装時には、サービスのライフサイクルの重要側面を扱うコールバック メソッドをオーバーライドして、必要に応じてサービスにバインドするためのメカニズムをコンポーネントに提供する必要があります。 + +オーバーライドする必要のある、最も重要なコールバック メソッドは次の 2 つです。</p> + +<dl> + <dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt> + <dd>アクティビティなどの他のコンポーネントが、{@link android.content.Context#startService +startService()} を呼び出してサービスの開始を要求したときに、システムがこのメソッドを呼び出します。 +このメソッドが実行されるとサービスは開始され、バックグラウンドで無期限に実行します。 +これを実装すると、作業完了時に {@link android.app.Service#stopSelf stopSelf()} か {@link +android.content.Context#stopService stopService()} を呼び出して自身でサービスを停止する必要があります +(バインドのみを提供する場合は、このメソッドを実装する必要はありません)。 +</dd> + <dt>{@link android.app.Service#onBind onBind()}</dt> + <dd>{@link android.content.Context#bindService +bindService()} を呼び出して他のコンポーネントをサービスにバインドさせるとき(RPC 実行時など)に、システムがこのメソッドを呼び出します。 +このメソッドの実装時には、{@link android.os.IBinder} を返してクライアントがサービスとの通信に使うインターフェースを提供する必要があります。 +このメソッドの実装は常に必要ですが、バインドを許可しない場合は、null を返す必要があります。 +</dd> + <dt>{@link android.app.Service#onCreate()}</dt> + <dd>サービスが始めて作成されたときに、1 回限りのセットアップ処理を実行するためにシステムがこのメソッドを呼び出します({@link android.app.Service#onStartCommand onStartCommand()} か {@link android.app.Service#onBind onBind()} のいずれかを呼び出す前)。 + +サービスが既に実行中の場合、このメソッドは呼び出されません。 +</dd> + <dt>{@link android.app.Service#onDestroy()}</dt> + <dd>サービスがもう使用されておらず破棄されたときに、システムがこのメソッドを呼び出します。これは、スレッドや登録されたリスナ、レシーバーなどをクリーンアップするためにサービスに実装する必要があります。 + +これが、サービスが受け取る最後の呼び出しになります。</dd> +</dl> + +<p>コンポーネントが {@link +android.content.Context#startService startService()} を呼び出してサービスを開始すると(結果的に {@link +android.app.Service#onStartCommand onStartCommand()} が呼び出される)、{@link android.app.Service#stopSelf()} を使ってサービス自身が停止するか、他のコンポーネントが {@link android.content.Context#stopService stopService()} を呼び出して停止するまで、サービスは実行し続けます。 + +</p> + +<p>コンポーネントが {@link android.content.Context#bindService bindService()} を呼び出してサービスを作成した(そして {@link +android.app.Service#onStartCommand onStartCommand()} が呼び出されて<em>いない</em>)場合、サービスはコンポーネントにバインドされている間のみ実行します。 + +すべてのクライアントからアンバインドされると、サービスはシステムによって破棄されます。 +</p> + +<p>Android システムは メモリが少なくなって、ユーザーが使用しているアクティビティ用のシステムリソースを回復させる必要が生じた場合のみ、サービスを強制的に停止させます。 +サービスがユーザーが使用しているアクティビティにバインドされている場合は、それが強制終了される可能性は低く、<a href="#Foreground">フォアグラウンドで実行</a>(後で説明)するように宣言されている場合は、強制終了されることはほとんどありません。一方で、サービスが開始されてから長時間実行している場合は、システムはバックグラウンド タスクのリストにおけるその位置付けを徐々に低くし、そのサービスが強制終了される確率が高くなります。開始されたサービスを作成する際は、システムによる再起動を円滑に処理するようデザインする必要があります。 + + + +— +システムがサービスを強制終了すると、リソースが回復次第そのサービスが再起動します(後述の {@link +android.app.Service#onStartCommand onStartCommand()} から返される値にもよります)。 +システムがサービスを破棄するタイミングについては、「<a href="{@docRoot}guide/components/processes-and-threads.html">Processes and Threading</a>」のドキュメントをご覧ください。 + +</p> + +<p>次のセクションでは、それぞれのタイプのサービスの作成方法と、他のアプリケーション コンポーネントからの使用方法について説明します。 +</p> + + + +<h3 id="Declaring">マニフェストでサービスを宣言する</h3> + +<p>アクティビティ(や他のコンポーネント)と同様に、すべてのサービスをアプリケーションのマニフェスト ファイルで宣言する必要があります。 +</p> + +<p>サービスを宣言するには、<a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> 要素を <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> の子要素として追加します。 + +次に例を示します。</p> + +<pre> +<manifest ... > + ... + <application ... > + <service android:name=".ExampleService" /> + ... + </application> +</manifest> +</pre> + +<p>マニフェストでのサービスの宣言に関する詳細については、<a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> 要素のリファレンスをご覧ください。 +</p> + +<p><a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> に含めることで、サービスやサービスを実行するプロセスの開始に必要なパーミッションなどのプロパティを定義できる他の属性がいくつかあります。 + +<a href="{@docRoot}guide/topics/manifest/service-element.html#nm">{@code android:name}</a> 属性は唯一の必須属性で、サービスのクラス名を指定します。 +—アプリケーションを発行したら、この名前は変更できません。変更すると、サービスを開始したりバインドしたりする明示的インテントの依存関係によってコードを破損する可能性があります(ブログの投稿「<a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Things That Cannot Change</a>」をご覧ください)。 + + + + +<p>アプリの安全性を保つため、<strong>{@link android.app.Service}を開始したりバインドしたりするときは、常に明示的インテントを使用</strong>し、サービスでインテント フィルタを宣言しないようにしてください。 +どのサービスを開始するかについて、ある程度のあいまい静を残しておく必要がある場合は、サービスにインテント フィルタを定義でき、{@link +android.content.Intent} からコンポーネント名を除外して、その後ターゲットのサービスのあいまい性を十分に解消する {@link +android.content.Intent#setPackage setPackage()} でインテントのパッケージを設定する必要があります。 + + +</p> + +<p>さらに、<a href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a> 属性を含めて {@code "false"} に設定すると、サービスを自身のアプリでしか利用できないようにできます。 + +これにより、他のアプリによるサービスの開始を効果的に回避でき、たとえ明示的インテントを使用したとしても開始できなくなります。 +</p> + + + + +<h2 id="CreatingStartedService">開始されたサービスを作成する</h2> + +<p>開始されたサービスは、他のコンポーネントが {@link +android.content.Context#startService startService()} を呼び出すことで結果的にサービスの {@link android.app.Service#onStartCommand onStartCommand()} メソッドを呼び出して開始されたサービスです。 +</p> + +<p>サービスが開始されると、サービスはそれを開始したコンポーネントから独立したライフサイクルを持ち、たとえ開始したコンポーネントが破棄されても、サービスは無期限に実行できます。 + +そのため、サービスはジョブが完了したら {@link android.app.Service#stopSelf stopSelf()} を呼び出して自身で停止する必要があり、他のコンポーネントが {@link android.content.Context#stopService stopService()} を呼び出して停止することもできます。 + +</p> + +<p>アクティビティなどのアプリケーション コンポーネントは、{@link +android.content.Context#startService startService()} を呼び出して、サービスを指定し、サービスが使用するデータを含めた {@link android.content.Intent} を渡してサービスを開始できます。 +サービスはこの {@link android.content.Intent} を、{@link android.app.Service#onStartCommand +onStartCommand()} メソッドで受け取ります。 +</p> + +<p>たとえば、オンライン データベースにデータを保存する必要のあるアクティビティがあるとします。アクティビティでサービスを開始し、{@link +android.content.Context#startService startService()} にインテントを渡して、保存するデータをサービスに配信します。 +サービスはインテントを {@link +android.app.Service#onStartCommand onStartCommand()} で受け取り、インターネットに接続してデータベースのトランザクションを実行します。 +トランザクションが完了したら、サービスは自身で停止し、破棄されます。 +</p> + +<p class="caution"><strong>警告:</strong> デフォルトでは、アプリケーションで宣言されたサービスは、アプリケーションと同じプロセスで、そのアプリケーションのメインスレッドで実行します。 +そのため、ユーザーが同じアプリケーションのアクティビティを操作している間に、サービスが集中的な処理やブロック操作を実行すると、アクティビティのパフォーマンスが低下します。 + +アプリケーションのパフォーマンスへの影響を回避するには、サービス内で新しいスレッドを開始する必要があります。 +</p> + +<p>従来どおり、開始されたサービスを作成するために拡張できるクラスが 2 つあります。</p> +<dl> + <dt>{@link android.app.Service}</dt> + <dd>これは、すべてのサービスの基本クラスです。サービスはデフォルトでアプリケーションのメインスレッドを使用し、アプリケーションが実行しているアクティビティのパフォーマンスを低下させることがあるため、このクラスを拡張するときは、サービスのすべての作業を行うための新しいスレッドを作成することが重要です。 + + +</dd> + <dt>{@link android.app.IntentService}</dt> + <dd>すべての開始要求を一件ずつ処理するワーカー スレッドを使用した {@link android.app.Service} のサブクラスです。 +サービスで同時に複数の要求を処理する必要がない場合は、これが最適です。 +{@link +android.app.IntentService#onHandleIntent onHandleIntent()} を実装するだけで、それぞれの開始要求のインテントを受け取り、バックグラウンドでの処理が可能になります。 +</dd> +</dl> + +<p>次のセクションでは、これらいずれかのクラスを使用してサービスを実装する方法について説明します。 +</p> + + +<h3 id="ExtendingIntentService">IntentService クラスを拡張する</h3> + +<p>開始されたサービスで同時に複数の要求を処理する必要があることはほとんどないため(実際には危険なマルチスレッド シナリオになります)、{@link android.app.IntentService} クラスを使用してサービスを実装するのが最適だと考えられます。 + +</p> + +<p>{@link android.app.IntentService} は、次の操作を行います。</p> + +<ul> + <li>アプリケーションのメインスレッドとは別の {@link +android.app.Service#onStartCommand onStartCommand()} に配信されるすべてのインテントを実行する、デフォルトのワーカー スレッドを作成します。 +</li> + <li>マルチスレッドの懸念を排除するため、一度に 1 つのインテントを {@link +android.app.IntentService#onHandleIntent onHandleIntent()} の実装に渡すワークキューを作成します。 +</li> + <li>{@link android.app.Service#stopSelf} を呼び出す必要がないよう、すべての開始要求の処理後にサービスを停止します。 +</li> + <li>Null を返す {@link android.app.IntentService#onBind onBind()} のデフォルト実装を提供します。 +</li> + <li>インテントをワークキュー、{@link +android.app.IntentService#onHandleIntent onHandleIntent()} の実装の順に送信する {@link android.app.IntentService#onStartCommand +onStartCommand()} のデフォルト実装を提供します。</li> +</ul> + +<p>上記すべての操作が行われることで、開発者が行う必要があるのは、クライアントから指示された内容を処理する {@link +android.app.IntentService#onHandleIntent onHandleIntent()} を実装するだけになります +(ただし、サービスの小さいコンストラクタを提供する必要はあります)。</p> + +<p>{@link android.app.IntentService} の実装例を次に示します。</p> + +<pre> +public class HelloIntentService extends IntentService { + + /** + * A constructor is required, and must call the super {@link android.app.IntentService#IntentService} + * constructor with a name for the worker thread. + */ + public HelloIntentService() { + super("HelloIntentService"); + } + + /** + * The IntentService calls this method from the default worker thread with + * the intent that started the service. When this method returns, IntentService + * stops the service, as appropriate. + */ + @Override + protected void onHandleIntent(Intent intent) { + // Normally we would do some work here, like download a file. + // For our sample, we just sleep for 5 seconds. + long endTime = System.currentTimeMillis() + 5*1000; + while (System.currentTimeMillis() < endTime) { + synchronized (this) { + try { + wait(endTime - System.currentTimeMillis()); + } catch (Exception e) { + } + } + } + } +} +</pre> + +<p>コンストラクタと {@link +android.app.IntentService#onHandleIntent onHandleIntent()} の実装、必要なのはこれだけです。</p> + +<p>{@link +android.app.IntentService#onCreate onCreate()}、{@link +android.app.IntentService#onStartCommand onStartCommand()}、{@link +android.app.IntentService#onDestroy onDestroy()} などの他のコールバック メソッドもオーバーライドする場合は、{@link android.app.IntentService} がワーカー スレッドの生存状態を正しく処理できるよう、必ず super を実装するようにします。 +</p> + +<p>たとえば、{@link android.app.IntentService#onStartCommand onStartCommand()} はデフォルト実装を返す必要があります(これによりインテントが {@link +android.app.IntentService#onHandleIntent onHandleIntent()} に配信されます)。 +</p> + +<pre> +@Override +public int onStartCommand(Intent intent, int flags, int startId) { + Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); + return super.onStartCommand(intent,flags,startId); +} +</pre> + +<p>{@link android.app.IntentService#onHandleIntent onHandleIntent()} 以外で、super クラスを呼び出す必要のないメソッドは、{@link android.app.IntentService#onBind +onBind()} です(ただし、サービスでバインドを許可している場合のみ実装が必要です)。 +</p> + +<p>次のセクションでは、この種のサービスが、基本の {@link android.app.Service} クラスを拡張したときにどのように実装されるかを説明します。 +これにはさらに多くのコードがありますが、開始要求の同時処理が必要な場合には適しています。 +</p> + + +<h3 id="ExtendingService">Service クラスを拡張する</h3> + +<p>前のセクションで説明したように、{@link android.app.IntentService} を使用すると開始されたサービスの実装が非常に簡単になります。 +ただし、サービスでマルチスレッドを実行する必要がある場合(開始要求をワークキュー経由で処理するのではなく)、{@link android.app.Service} クラスを拡張して、それぞれのインテントを処理できます。 + +</p> + +<p>比較のために、{@link +android.app.IntentService} を使用した上記の例とまったく同じ処理を実行する {@link +android.app.Service} クラスの実装の例が次のコードです。つまり、それぞれの開始要求に対し、ワーカー スレッドを使用してジョブとプロセスを実行し、一度に 1 つの要求のみを処理します。 +</p> + +<pre> +public class HelloService extends Service { + private Looper mServiceLooper; + private ServiceHandler mServiceHandler; + + // Handler that receives messages from the thread + private final class ServiceHandler extends Handler { + public ServiceHandler(Looper looper) { + super(looper); + } + @Override + public void handleMessage(Message msg) { + // Normally we would do some work here, like download a file. + // For our sample, we just sleep for 5 seconds. + long endTime = System.currentTimeMillis() + 5*1000; + while (System.currentTimeMillis() < endTime) { + synchronized (this) { + try { + wait(endTime - System.currentTimeMillis()); + } catch (Exception e) { + } + } + } + // Stop the service using the startId, so that we don't stop + // the service in the middle of handling another job + stopSelf(msg.arg1); + } + } + + @Override + public void onCreate() { + // Start up the thread running the service. Note that we create a + // separate thread because the service normally runs in the process's + // main thread, which we don't want to block. We also make it + // background priority so CPU-intensive work will not disrupt our UI. + HandlerThread thread = new HandlerThread("ServiceStartArguments", + Process.THREAD_PRIORITY_BACKGROUND); + thread.start(); + + // Get the HandlerThread's Looper and use it for our Handler + mServiceLooper = thread.getLooper(); + mServiceHandler = new ServiceHandler(mServiceLooper); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); + + // For each start request, send a message to start a job and deliver the + // start ID so we know which request we're stopping when we finish the job + Message msg = mServiceHandler.obtainMessage(); + msg.arg1 = startId; + mServiceHandler.sendMessage(msg); + + // If we get killed, after returning from here, restart + return START_STICKY; + } + + @Override + public IBinder onBind(Intent intent) { + // We don't provide binding, so return null + return null; + } + + @Override + public void onDestroy() { + Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); + } +} +</pre> + +<p>このように、{@link android.app.IntentService} を使う場合よりもかなり面倒です。</p> + +<p>ただし、{@link android.app.Service#onStartCommand +onStartCommand()} への各呼び出しを自身で処理するため、同時に複数の要求を実行することも可能です。この例にはあてはまりませんが、自身の状況に合う場合は、要求ごとに新しいスレッドを作成し、すぐに実行することもできます(前の要求が完了するのを待つ必要がありません)。 + +</p> + +<p>{@link android.app.Service#onStartCommand onStartCommand()} メソッドは整数を返す必要があることに注意してください。 +整数は、システムがサービスを強制終了した場合に、サービスをどのように続行させるかを記述する値です(前述したように、{@link +android.app.IntentService} のデフォルト実装が代わりにこれを処理しますが、自身で修正することもできます)。 +{@link android.app.Service#onStartCommand onStartCommand()} から返される値は、次のいずれかの定数である必要があります。 + +</p> + +<dl> + <dt>{@link android.app.Service#START_NOT_STICKY}</dt> + <dd>{@link android.app.Service#onStartCommand +onStartCommand()} から戻った後でシステムがサービスを強制終了した場合は、配信が保留中のインテントがない限りシステムはサービスを再作成<em>しません</em>。 +これは、サービスが不必要で、アプリケーションが未完了のジョブを再開できる場合にサービスを実行してしまうのを回避できる最も安全な選択肢です。 +</dd> + <dt>{@link android.app.Service#START_STICKY}</dt> + <dd>{@link android.app.Service#onStartCommand +onStartCommand()} から戻った後でシステムがサービスを強制終了した場合は、サービスを再作成し、{@link +android.app.Service#onStartCommand onStartCommand()} を呼び出しますが、最後のインテントは再配信<em>しません</em>。代わりに、サービスを開始するインテントが保留になっている場合を除いて、システムは {@link android.app.Service#onStartCommand onStartCommand()} を null インテントを使って呼び出します。保留中のインテントがある場合、そのインテントは配信されます。 + + +これは、コマンドは実行しないが、無期限に実行し、ジョブを待機するメディア プレーヤー(や同様のサービス)に適しています。 +</dd> + <dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt> + <dd>{@link android.app.Service#onStartCommand +onStartCommand()} から戻った後でシステムがサービスを強制終了した場合は、サービスを再作成し、サービスに最後に配信されたインテントで {@link +android.app.Service#onStartCommand onStartCommand()} を呼び出します。 +すべてのペンディング インテントが順に配信されます。これは、ファイルのダウンロードのような、活発にジョブを実行し、ただちに再開する必要のあるサービスに適しています。 +</dd> +</dl> +<p>これらの戻り値の詳細については、リンクされた各定数のリファレンス ドキュメントをご覧ください。 +</p> + + + +<h3 id="StartingAService">サービスを開始する</h3> + +<p>アクティビティや他のアプリケーション コンポーネントから {@link android.content.Intent}(開始するサービスを指定する)を {@link android.content.Context#startService startService()} に渡すことで、サービスを開始できます。 + +Android システムが、サービスの {@link +android.app.Service#onStartCommand onStartCommand()} メソッドを呼び出して、{@link +android.content.Intent} を渡します(絶対に、{@link android.app.Service#onStartCommand +onStartCommand()} を直接呼び出さないでください)。</p> + +<p>アクティビティが前のセクションで例に挙げたサービス({@code +HelloSevice})を、{@link android.content.Context#startService +startService()} で明示的インテントを使って開始する例を次に示します。</p> + +<pre> +Intent intent = new Intent(this, HelloService.class); +startService(intent); +</pre> + +<p>{@link android.content.Context#startService startService()} メソッドがすぐに戻り、Android システムがサービスの {@link android.app.Service#onStartCommand +onStartCommand()} メソッドを呼び出します。 +サービスがまだ実行されていない場合、システムはまず {@link +android.app.Service#onCreate onCreate()} を呼び出してから、{@link android.app.Service#onStartCommand +onStartCommand()} を呼び出します。</p> + +<p>サービスでバインドが提供されない場合は、{@link +android.content.Context#startService startService()} で配信されたインテントが、アプリケーション コンポーネントとサービス間の唯一の通信モードになります。 +ただし、サービスから結果を送り返す場合は、サービスを開始するクライアントがブロードキャスト用に {@link android.app.PendingIntent} を作成でき({@link android.app.PendingIntent#getBroadcast getBroadcast()} で)、それをサービスを開始する {@link android.content.Intent} のサービスに配信できます。 + + +その後、サービスはブロードキャストを使って結果を配信できます。 +</p> + +<p>サービスを開始する要求が複数ある場合は、それに対応する複数の呼び出しがサービスの {@link android.app.Service#onStartCommand onStartCommand()} に対して発生することになります。 +ただし、サービスを停止するために必要な要求({@link android.app.Service#stopSelf stopSelf()} や {@link +android.content.Context#stopService stopService()} を使用)は、1 つのみです。 +</p> + + +<h3 id="Stopping">サービスを停止する</h3> + +<p>開始されたサービスは、自身でライフサイクルを管理する必要があります。つまり、システムメモリを復元する必要がある場合を除き、システムがサービスを停止したり破棄したりすることはなく、サービスは {@link android.app.Service#onStartCommand onStartCommand()} から戻った後も実行し続けます。 + +そのため、サービスは {@link android.app.Service#stopSelf stopSelf()} を呼び出して自身で停止する必要があり、他のコンポーネントが {@link android.content.Context#stopService stopService()} を呼び出して停止することもできます。 + +</p> + +<p>{@link android.app.Service#stopSelf stopSelf()} や {@link +android.content.Context#stopService stopService()} で停止が要求されたら、システムは可能な限りすぐにサービスを破棄します。 +</p> + +<p>ただし、サービスが {@link +android.app.Service#onStartCommand onStartCommand()} への複数の要求を同時に処理している場合は、その後に新しい開始要求を受け取る可能性があることから、開始要求の処理後もサービスを停止しないでください(1 つ目の要求の最後に停止すると、2 つ目が停止されてしまいます)。 + +この問題を回避するには、{@link android.app.Service#stopSelf(int)} を使って、常に最新の開始要求に基づいてサービスの停止要求を行うようにできます。 + +具体的には、{@link +android.app.Service#stopSelf(int)} を呼び出すとき、停止要求に対応する開始要求の ID({@link android.app.Service#onStartCommand onStartCommand()} に配信された <code>startId</code>)を渡します。 + +その後、{@link +android.app.Service#stopSelf(int)} を呼び出す前にサービスが新しい開始要求を受け取ったとしても、結果的に ID が一致せずサービスが停止されなくなります。</p> + +<p class="caution"><strong>警告:</strong> アプリケーションはサービスの処理が完了したら、システムリソースやバッテリ電力の節約のため、サービスを停止することが重要です。 +必要であれば、他のコンポーネントから {@link +android.content.Context#stopService stopService()} を呼び出してサービスを停止することもできます。 +サービスのバインドを有効にしている場合でも、{@link +android.app.Service#onStartCommand onStartCommand()} を受け取ったときには常に自身でサービスを停止する必要があります。 +</p> + +<p>サービスのライフサイクルの詳細については、後半のセクションの<a href="#Lifecycle">サービスのライフサイクルを管理する</a>をご覧ください。</p> + + + +<h2 id="CreatingBoundService">バインドされたサービスを作成する</h2> + +<p>バインドされたサービスとは、アプリケーション コンポーネントが長時間の接続を作成するために {@link +android.content.Context#bindService bindService()} を呼び出してサービスにバインドできるようにするサービスです(通常はコンポーネントが {@link +android.content.Context#startService startService()} を呼び出すことではサービスは<em>開始</em>できません)。 +</p> + +<p>バインドされたサービスは、アプリケーションのアクティビティや他のコンポーネントからのサービスとやり取りしたり、アプリケーションの一部の機能をプロセス間通信(IPC)を用いて他のアプリケーションが利用できるようにしたりする場合に作成します。 + +</p> + +<p>バインドされたサービスを作成するには、{@link +android.app.Service#onBind onBind()} コールバック メソッドを実装して、サービスとの通信用のインターフェースを定義する {@link android.os.IBinder} を返す必要があります。 +その後、他のアプリケーション コンポーネントが {@link android.content.Context#bindService bindService()} を呼び出してインターフェースを取得し、サービスのメソッドの呼び出しを開始できます。 + +サービスは、バインドされているアプリケーション コンポーネントのためだけに存在するため、バインドされているコンポーネントがなくなると、サービスにシステムによって破棄されます(バインドされたサービスは、{@link android.app.Service#onStartCommand onStartCommand()} でサービスが開始されたときと同じ方法で停止する必要は<em>ありません</em>)。 + + +</p> + +<p>バインドされたサービスを作成するには、まずクライアントからサービスへの通信方法を指定するインターフェースを定義します。 +サービスとクライアント間のこのインターフェースは {@link android.os.IBinder} の実装である必要があり、サービスはこれを {@link android.app.Service#onBind +onBind()} コールバック メソッドから返す必要があります。 + +クライアントが {@link android.os.IBinder} を受け取ると、そのインターフェースを介してサービスとのやり取りを開始できます。 +</p> + +<p>複数のクライアントが同時にサービスにバインドできます。クライアントとサービスのやり取りが終わったら、{@link android.content.Context#unbindService unbindService()} を呼び出してアンバインドします。 +サービスにバインドされているクライアントがなくなったら、システムがサービスを破棄します。 +</p> + +<p>バインドされたサービスの実装方法はいくつかあり、その実装は開始されたサービスよりも複雑であるため、バインドされたサービスの詳細については、<a href="{@docRoot}guide/components/bound-services.html">バインドされたサービス</a> のドキュメントで別途説明しています。 + +</p> + + + +<h2 id="Notifications">ユーザーに通知を送信する</h2> + +<p>一旦サービスが実行されると、<a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">トースト通知</a>や<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">ステータスバー通知</a>を使ってユーザーにイベントを通知できます。</p> + +<p>トースト通知は、現在のウィンドウに表示されるメッセージで、少しの間表示され、すぐに消えます。一方、ステータスバー通知では、ステータスバーにメッセージの付いたアイコンが表示され、ユーザーはそれを選択して何らかの操作(アクティビティの開始など)を行うことができます。 + +</p> + +<p>通常は、バックグラウンド ワークが完了して、ユーザーが実行できる操作がある場合(ファイルのダウンロードが完了した場合など)は、ステータスバーの通知が最適なテクニックです。 + +展開したビューでユーザーが通知を選択すると、通知がアクティビティ(ダウンロードしたファイルを表示するなど)を開始できるようになります。 +</p> + +<p>詳細については、デベロッパー ガイドの「<a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">トースト通知</a>」や「<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">ステータスバーの通知</a>」をご覧ください。 +</p> + + + +<h2 id="Foreground">サービスをフォアグラウンドで実行する</h2> + +<p>フォアグラウンド サービスは、ユーザーがその存在を認識しているものであるとみなされるため、メモリ残量が少なくなった場合でも、システムによる強制終了の現候補にはなりません。 +フォアグラウンド サービスではステータスバーに通知を表示する必要があり、通知は「継続中」という見出しの下に表示されるため、サービスが停止するか、フォアグラウンドから除去しない限り通知を消すことはできないということになります。 + + +</p> + +<p>たとえば、サービスから音楽を再生する音楽プレーヤーは、ユーザーがその操作を認識しているのは明らかであるため、フォアグラウンドで実行する必要があります。 + +ステータスバーの通知には現在再生中の曲名を表示でき、ユーザーが音楽プレーヤーを操作するためのアクティビティを起動できるようにできます。 +</p> + +<p>サービスをフォアグラウンドで実行するよう要求するには、{@link +android.app.Service#startForeground startForeground()} を呼び出します。このメソッドは、通知を一意に識別する整数と、ステータスバーの {@link +android.app.Notification} の 2 つのパラメータを受け付けます。 +次に例を示します。</p> + +<pre> +Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), + System.currentTimeMillis()); +Intent notificationIntent = new Intent(this, ExampleActivity.class); +PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); +notification.setLatestEventInfo(this, getText(R.string.notification_title), + getText(R.string.notification_message), pendingIntent); +startForeground(ONGOING_NOTIFICATION_ID, notification); +</pre> + +<p class="caution"><strong>警告:</strong> {@link +android.app.Service#startForeground startForeground()} に渡す整数 ID には、0 は使用できません。</p> + + +<p>サービスをフォアグラウンドから除去するには、{@link +android.app.Service#stopForeground stopForeground()} を呼び出します。このメソッドでは、同時にステータスバーの通知も除去するかどうかを示すブール値を受け付けます。 +このメソッドでは、サービスは停止<em>されません</em>。 +ただし、サービスがまだフォアグラウンドで実行中に停止した場合は、通知も除去されます。 +</p> + +<p>通知の詳細については、「<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status Bar Notifications</a>」をご覧ください。 +</p> + + + +<h2 id="Lifecycle">サービスのライフサイクルを管理する</h2> + +<p>サービスのライフサイクルは、アクティビティのライフサイクルよりもはるかにシンプルです。ただし、サービスはバックグラウンドでサイレントに実行されるため、サービスがどのように作成され、破棄されるかについては、より一層の注意を払っておく必要があります。 + +</p> + +<p>作成されてから破棄されるまでのサービスのライフサイクルには、2 つの経路があります。—— +</p> + +<ul> +<li>開始されたサービスの場合 + <p>他のコンポーネントが {@link +android.content.Context#startService startService()} を呼び出したときにサービスが作成されます。その後サービスは無期限に実行し、{@link +android.app.Service#stopSelf() stopSelf()} を呼び出して自身で停止する必要があります。 +また、他のコンポーネントから {@link android.content.Context#stopService stopService()} を呼び出してサービスを停止することもできます。 + +サービスが停止すると、システムがそれを破棄します。</p></li> + +<li>バインドされたサービス + <p>他のコンポーネント(クライアント)が {@link +android.content.Context#bindService bindService()} を呼び出したときにサービスが作成されます。その後、クライアントが {@link android.os.IBinder} インターフェースを介してサービスとやり取りします。 +クライアントは、{@link android.content.Context#unbindService unbindService()} を呼び出して接続を終了できます。 +サービスには同時に複数のクライアントがバインドでき、すべてがアンバインドされると、サービスはシステムによって破棄されます +(サービスを自身で停止する必要は<em>ありません</em>)。 +</p></li> +</ul> + +<p>この 2 つの経路は、完全に分離しているわけではありません。つまり、{@link android.content.Context#startService startService()} で既に開始されたサービスにバインドすることも可能です。 +たとえば、{@link android.content.Context#startService +startService()} を呼び出してバックグラウンドの音楽サービスを開始し、{@link android.content.Intent} を使って再生する音楽を指定できます。 +その後、ユーザーがプレーヤーを操作したり、現在の曲に関する情報を入手したりする場合は、{@link +android.content.Context#bindService bindService()} を呼び出すことでアクティビティをサービスにバインドできます。 + +このような場合は、すべてのクライアントがアンバインドされるまで、{@link +android.content.Context#stopService stopService()} や {@link android.app.Service#stopSelf +stopSelf()} ではサービスは停止されません。 </p> + + +<h3 id="LifecycleCallbacks">ライフサイクル コールバックを実装する</h3> + +<p>アクティビティと同様に、サービスにもコールバック メソッドがあり、それを実装することでサービスの状態の変化を監視したり、適切なタイミングで処理を実行したりできます。 +次のスケルトン サービスは、それぞれのライフサイクル メソッドを表しています。 +</p> + +<pre> +public class ExampleService extends Service { + int mStartMode; // indicates how to behave if the service is killed + IBinder mBinder; // interface for clients that bind + boolean mAllowRebind; // indicates whether onRebind should be used + + @Override + public void {@link android.app.Service#onCreate onCreate}() { + // The service is being created + } + @Override + public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) { + // The service is starting, due to a call to {@link android.content.Context#startService startService()} + return <em>mStartMode</em>; + } + @Override + public IBinder {@link android.app.Service#onBind onBind}(Intent intent) { + // A client is binding to the service with {@link android.content.Context#bindService bindService()} + return <em>mBinder</em>; + } + @Override + public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) { + // All clients have unbound with {@link android.content.Context#unbindService unbindService()} + return <em>mAllowRebind</em>; + } + @Override + public void {@link android.app.Service#onRebind onRebind}(Intent intent) { + // A client is binding to the service with {@link android.content.Context#bindService bindService()}, + // after onUnbind() has already been called + } + @Override + public void {@link android.app.Service#onDestroy onDestroy}() { + // The service is no longer used and is being destroyed + } +} +</pre> + +<p class="note"><strong>注:</strong> アクティビティのライフサイクル コールバック メソッドの場合とは異なり、これらのコールバック メソッドのスーパークラスの実装を呼び出す必要は<em>ありません</em>。 +</p> + +<img alt="" src="images/hero/how-to-enter1.jpg" /> +<p class="img-caption"><strong>図 2.</strong> サービスのライフサイクル。左側の図は、{@link android.content.Context#startService +startService()} でサービスが作成されたときのライフサイクルを示し、右側の図は、{@link android.content.Context#bindService bindService()} でサービスが作成されたときのライフサイクルを示しています。 + +</p> + +<p>これらのメソッドを実装すると、サービスのライフサイクル内の次の 2 つのネストされたループを監視できます。 </p> + +<ul> +<li>サービスの<strong>全体の生存期間</strong>は、{@link +android.app.Service#onCreate onCreate()} が呼び出されてから、{@link +android.app.Service#onDestroy} から戻るまでの間です。アクティビティと同様に、サービスが {@link android.app.Service#onCreate onCreate()} で初期設定を行い、{@link +android.app.Service#onDestroy onDestroy()} で残りのすべてのリソースを解放します。 +たとえば、音楽再生サービスでは、音楽を再生するスレッドを {@link +android.app.Service#onCreate onCreate()} に作成して、停止するスレッドを {@link +android.app.Service#onDestroy onDestroy()} に作成します。 + + +<p>{@link android.app.Service#onCreate onCreate()} メソッドと {@link android.app.Service#onDestroy +onDestroy()} メソッドは、それが{@link android.content.Context#startService startService()} か {@link +android.content.Context#bindService bindService()} のどちらで作成された場合でも、すべてのサービスに対して呼び出されます。 +</p></li> + +<li>サービスの<strong>アクティブな生存期間</strong> {@link +android.app.Service#onStartCommand onStartCommand()} か {@link android.app.Service#onBind onBind()} のいずれかへの呼び出しから開始します。各メソッドには、{@link android.content.Context#startService +startService()} か {@link android.content.Context#bindService bindService()} のいずれかに渡された {@link +android.content.Intent} が渡されます。 + +<p>サービスが開始された場合、アクティブな生存期間の完了は、全体の生存期間の完了と同じタイミングとなります({@link android.app.Service#onStartCommand +onStartCommand()} から戻った後もサービスはまだアクティブです)。 +サービスがバインドされた場合、アクティブな生存期間は {@link +android.app.Service#onUnbind onUnbind()} から戻った時点で完了します。</p> +</li> +</ul> + +<p class="note"><strong>注:</strong> 開始されたサービスは、{@link android.app.Service#stopSelf stopSelf()} か {@link +android.content.Context#stopService stopService()} への呼び出しで停止されますが、サービスには同様のコールバックはありません({@code onStop()} コールバックがありません)。 + +そのため、サービスがクライアントにバインドされていない限り、サービスが停止するとシステムがそれを破棄します。受け取るコールバックは {@link +android.app.Service#onDestroy onDestroy()} のみです。 +—</p> + +<p>図 2 は、サービスの典型的なコールバック メソッドを表しています。この図では、{@link android.content.Context#startService startService()} で作成されたサービスと {@link android.content.Context#bindService bindService()} で作成されたサービスを分けていますが、開始方法にかかわらず、すべてのサービスがクライアントからバインドされる可能性があることに注意してください。つまり、当初は {@link android.app.Service#onStartCommand +onStartCommand()} で(クライアントが {@link android.content.Context#startService startService()} を呼び出した際)開始されたサービスも、{@link android.app.Service#onBind onBind()} への呼び出し(クライアントが {@link android.content.Context#bindService bindService()} を呼び出した際)を受け取ることができます。 + + + + + +</p> + +<p>バインドを提供するサービスの作成に関する詳細は、「<a href="{@docRoot}guide/components/bound-services.html">バインドされたサービス</a>」のドキュメントをご覧ください。このドキュメントの<a href="{@docRoot}guide/components/bound-services.html#Lifecycle">バインドされたサービスのライフサイクルを管理する</a>では、{@link android.app.Service#onRebind onRebind()} コールバックの詳細についても説明しています。 + + +</p> + + +<!-- +<h2>Beginner's Path</h2> + +<p>To learn how to query data from the system or other applications (such as contacts or media +stored on the device), continue with the <b><a +href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></b> +document.</p> +--> diff --git a/docs/html-intl/intl/ja/guide/components/tasks-and-back-stack.jd b/docs/html-intl/intl/ja/guide/components/tasks-and-back-stack.jd new file mode 100644 index 000000000000..12f5911da22e --- /dev/null +++ b/docs/html-intl/intl/ja/guide/components/tasks-and-back-stack.jd @@ -0,0 +1,578 @@ +page.title=タスクとバックスタック +parent.title=アクティビティ +parent.link=activities.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>本書の内容</h2> +<ol> +<li><a href="#ActivityState">アクティビティの状態を保存する</a></li></li> +<li><a href="#ManagingTasks">タスクを管理する</a> + <ol> + <li><a href="#TaskLaunchModes">起動モードを定義する</a></li> + <li><a href="#Affinities">アフィニティを処理する</a></li> + <li><a href="#Clearing">バックスタックをクリアする</a></li> + <li><a href="#Starting">タスクを開始する</a></li> + </ol> +</li> +</ol> + +<h2>記事</h2> +<ol> + <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html">Multitasking the Android Way</a> +</li> +</ol> + +<h2>関連ドキュメント</h2> +<ol> + <li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a> +</li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>} manifest element</a> +</li> + <li><a href="{@docRoot}guide/components/recents.html">オーバービュー画面</a></li> +</ol> +</div> +</div> + + +<p>通常、アプリケーションには複数の<a href="{@docRoot}guide/components/activities.html">アクティビティ</a>が含まれています。それぞれのアクティビティは、ユーザーが実行して、他のアクティビティを開始するといった特定のアクションを中心に設計されています。 + +たとえば、メール アプリケーションに新規メッセージ一覧を表示する 1 つのアクティビティがあるとします。ユーザーがメッセージを選択すると、そのメッセージを表示するための新しいアクティビティが開きます。 +</p> + +<p>アクティビティでは、端末上の他のアプリケーションに存在するアクティビティを開始することもできます。たとえば、アプリケーションがメールの送信を求める場合は、「送信」アクションを実行し、メールアドレスや本文などのデータを含めるインテントを定義できます。 + +その結果、この種のインテントの処理を宣言している別のアプリケーションのアクティビティが開きます。 +この場合、インテントはメールを送信することであるため、メール アプリケーションの「作成」アクティビティが開始されます(複数のアクティビティが同じインテントに対応している場合、システムはユーザーに選択を求めます)。 + +メールが送信されると、元のアクティビティが再開され、まるでメール アクティビティがそのアプリケーションの一部であるように見えます。 +アクティビティは異なるアプリケーションのものでも、Android は両方のアクティビティを同じ<em>タスク</em>内に保つことによって、このシームレスな操作性を維持しています。 + +</p> + +<p>タスクとは、ユーザーが特定の作業を行う時に情報のやり取りを行うアクティビティの集まりです。 +アクティビティは、各アクティビティが開かれた順にスタック(<em>バックスタック</em>)形式で配置されます。 +</p> + +<!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED +<div class="sidebox-wrapper"> +<div class="sidebox"> +<h3>Adding fragments to a task's back stack</h3> + +<p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example, +suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the +other being a layout to display an item from the list (fragment B). When the user selects an item +from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be +desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p> +<p>In order to add fragment B to the back stack so that this is possible, you must call {@link +android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link +android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment +C.</p> +<p>For more information about using fragments and adding them to the back stack, see the {@link +android.app.Fragment} class documentation.</p> + +</div> +</div> +--> + +<p>ほとんどのタスクは、端末のホーム画面から開始されます。ユーザーがアプリケーション ランチャーでアイコン(またはホーム画面のショートカット)にタッチすると、アプリケーションのタスクがフォアグラウンドに移動します。 + +アプリケーションにタスクが存在しない(アプリケーションが最近使われていない)場合は、新しいタスクが作成され、そのアプリケーションの「メイン」アクティビティがスタック内のルート アクティビティとして開きます。 + +</p> + +<p>現在のアクティビティが別のアクティビティを開始すると、新しいアクティビティがスタックの一番上にプッシュされ、アクティブになります。 +前のアクティビティはスタックに残りますが、停止されます。アクティビティが停止すると、システムはそのユーザー インターフェースの状態を維持します。 +ユーザーが [<em>戻る</em>] ボタンを押すと、現在のアクティビティがスタックの一番上から消え(アクティビティは破棄され)、前のアクティビティが再開します(UI は前の状態で復元されます)。 + + +スタック内のアクティビティが並べ替えられることはなく、スタック上にプッシュされるかスタックから消されるかのみです — 現在のアクティビティにより開始されるとスタック上にプッシュされ、ユーザーが [<em>戻る</em>] ボタンを押すと破棄されます。 + +このように、バックスタックは「後入れ先出し」オブジェクト構造となっています。 + +図 1 は、この動作を時系列に視覚化し、アクティビティとそれに伴うその時点でのバックスタックの状態を示したものです。 + +</p> + +<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" /> +<p class="img-caption"><strong>図 1.</strong>タスク内の新しいアクティビティがバックスタックにアイテムを追加するプロセスを示しています。 +ユーザーが [<em>戻る</em>] ボタンを押すと、現在のアクティビティは破棄され、前のアクティビティが再開します。 + +</p> + + +<p>ユーザーが続けて [<em>戻る</em>] ボタンを押すと、スタック内のアクティビティは消えていき、前のアクティビティが表示されます。最終的に、ユーザーはホーム画面(またはタスクの開始時に実行されていたアクティビティ)に戻ります。 + + +すべてのアクティビティがスタックから削除されると、タスクはなくなります。</p> + +<div class="figure" style="width:287px"> +<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p +class="img-caption"><strong>図 2.</strong> 2 つのタスク: タスク B がフォアグラウンドでユーザー操作を受け入れます。タスク A は再開されるまでバックグラウンドで待機します。 +</p> +</div> +<div class="figure" style="width:215px"> + <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p +class="img-caption"><strong>図 3.</strong> 1 つのアクティビティが複数回インスタンス化されます。</p> +</div> + +<p>タスクは結束した構成単位で、ユーザーが新しいタスクを開始したり [<em>ホーム</em>] ボタンを使ってホーム画面に移動したりすると「バックグラウンド」に移動できます。 +バックグラウンドでは、タスク内のすべてのアクティビティが停止されますが、タスクのバックスタックは元の状態を保ちます — 図 2 に示すように、別のタスクが行われている間、タスクはフォーカスを失った状態になります。 + + +タスクはその後「フォアグラウンド」に戻り、ユーザーは操作の続きを行うことができます。 +たとえば、現在のタスク(タスク A)のスタックに 3 つのアクティビティがあるとします。現在のアクティビティの下に 2 つのアクティビティがある状態です。 +ユーザーが [<em>ホーム</em>] ボタンを押し、アプリケーション ランチャーから新しいアプリケーションを起動します。 + +ホーム画面が表示されると、タスク A はバックグラウンドに移動します。 +新しいアプリケーションが起動すると、システムはそのアプリケーションのタスク(タスク B)を開始します。タスク B には独自のアクティビティ スタックがあります。 +アプリケーションの操作が終了すると、ユーザーはホームに戻り、タスク A を開始した元のアプリケーションを選択します。ここでタスク A はフォアグラウンドに移動します — 3 つのアクティビティはすべて元のままで、スタックの一番上にあるアクティビティが再開します。 + + + +この時点で、ユーザーはホームに移動してタスク B を開始したアプリケーションを選択して(または<a href="{@docRoot}guide/components/recents.html">オーバービュー画面</a>でアプリのタスクを選択して)タスク B に切り替えることもできます。これは、Android のマルチタスク操作の一例です。 + + + +</p> + +<p class="note"><strong>注:</strong> バックグラウンドには複数のタスクを一度に置くことができます。しかし、ユーザーが多数のバックグラウンド タスクを同時に実行すると、システムがメモリを回復するためにバックグラウンド アクティビティを破棄する場合があります。その結果、アクティビティの状態は失われます。<a href="#ActivityState">アクティビティの状態</a>セクションをご覧ください。 + + +</p> + +<p>バックスタック内のアクティビティが並べ替えられることはないため、アプリケーションが複数のアクティビティからの特定のアクティビティ開始を許可すると、(アクティビティの前のインスタンスを一番上に移動させるのではなく)そのアクティビティの新しいインスタンスが作成されてスタック上にプッシュされます。 + + +これによって、図 3 に示すように、アプリケーションの 1 つのアクティビティが(別のタスクからも)複数回インスタンス化される場合があります。 +この場合は、ユーザーが [<em>戻る</em>] ボタンを使って移動すると、アクティビティの各インスタンスが(UI の状態はそれぞれそのままで)開いた順に表示されます。 + + +しかし、1 つのアクティビティを何度もインスタンス化したくない場合は、この動作を修正できます。 +その方法については、後述のセクション<a href="#ManagingTasks">タスクを管理する</a>で説明します。</p> + + +<p>以下は、アクティビティとタスクのデフォルトの動作をまとめたものです。</p> + +<ul> + <li>アクティビティ A がアクティビティ B を開始すると、アクティビティ A は停止しますが、システムはその状態(スクロールの位置やフォームに入力されたテキストなど)を保持します。アクティビティ B が開いた状態でユーザーが [<em>戻る</em>] ボタンを押すと、アクティビティ A が再開し、その状態が復元されます。 + + +</li> + <li>ユーザーが [<em>ホーム</em>] ボタンを押してタスクを離れると、現在のアクティビティは停止し、そのタスクはバックグラウンドに移動します。 + +システムはタスク内のすべてのアクティビティの状態を保持します。後にユーザーがタスクを開始したランチャー アイコンを選択してタスクを再開すると、タスクはフォアグラウンドに移動し、スタックの一番上にあるアクティビティを開始します。 + +</li> + <li>ユーザーが [<em>戻る</em>] ボタンを押すと、現在のアクティビティはスタックから消え、破棄されます。 + +スタック内にある前のアクティビティが再開します。アクティビティが破棄された場合、システムはその状態を<em>保持しません</em>。 +</li> + <li>アクティビティは、別のタスクからでも複数回インスタンス化できます。</li> +</ul> + + +<div class="note design"> +<p><strong>ナビゲーション デザイン</strong></p> + <p>Android 上でのアプリ ナビゲーションの仕組みの詳細については、Android Design の「<a href="{@docRoot}design/patterns/navigation.html">Navigation</a>」ガイドをご覧ください。</p> +</div> + + +<h2 id="ActivityState">アクティビティの状態を保存する</h2> + +<p>上述のように、デフォルト動作では、システムはアクティビティが停止するとその状態を保持します。 +この方法では、ユーザーが前のアクティビティに戻ると、ユーザー インターフェースが前の状態のままで表示されます。 +しかし、コールバック メソッドを使って積極的にアクティビティの状態を保持することもできます。破棄されたアクティビティを再作成しなければならないことを考えると、アクティビティの状態は積極的に<strong>保持すべき</strong>です。 + +</p> + +<p>システムが(新しいアクティビティの開始時やバックグラウンドへのタスクの移動時などに)アクティビティの 1 つを停止している時にシステム メモリの回復が必要になると、システムはそのアクティビティを完全に破棄する可能性があります。 + +これにより、アクティビティの状態に関する情報が失われてしまいます。システムは、アクティビティがバックスタックに留まっていることは認識していますが、アクティビティがスタックの一番上に置かれるとアクティビティを(再開ではなく)再作成しなければなりません。 + + +ユーザーの作業内容が失われるのを回避するには、{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} コールバック メソッドをアクティビティに実装することによって、作業状態を積極的に保持する必要があります。 + + +</p> + +<p>アクティビティの状態の保存方法の詳細については、「<a href="{@docRoot}guide/components/activities.html#SavingActivityState">Activities</a>」ドキュメントをご覧ください。 +</p> + + + +<h2 id="ManagingTasks">タスクを管理する</h2> + +<p>上記のように、Android は、連続して開始されたすべてのアクティビティを同じタスクの「後入れ先出し」式スタックに置くことによって、タスクやバックスタックを管理します。この方法は、ほとんどのアプリケーションでうまく動作し、アクティビティがどのようにタスクに関連付けられ、どのようにバックスタックに置かれているのかを心配する必要はありません。 + + +しかし、通常の動作に割り込みたい場合もあります。 +アプリケーション内のアクティビティが開始された時に(現在のタスク内に置かれる代わりに)新しいタスクを開始させたり、アクティビティの開始時に(新しいインスタンスをバックスタックの一番上に作成する代わりに)アクティビティの既存インスタンスを前に持ってきたり、ユーザーがタスクを離れる時にルート アクティビティ以外のすべてのアクティビティをバックスタックからクリアする場合などが考えられます。 + + + +</p> + +<p><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> マニフェスト エレメントの属性と {@link android.app.Activity#startActivity startActivity()} に渡すインテント内のフラグを使って、これらの、さらに他の動作を実現できます。 + + +</p> + +<p>この件に関して、使用できる主な <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 属性には以下のものがあります。 +</p> + +<ul class="nolist"> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff"> {@code taskAffinity}</a> +</li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode"> {@code launchMode}</a> +</li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> {@code allowTaskReparenting}</a> +</li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear"> {@code clearTaskOnLaunch}</a> +</li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> {@code alwaysRetainTaskState}</a> +</li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish"> {@code finishOnTaskLaunch}</a> +</li> +</ul> + +<p>使用できる主なインテント フラグには以下のものがあります。</p> + +<ul class="nolist"> + <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li> + <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li> + <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li> +</ul> + +<p>以下のセクションでは、これらのマニフェスト属性とインテント フラグを使ってアクティビティをタスクに関連付ける方法とバックスタック内での動作を定義する方法を説明します。 +</p> + +<p>また、タスクとアクティビティの提示方法やオーバービュー画面での管理方法に関する考慮点について別途記載しています。 +詳細については、「<a href="{@docRoot}guide/components/recents.html">オーバービュー画面</a>」をご覧ください。 +通常、オーバービュー画面にタスクとアクティビティを提示する方法はシステムが定義できるよう許可し、この動作を変更する必要はありません。 +</p> + +<p class="caution"><strong>警告:</strong> ほとんどのアプリケーションはアクティビティとタスクに対するデフォルトの動作に割り込むべきではありません。 +アクティビティがデフォルトの動作を変更する必要があると判断した場合は、起動時と他のアクティビティやタスクからの [<em>戻る</em>] ボタンによる移動時のアクティビティのユーザビリティを慎重にテストする必要があります。ユーザーが想定する動作と競合する恐れのあるナビゲーション時の動作については必ずテストを行ってください。 + + +</p> + + +<h3 id="TaskLaunchModes">起動モードを定義する</h3> + +<p>起動モードでは、アクティビティの新しいインスタンスを現在のタスクに関連付ける方法を定義できます。 +次の 2 つの方法を使ってさまざまな起動モードを定義できます。</p> +<ul class="nolist"> + <li><a href="#ManifestForTasks">マニフェスト ファイルを使用する</a> + <p>マニフェスト ファイルにアクティビティを宣言する際に、開始時にアクティビティをタスクに関連付ける方法を指定できます。 +</li> + <li><a href="#IntentFlagsForTasks">インテント フラグを使用する</a> + <p>{@link android.app.Activity#startActivity startActivity()} を呼び出す際に、新しいアクティビティを現在のタスクに関連付ける方法(または関連付けるかどうか)を宣言する {@link android.content.Intent} にフラグを置くことができます。 + +</p></li> +</ul> + +<p>アクティビティ A がアクティビティ B を開始する場合、アクティビティ B は自身を現在のタスクに関連付ける方法(もしあれば)をマニフェストに定義し、アクティビティ A はアクティビティ B を現在のタスクに関連付ける方法を要求できます。 + +両方のアクティビティがアクティビティ B をタスクに関連付ける方法を定義している場合は、アクティビティ B の要求よりも(インテントに定義される)アクティビティ A の要求が優先されます。 + +</p> + +<p class="note"><strong>注:</strong> マニフェスト ファイルで使用できる起動モードの中にはインテントのフラグとして使用できないものもあります。同様に、インテントのフラグとして使用できる起動モードの中には、マニフェストで定義できないものもあります。 + +</p> + + +<h4 id="ManifestForTasks">マニフェスト ファイルを使用する</h4> + +<p>マニフェスト ファイルでアクティビティを宣言する際に、<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> エレメントの <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 属性を使ってアクティビティをタスクに関連付ける方法を定義できます。 + + +</p> + +<p><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 属性は、アクティビティをタスク内で起動する方法についての指示を定めます。 + +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code> 属性には、次の 4 つの起動モードを割り当てることができます。 + +</p> + +<dl> +<dt>{@code "standard"}(デフォルトのモード)</dt> + <dd>デフォルトの設定です。システムは、開始されたタスクからアクティビティの新しいインスタンスをタスク内に作成し、インテントを渡します。 +アクティビティは複数回インスタンス化できます。各インスタンスは異なるタスクに所属でき、1 つのタスクは複数のインスタンスを持つことができます。 +</dd> +<dt>{@code "singleTop"}</dt> + <dd>アクティビティのインスタンスが現在のタスクの一番上に既に存在する場合は、システムはアクティビティの新しいインスタンスを作成せずに、{@link android.app.Activity#onNewIntent onNewIntent()} メソッドを呼び出して、インテントをそのインスタンスに渡します。 + + +アクティビティは複数回インスタンス化できます。各インスタンスは異なるタスクに所属でき、1 つのタスクは複数のインスタンスを持つことができます(バックスタックの一番上にあるアクティビティがそのアクティビティの既存のインスタンスで<em>ない</em>場合のみ)。 + + + <p>たとえば、タスクのバックスタックがアクティビティ B、C、そしてアクティビティ D を一番上に持つルート アクティビティ A で構成されているとします(スタックは A-B-C-D で D が一番上)。 +D タイプのアクティビティにインテントが届きます。もし D の起動モードがデフォルトの {@code "standard"} である場合は、そのクラスの新しいインスタンスが起動し、スタックは A-B-C-D-D となります。しかし、D の起動モードが {@code "singleTop"} である場合は、スタックの一番上にある D の既存のインスタンスが {@link android.app.Activity#onNewIntent onNewIntent()} を介してインテントを受け取ります — この場合、スタックは A-B-C-D のままとなります。ただし、B タイプのアクティビティのインテントが届くと、その起動モードが {@code "singleTop"} であっても、B の新しいインスタンスがスタックに追加されます。 + + + + + +</p> + <p class="note"><strong>注:</strong> アクティビティの新しいインスタンスが作成されると、ユーザーは [<em>戻る</em>] ボタンを押して前のアクティビティに戻ることができます。 +しかし、アクティビティの既存のインスタンスが新しいインテントに対応すると、ユーザーは、新しいインテントが {@link android.app.Activity#onNewIntent onNewIntent()} で届く前の状態に [<em>戻る</em>] ボタンを押して戻ることはできません。 + + + + +</p> +</dd> + +<dt>{@code "singleTask"}</dt> + <dd>システムは新しいタスクを作成し、新しいタスクのルートにアクティビティをインスタンス化します。しかし、そのアクティビティのインスタンスが別のタスクに既に存在する場合は、システムは新しいインスタンスを作成せずに、{@link android.app.Activity#onNewIntent onNewIntent()} メソッドを呼び出して、インテントを既存のインスタンスに渡します。 + + +同時に存在できるアクティビティのインスタンスは 1 つだけです。 + + <p class="note"><strong>注:</strong> アクティビティは新しいタスク内で開始されますが、ユーザーは [<em>戻る</em>] ボタンを押して前のアクティビティに戻ることができます。 +</p></dd> +<dt>{@code "singleInstance"}</dt> + <dd>システムが、他のアクティビティをインスタンスを保持しているタスクで起動しないことを除いて {@code "singleTask"} と同じです。 +アクティビティは、常にタスクの唯一の構成要素となります。このアクティビティによって開始されたアクティビティは別のタスクで開きます。 +</dd> +</dl> + + +<p>たとえば、Android Browser アプリケーションは、<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> エレメントの {@code singleTask} 起動モードを指定することによって、ウェブブラウザ アクティビティを常に自身のタスクで開くことを宣言しています。これは、開発されたアプリケーションが Android Browser を開くインテントを発行すると、そのアクティビティがアプリケーションのタスクには配置<em>されない</em>ことを意味します。 + + + +代わりに、Android Browser の新しいタスクが開始されるか、Android Browser に既に実行中のバックグラウンド タスクがある場合は、そのタスクがフォアグラウンドに移動し、新しいインテントに対応します。 + +</p> + +<p>アクティビティを新しいタスク内で開始するかアクティビティを起動したアクティビティと同じタスクで開始するかにかかわらず、ユーザーは [<em>戻る</em>] ボタンを押して前のアクティビティに戻ることができます。 +ただし、{@code singleTask} 起動モードを設定したアクティビティを開始し、そのアクティビティのインスタンスがバックグラウンド タスクに存在する場合は、そのタスク全体がフォアグラウンドに移動します。 + +この時点で、バックスタックの一番上に、フォアグラウンドに移動したタスクのすべてのアクティビティが含まれてます。 + +図 4 は、このタイプのシナリオを示しています。</p> + +<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" /> +<p class="img-caption"><strong>図 4.</strong>「singleTask」起動モードを持つアクティビティをバックスタックに追加する方法を示しています。 +アクティビティが自身のバックスタックを持つバックグラウンド タスクの一部である場合は、バックスタック全体がフォアグラウンドに移動し、現在のタスクの上に置かれます。 + +</p> + +<p>マニフェスト ファイルでの起動モードの使用の詳細については、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> エレメントのドキュメントをご覧ください。{@code launchMode} 属性と利用できる値について詳しく説明しています。 + + +</p> + +<p class="note"><strong>注:</strong> 次のセクションで説明しますが、<a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 属性を使ってアクティビティに指定する動作は、アクティビティを開始するインテントに含まれるフラグによって上書きされる場合があります。 + +</p> + + + +<h4 id="#IntentFlagsForTasks">インテント フラグを使用する</h4> + +<p>アクティビティの開始時に、{@link android.app.Activity#startActivity startActivity()} に渡すインテントにフラグを含めることによってアクティビティとタスクのデフォルトの関連付けを変更できます。 + +以下は、デフォルトの動作を変更するために使用できるフラグです。 +</p> + +<p> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt> + <dd>新しいタスクでアクティビティを開始します。開始しようとしているアクティビティに対してタスクが既に実行されている場合は、そのタスクの最新の状態が復元されてフォアグラウンドに移動し、アクティビティが {@link android.app.Activity#onNewIntent onNewIntent()} で新しいインテントを受け取ります。 + + + <p>この手順は、上述のセクションで説明した {@code "singleTask"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> の値の動作と同じものです。 +</p></dd> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt> + <dd>開始されるアクティビティが(バックスタックの一番上にある)現在のアクティビティである場合は、アクティビティの新しいインスタンスを作成する代わりに、既存のインスタンスが {@link android.app.Activity#onNewIntent onNewIntent()} の呼び出しを受け取ります。 + + + <p>この手順は、上述のセクションで説明した {@code "singleTop"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> の値の動作と同じものです。 +</p></dd> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt> + <dd>開始されるアクティビティが既に現在のタスクを実行している場合は、そのアクティビティの新しいインスタンスを起動する代わりに、上に置かれたその他すべてのアクティビティを破棄し、{@link android.app.Activity#onNewIntent onNewIntent()} を介してこのインテントを(一番上に移動した)アクティビティの再開されたインスタンスに渡します。 + + + + <p>この動作を起こす <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 属性には値はありません。 +</p> + <p>ほとんどのケースで {@code FLAG_ACTIVITY_CLEAR_TOP} は {@code FLAG_ACTIVITY_NEW_TASK} と併用されます。同時に使用することで、これらのフラグは、別のタスクにある既存のアクティビティを捜し出し、インテントに対応できる位置に置く手段を提供します。 + + + </p> + <p class="note"><strong>注:</strong> 指定されたアクティビティの起動モードが {@code "standard"} である場合は、やはりスタックから削除されます。その場所に、渡されるインテントに対応する新しいインスタンスが開始されます。 + + +これは、起動モードが {@code "standard"} である場合は、新しいインテントに対して常に新しいインスタンスが作成されるためです。 + </p> +</dd> +</dl> + + + + + +<h3 id="Affinities">アフィニティを処理する</h3> + +<p><em>アフィニティ</em>は、アクティビティの所属が望ましいタスクを示します。 デフォルトでは、同じアプリケーションのすべてアクティビティに相互のアフィニティが設定されています。 +このため、同じアプリケーションのすべてのアクティビティは、デフォルトで同じタスクに属します。 +しかし、アクティビティのデフォルトのアフィニティは変更できます。 +異なるアプリケーションに定義されているアクティビティがアフィニティを共有したり、同じアプリケーションに定義されたアクティビティに別のタスクのアフィニティを割り当てたりすることができます。 + +</p> + +<p><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> エレメントの <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 属性を使って、任意のアクティビティのアフィニティを変更できます。 + +</p> + +<p><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 属性には文字列を指定します。これは、<a href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code <manifest>}</a> エレメントに宣言されたデフォルトのパッケージ名とは異なる一意のものでなければなりません。理由は、システムがアプリケーションに対するデフォルトのタスク アフィニティを識別するためにこの名前を使用するためです。 + + + + +</p> + +<p>アフィニティは、以下の 2 つの状況で役立ちます。</p> +<ul> + <li>アクティビティを開始するインテントが {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} フラグを含んでいる場合 + + + +<p>新しいアクティビティは、デフォルトで、{@link android.app.Activity#startActivity startActivity()} を呼び出したアクティビティのタスクで開始されます。 +呼び出し元と同じバックスタックにプッシュされます。 +しかし、{@link android.app.Activity#startActivity startActivity()} に渡されたインテントに {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} フラグが含まれると、システムは新しいアクティビティを収容する別のタスクを捜します。 + + +これは、通常新しいタスクですが、新しいタスクである必要はありません。 +新しいアクティビティとして同じアフィニティを持つ既存のタスクが存在する場合は、アクティビティはそのタスクで開始されます。 +存在しない場合は、新しいタスクを開始します。</p> + +<p>このフラグによってアクティビティが新しいタスクを開始し、ユーザーが [<em>ホーム</em>] ボタンを押してタスクを離れる場合には、ユーザーがそのタスクに戻るための手段が必要です。 + +エンティティの中には(通知マネージャーなど)、自身の一部としてではなく、常に外部タスクでアクティビティを開始するものがあります。そのために、これらのエンティティが {@link android.app.Activity#startActivity startActivity()} に渡すインテントには常に {@code FLAG_ACTIVITY_NEW_TASK} が含まれます。このフラグを使った外部エンティティにより起動される可能性があるアクティビティがある場合は、起動アイコンなどを使って、アクティビティが開始したタスクにユーザーが戻れるよう独立した手段を確保します。(タスクのルート アクティビティには {@link android.content.Intent#CATEGORY_LAUNCHER} インテント フィルタがあります。後述の<a href="#Starting">タスクを開始する</a>セクションをご覧ください)。 + + + + + + +</p> +</li> + + <li>アクティビティの <a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code allowTaskReparenting}</a> 属性が {@code "true"} に設定されている場合。 + + <p>この場合は、タスクがフォアグラウンドに移動した時に、アクティビティは自身が開始したタスクから、アフィニティがあるタスクへと移動できます。 +</p> + <p>たとえば、選ばれた都市の天気を予報するアクティビティが旅行アプリケーションの一部として定義されているケースを考えてみましょう。 +このアクティビティは、アプリケーション内のその他のアクティビティと同じアフィニティ(デフォルトのアプリケーション アフィニティ)を持ち、この属性による親への再割り当てが許可されています。いずれかのアクティビティにより開始された天気予報アクティビティは、最初はそのアクティビティと同じタスクに属しています。 + + +しかし、旅行アプリケーションのタスクがフォアグラウンドに移動すると、天気予報アクティビティはそのタスクに再度割り当てられ、タスク内に表示されます。 +</p> +</li> +</ul> + +<p class="note"><strong>ヒント:</strong> {@code .apk} ファイルがユーザーの視点で 1 つ以上の「アプリケーション」を含んでいる場合は、各「アプリケーション」に関連付けられたアクティビティに <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 属性を使って異なるアフィニティを割り当てることをお勧めします。 + +</p> + + + +<h3 id="Clearing">バックスタックをクリアする</h3> + +<p>ユーザーがタスクを長時間離れると、システムはルート アクティビティを除くすべてのアクティビティをタスクからクリアします。 +ユーザーが再びタスクに戻ると、ルート アクティビティのみが復元されます。システムがこの動作を行うのは、しばらく時間が経過した後は、ユーザーが前に行っていた作業を放棄した可能性が高く、新しいことを始めるためにタスクに戻ったとみなされるためです。 + + </p> + +<p>この動作を変更するために、以下のアクティビティ属性を使用できます。 </p> + +<dl> +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code> +</dt> +<dd>タスクのルート アクティビティでこの属性が {@code "true"} に設定されていると、上記のデフォルトの動作は発生しません。長時間が経過しても、タスクはすべてのアクティビティをスタックに保持します。 + +</dd> + +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt> +<dd>タスクのルート アクティビティでこの属性が {@code "true"} に設定されている場合、ユーザーがタスクを離れて戻るたびに、スタックがルート アクティビティまでクリアされます。 + +つまり、<a href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code alwaysRetainTaskState}</a> の逆の動作となります。 + +ユーザーがタスクをほんの少しの間離れた場合でも、タスクは常に初期状態に戻ります。 +</dd> + +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code> +</dt> +<dd>この属性は、<a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a> に似ていますが、タスク全体ではなく 1 つのアクティビティに作用します。 + +ルート アクティビティを含むあらゆるアクティビティを消すことができます。 +この属性が {@code "true"} に設定されていると、アクティビティは現在のセッションが開かれている間のみタスクの一部として留まります。 +ユーザーがタスクから離れて戻ると、アクティビティは消えています。 +</dd> +</dl> + + + + +<h3 id="Starting">タスクを開始する</h3> + +<p>指定するアクションとして {@code "android.intent.action.MAIN"}、指定するカテゴリとして {@code "android.intent.category.LAUNCHER"} を持つインテント フィルタを付加することによって、アクティビティをタスクのエントリ ポイントとして設定できます。 + + +次に例を示します。</p> + +<pre> +<activity ... > + <intent-filter ... > + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + ... +</activity> +</pre> + +<p>この種類のインテント フィルタを使うことによって、アクティビティのアイコンとラベルがアプリケーション ランチャーに表示されるようになります。これにより、ユーザーは、アクティビティを起動し、アクティビティの起動後は、作成されたタスクにいつでも戻ることができるようになります。 + + +</p> + +<p>ユーザーがタスクを離れた後に、このアクティビティ ランチャーを使って戻ってくることが可能でなければならないため、2 番目の機能が重要になります。 +アクティビティが {@link android.content.Intent#ACTION_MAIN} と {@link android.content.Intent#CATEGORY_LAUNCHER} フィルタを持つ場合のみに、アクティビティが常にタスクを開始することを示す {@code "singleTask"} と {@code "singleInstance"} の 2 つの<a href="#LaunchModes">起動モード</a>を使用すべきなのはこのためです。 + + + +たとえば、フィルタがない場合にどうなるのかを想像してみてください。 +インテントが {@code "singleTask"} アクティビティを起動し、新しいタスクを開始し、ユーザーがそのタスクでしばらくの間作業を行います。 +その後、ユーザーは [<em>ホーム</em>] ボタンを押します。 +タスクはバックグラウンドに移動し、見えなくなります。タスクはアプリケーション ランチャーに表示されていないため、この状態ではユーザーがタスクに戻る手段がありません。 +</p> + +<p>ユーザーがアクティビティに戻るのを防ぐには、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> エレメントの <a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a> を {@code "true"} に設定します(<a href="#Clearing">スタックをクリアする</a>をご覧ください)。 + + + +</p> + +<p>オーバービュー画面でのタスクとアクティビティの表示方法と管理方法の詳細については、「<a href="{@docRoot}guide/components/recents.html">オーバービュー画面</a>」をご覧ください。 + +</p> + +<!-- +<h2>Beginner's Path</h2> + +<p>For more information about how to use intents to +activate other application components and publish the intents to which your components +respond, continue with the <b><a +href="{@docRoot}guide/components/intents-filters.html">Intents and Intent +Filters</a></b> document.</p> +--> diff --git a/docs/html-intl/intl/ja/guide/index.jd b/docs/html-intl/intl/ja/guide/index.jd new file mode 100644 index 000000000000..07688b63ec20 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/index.jd @@ -0,0 +1,74 @@ +page.title=Android 入門 + +@jd:body + + +<div class="sidebox" style="width:220px"><!-- width to match col-4 below --> +<p>アプリの動作方法について学ぶには、「<a href="{@docRoot}guide/components/fundamentals.html">App Fundamentals</a>」をご覧ください。 +</p> +<p>今すぐコーディングを始める場合は、「<a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>」をご覧ください。</p> +</div> + +<p>Android は、モバイル端末用の画期的なアプリやゲームを Java 言語環境でビルドできる、充実したアプリケーション フレームワークを提供します。 +左側のナビゲーションに表示されているドキュメントには、さまざまな Android API を使ってアプリをビルドする詳しい方法が記載されています。 +</p> + +<p>Android 開発の経験がない場合は、Android アプリのフレームワークについて次の基本的な概念を理解していることが重要になります。 +</p> + + +<div class="landing-banner"> + +<div class="col-6"> + +<h4>アプリには複数のエントリ ポイントがある</h4> + +<p>Android のアプリは、個別に呼び出し可能な異なるコンポーネントを組み合わせてビルドされます。 +たとえば、1 つの<em>アクティビティ</em>が 1 つの画面でユーザー インターフェースを提供し、<em>サービス</em>がバックグラウンドで個別に処理を実行します。 + +</p> + +<p><em>インテント</em>を使って、1 つのコンポーネントから別のコンポーネントを開始できます。地図アプリで住所を表示するアクティビティなどのように、別のアプリでコンポーネントを開始することもできます。 +このモデルでは、1 つのアプリに複数のエントリ ポイントを提供し、あらゆるアプリを他のアプリが呼び出すアクションの「デフォルト」として動作させることができます。 + +</p> + + +<p><b>詳細を見る</b></p> +<ul class="nolist"> +<li><a href="{@docRoot}guide/components/fundamentals.html">App Fundamentals</a> +<li><a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a> +<li><a href="{@docRoot}guide/components/activities.html">Activities</a> +</ul> + +</div> + + +<div class="col-6"> + +<h4>さまざまな端末に対応するアプリ</h4> + +<p>Android は、さまざまな端末の構成に独自のリソースを提供できる柔軟なアプリ フレームワークを提供します。 +たとえば、画面サイズごとに個別の XML レイアウト ファイルを作成し、システムが使用中の端末の画面サイズに基づいて適用するレイアウトを決定します。 + +</p> + +<p>アプリの機能に特定のハードウェア(カメラなど)が必要な場合は、実行時に端末機能の使用可能状況をクエリできます。 +必要に応じて、アプリに必要な機能を宣言することもできます。これによって、Google Play ストアなどのアプリ マーケットでは、宣言した機能に対応していない端末へのインストールが許可されません。 + +</p> + + +<p><b>詳細を見る</b></p> +<ul class="nolist"> +<li><a href="{@docRoot}guide/practices/compatibility.html">Device Compatibility</a> +<li><a href="{@docRoot}guide/topics/resources/overview.html">リソースの概要</a> +<li><a href="{@docRoot}guide/topics/ui/overview.html">ユーザー インターフェースの概要</a> +</ul> + +</div> + +</div><!-- end landing-banner --> + + + diff --git a/docs/html-intl/intl/ja/guide/topics/manifest/manifest-intro.jd b/docs/html-intl/intl/ja/guide/topics/manifest/manifest-intro.jd new file mode 100644 index 000000000000..7d9e8ac588f8 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/manifest/manifest-intro.jd @@ -0,0 +1,517 @@ +page.title=アプリ マニフェスト +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>本書の内容</h2> +<ol> +<li><a href="#filestruct">マニフェスト ファイルの構造</a></li> +<li><a href="#filec">ファイルの規則</a> +<li><a href="#filef">ファイルの特徴</a> + <ol> + <li><a href="#ifs">インテント フィルタ</a></li> + <li><a href="#iconlabel">アイコンとラベル</a></li> + <li><a href="#perms">パーミッション</a></li> + <li><a href="#libs">ライブラリ</a></li> + </ol></li> +</ol> +</div> +</div> + +<p> + すべてのアプリケーションには、そのルート ディレクトリに AndroidManifest.xml ファイル(名前はこのまま)が必要です。 + <span itemprop="description">マニフェスト ファイルはアプリに関する重要な情報を Android システムに提示します。これは、システムがアプリのコードを実行する前に必要な情報です。 + + +</span> その他、マニフェスト ファイルでは次のことを行います。 +</p> + +<ul> +<li>アプリケーションの Java パッケージ名を指定します。パッケージ名は、アプリケーションの一意の識別子としての機能を果たします。 +</li> + +<li>アプリケーションのコンポーネント(アプリケーションを構成するアクティビティ、サービス、ブロードキャスト レシーバー、コンテンツ プロバイダ)を記述します。 + +各コンポーネントを実装するクラスの名前を指定し、その機能(対応可能な {@link android.content.Intent Intent} メッセージなど)を公開します。 + +これらの宣言によって、Android システムは、どんなコンポーネントがあり、それらのコンポーネントがどのような条件で起動されるのかを把握できます。 +</li> + +<li>アプリケーション コンポーネントをホストするプロセスを決定します。</li> + +<li>アプリケーションが API の保護された部分にアクセスしたり他のアプリケーションとやり取りしたりする際に必要となるパーミッションを宣言します。 +</li> + +<li>他のアプリケーションがアプリケーションのコンポーネントとやり取りするために必要なパーミッションを宣言します。 +</li> + +<li>アプリケーションの実行時にプロファイリングやその他の情報を提供する {@link android.app.Instrumentation} クラスを記載します。 +これらの宣言は、アプリケーションの開発時やテスト時にのみマニフェストに含まれ、アプリケーションの公開前に削除されます。 + +</li> + +<li>アプリケーションに必要な Android API の最小限のレベルを宣言します。 +</li> + +<li>アプリケーションにリンクする必要があるライブラリを記載します。</li> +</ul> + + +<h2 id="filestruct">マニフェスト ファイルの構造</h2> + +<p> +次の図は、マニフェスト ファイルの一般的な構造とファイルに含むことができるすべてのエレメントを示します。 +各エレメントとそれぞれの属性はすべて別のファイルに記述されます。 +エレメントの詳細を見るには、図中、図の下にあるアルファベット順のエレメント一覧、またはその他の説明文に表示されているエレメント名をクリックしてください。 + + + +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> + +<a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a> + + <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission /></a> + <a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission /></a> + <a href="{@docRoot}guide/topics/manifest/permission-tree-element.html"><permission-tree /></a> + <a href="{@docRoot}guide/topics/manifest/permission-group-element.html"><permission-group /></a> + <a href="{@docRoot}guide/topics/manifest/instrumentation-element.html"><instrumentation /></a> + <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><uses-sdk /></a> + <a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html"><uses-configuration /></a> <!-- ##api level 3## --> + <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><uses-feature /></a> <!-- ##api level 4## --> + <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html"><supports-screens /></a> <!-- ##api level 4## --> + <a href="{@docRoot}guide/topics/manifest/compatible-screens-element.html"><compatible-screens /></a> <!-- ##api level 9## --> + <a href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html"><supports-gl-texture /></a> <!-- ##api level 11## --> + + <a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a> + + <a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a> + <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a> + <a href="{@docRoot}guide/topics/manifest/action-element.html"><action /></a> + <a href="{@docRoot}guide/topics/manifest/category-element.html"><category /></a> + <a href="{@docRoot}guide/topics/manifest/data-element.html"><data /></a> + <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"></intent-filter></a> + <a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data /></a> + <a href="{@docRoot}guide/topics/manifest/activity-element.html"></activity></a> + + <a href="{@docRoot}guide/topics/manifest/activity-alias-element.html"><activity-alias></a> + <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"></intent-filter></a> + <a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data /></a> + <a href="{@docRoot}guide/topics/manifest/activity-alias-element.html"></activity-alias></a> + + <a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a> + <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"></intent-filter></a> + <a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data/></a> + <a href="{@docRoot}guide/topics/manifest/service-element.html"></service></a> + + <a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a> + <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"></intent-filter></a> + <a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data /></a> + <a href="{@docRoot}guide/topics/manifest/receiver-element.html"></receiver></a> + + <a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a> + <a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"><grant-uri-permission /></a> + <a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data /></a> + <a href="{@docRoot}guide/topics/manifest/path-permission-element.html"><path-permission /></a> + <a href="{@docRoot}guide/topics/manifest/provider-element.html"></provider></a> + + <a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><uses-library /></a> + + <a href="{@docRoot}guide/topics/manifest/application-element.html"></application></a> + +<a href="{@docRoot}guide/topics/manifest/manifest-element.html"></manifest></a> +</pre> + +<p> +以下は、マニフェスト ファイルに含むことができるすべてのエレメントをアルファベット順に並べたものです。 +使用が許可されているのはこれらのエレメントのみです。独自のエレメントや属性は追加できません。 + +</p> + +<p style="margin-left: 2em"> +<code><a href="{@docRoot}guide/topics/manifest/action-element.html"><action></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html"><activity-alias></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/category-element.html"><category></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/data-element.html"><data></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"><grant-uri-permission></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/instrumentation-element.html"><instrumentation></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html"><permission-group></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html"><permission-tree></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/supports-screens-element.html"><supports-screens></a></code> <!-- ##api level 4## --> +<br/><code><a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html"><uses-configuration></a></code> <!-- ##api level 3## --> +<br/><code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><uses-feature></a></code> <!-- ##api level 4## --> +<br/><code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><uses-library></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> +<br/><code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><uses-sdk></a></code> +</p> + + + + +<h2 id="filec">ファイルの規則</h2> + +<p> +マニフェスト ファイルに含まれるエレメントと属性には、通常、次の規則とルールが適用されます。 + +</p> + +<dl> +<dt><b>エレメント</b></dt> +<dd>必須のエレメントは<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> と <code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> のみです。両方のエレメントを提示する必要があり、使用できるのはそれぞれ 1 回のみです。 + + +その他のほとんどのエレメントは、複数回使ってもまったく使わなくてもかまいませんが、意味のあるマニフェストを行うにはいくつかのエレメントが必要です。 + + + + +<p> +内容のあるエレメントには他のエレメントが含まれているためです。すべての値は属性によって設定され、エレメント内に文字データが設定されることはありません。 + +</p> + +<p> +同じレベルにあるエレメントに順番はありません。たとえば、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> や <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code>、<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code> エレメントは、どのような順で並べてもかまいません。 + + + +(<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html"><activity-alias></a></code> エレメントは例外となります。 + +エイリアスとなっている <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> のすぐ後に記述する必要があります)。 + + +</p></dd> + +<dt><b>属性</b></dt> +<dd>正式には、すべての属性はオプションです。しかし、エレメントが目的を達成するために設定しなければならない属性もあります。 +このドキュメントはガイドとしてお使いください。 +真の意味でオプションの属性には、デフォルト値または指定がない場合の動作が記述されています。 + + +<p>ルートの <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> エレメントの属性の一部を除き、すべての属性名は {@code android:} 接頭辞で始まります(例: {@code android:alwaysRetainTaskState})。 + + +この接頭辞は共通であるため、ドキュメントで属性が名前で参照されている場合は通常省略されます。 + +</p></dd> + +<dt><b>クラス名の宣言</b></dt> +<dd>多くのエレメントは Java オブジェクトと一致しています。これらのエレメントには、アプリケーション自体(<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> エレメント)とその主要なコンポーネントであるアクティビティ(<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>)、サービス(<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>)、ブロードキャスト レシーバー(<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code>)やコンテンツ プロバイダ(<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code>)が含まれます。 + + + + + + + + + + + +<p> +サブクラスを定義する場合は、コンポーネント クラス({@link android.app.Activity}、{@link android.app.Service}、{@link android.content.BroadcastReceiver}、{@link android.content.ContentProvider})でいつも行うように、サブクラスは {@code name} 属性で宣言されます。 + + +この名前には、完全なパッケージ名を含む必要があります。 +たとえば、{@link android.app.Service} サブクラスの宣言は以下のようになります。 + +</p> + +<pre><manifest . . . > + <application . . . > + <service android:name="com.example.project.SecretService" . . . > + . . . + </service> + . . . + </application> +</manifest></pre> + +<p> +ただし、簡素化する方法として、文字列の最初の文字がピリオドの場合、文字列はアプリケーションのパッケージ名に付加されます(<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> エレメントの <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html#package">package</a></code> 属性によって指定されるため)。 + + + + +以下は、上記のものと同じ内容です。 +</p> + +<pre><manifest package="com.example.project" . . . > + <application . . . > + <service android:name=".SecretService" . . . > + . . . + </service> + . . . + </application> +</manifest></pre> + +<p> +コンポーネントの開始時に、Android は名前が指定されたサブクラスのインスタンスを作成します。サブクラスが指定されていない場合は、基底クラスのインスタンスを作成します。 + +</p></dd> + +<dt><b>複数の値</b></dt> +<dd>1 つ以上の値が指定されている場合は、1 つのエレメントに複数の値が記載されているのではなく、エレメントが繰り返されているケースがほとんどです。 +たとえば、インテント フィルタには複数のアクションが記載されている場合があります。 + + +<pre><intent-filter . . . > + <action android:name="android.intent.action.EDIT" /> + <action android:name="android.intent.action.INSERT" /> + <action android:name="android.intent.action.DELETE" /> + . . . +</intent-filter></pre></dd> + +<dt><b>リソースの値</b></dt> +<dd>属性には、ユーザーに対して表示する値を含むものもあります。たとえば、アクティビティのラベルやアイコンです。 +これらの属性の値は、ローカライズされていなければならないため、リソースまたはテーマから設定する必要があります。 +リソースの値は、以下の形式で記述されます。 +</p> + +<p style="margin-left: 2em">{@code @[<i>package</i>:]<i>type</i>:<i>name</i>}</p> + +<p> +リソースがアプリケーションと同じパッケージ内にある場合は package 名を省略できます。type はリソースのタイプ(「string」や「drawable」など)、name は特定のリソースの名前です。<i></i> +<i></i> +<i></i>次に例を示します。 + +</p> + +<pre><activity android:icon="@drawable/smallPic" . . . ></pre> + +<p> +テーマからの値も同様の方法で表記されますが、冒頭は '{@code @}' ではなく '{@code ?}' となります。 + +</p> + +<p style="margin-left: 2em">{@code ?[<i>package</i>:]<i>type</i>:<i>name</i>} +</p></dd> + +<dt><b>文字列の値</b></dt> +<dd>属性値が文字列で文字をエスケープする場合はダブル バックスラッシュ('{@code \\}')を使う必要があります。たとえば、改行は '{@code \\n}'、Unicode の文字は '{@code \\uxxxx}' となります。 + +</dd> +</dl> + + +<h2 id="filef">ファイルの特徴</h2> + +<p> +以下のセクションでは、Android の機能がどのようにマニフェスト ファイルに反映されるのかを説明します。 + +</p> + + +<h3 id="ifs">インテント フィルタ</h3> + +<p> +アプリケーションのコア コンポーネント(アクティビティ、サービス、ブロードキャスト レシーバー)はインテントによって開始されます。 +<i></i>インテントとは、目的とするアクションを記述している情報の束({@link android.content.Intent} オブジェクト)で、使用されるデータやアクションを実行するコンポーネントのカテゴリ、その他の関連する指示を含みます。 + + +Android は、インテントに対応する適切なコンポーネントを捜し出し、必要に応じて新しいインスタンスを起動し、それにインテント オブジェクトを渡します。 + + + +</p> + +<p> +コンポーネントはインテント フィルタを使ってその機能(対応できるインテントの種類)を通知します。 +<i></i>Android システムはコンポーネントを起動する前にコンポーネントが対応できるインテントを知っておく必要があるため、インテント フィルタはマニフェスト ファイルの <code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code> エレメントで指定されます。 + + + +コンポーネントは、それぞれが異なる機能を記述しているフィルタをいくつでも持つことができます。 + +</p> + +<p> +対象となるコンポーネントの名前を明示的に指定しているインテントは、コンポーネントを起動します。この場合、フィルタは適用されません。 +対象の名前が指定されていない場合は、コンポーネントのフィルタを通過したインテントのみがコンポーネントを起動できます。 + + +</p> + +<p> +インテント フィルタに対してインテント オブジェクトをテストする方法については、「<a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a>」ドキュメントをご覧ください。 + + + +</p> + + +<h3 id="iconlabel">アイコンとラベル</h3> + +<p> +エレメントは、小さなアイコンやテキスト ラベルをユーザーに表示するために、{@code icon} と {@code label} 属性を持つ場合があります。 +画面に長い説明文を表示するための {@code description} 属性を持つエレメントもあります。 + +たとえば、<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code> エレメントはこれらすべての属性を持っています。これによって、アプリケーションがユーザーにパーミッションを付与するかどうかを尋ねる際に、ユーザーに対して、パーミッションを示すアイコン、パーミッションの名前、パーミッションについての説明文を提示できます。 + + + + + +</p> + +<p> +どの場合においても、属性を含むエレメントに設定されたアイコンとラベルが、そのすべてのサブエレメントの {@code icon} と {@code label} のデフォルト設定となります。 +そのため、<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> エレメントに設定されたアイコンとラベルは、アプリケーションの各コンポーネントのデフォルトのアイコンとラベルとなります。 + + +同様に、コンポーネントに設定されたアイコンとラベルは、— <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> エレメントのように — それぞれのコンポーネントの <code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code> エレメントのデフォルト設定となります。 + + + + +<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> エレメントにラベルを設定し、アクティビティとそのインテント フィルタに設定しない場合は、アプリケーション ラベルはアクティビティとインテント フィルタの両方のラベルとして取り扱われます。 + + + + +</p> + +<p> +インテント フィルタに設定されるアイコンとラベルは、コンポーネントがユーザーに対して提示されるときはいつでも、そのフィルタにより通知されている機能を提供するコンポーネントを示すために使用されます。 + +たとえば、「{@code android.intent.action.MAIN}」と「{@code android.intent.category.LAUNCHER}」が設定されているフィルタは、アプリケーションを起動するアクティビティを通知しています — つまり、アプリケーション ランチャーに表示されるということです。 + + + +そのため、このフィルタに設定されているアイコンとラベルがランチャーに表示されるものとなります。 + +</p> + + +<h3 id="perms">パーミッション</h3> + +<p> +パーミッションは、コードの一部や端末上のデータへのアクセスを制限する機能を提供します。<i></i> + 誤用や悪用によってユーザーの利用を妨げたり有害な作用をもたらす恐れのある重要なデータやコードを保護したりするための制限を設定します。 + +</p> + +<p> +それぞれのパーミッションは一意のラベルで識別されています。通常、ラベルは制限されるアクションを示します。 +以下は、Android により定義されているパーミッションの例です。 + +</p> + +<p style="margin-left: 2em">{@code android.permission.CALL_EMERGENCY_NUMBERS} +<br/>{@code android.permission.READ_OWNER_DATA} +<br/>{@code android.permission.SET_WALLPAPER} +<br/>{@code android.permission.DEVICE_POWER}</p> + +<p> +1 つの機能は、1 つのパーミッションでのみ保護できます。 +</p> + +<p> +アプリケーションがパーミッションにより保護されている機能へのアクセスを必要としている場合は、<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> エレメントをマニフェスト ファイルに記述し、そのパーミッションが必要であることを宣言する必要があります。 + + +これによって、アプリケーションが端末にインストールされた際に、インストーラーは、アプリケーションの証明書に署名した関係機関を確認し、場合によってはユーザーに尋ねることで、要求されたパーミッションを付与するかどうかを決定します。 + + +パーミッションが付与されると、アプリケーションは保護された機能を使用できるようになります。 + +パーミッションが付与されなかった場合は、アプリケーションは機能にアクセスできず、ユーザーに通知が表示されることもありません。 + +</p> + +<p> +アプリケーションは、パーミッションを使って自身のコンポーネント(アクティビティ、サービス、ブロードキャスト レシーバー、コンテンツ プロバイダ)を保護することもできます。 +Android により定義されているパーミッション({@link android.Manifest.permission android.Manifest.permission} に記載)や他のアプリケーションにより宣言されたパーミッションであればどれでも使用できます。 + + +独自のパーミッションを定義することもできます。新しいパーミッションは、<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code> エレメントを使って宣言します。 + + +たとえば、次のようにアクティビティを保護できます。 +</p> + +<pre> +<manifest . . . > + <permission android:name="com.example.project.DEBIT_ACCT" . . . /> + <uses-permission android:name="com.example.project.DEBIT_ACCT" /> + . . . + <application . . .> + <activity android:name="com.example.project.FreneticActivity" + android:permission="com.example.project.DEBIT_ACCT" + . . . > + . . . + </activity> + </application> +</manifest> +</pre> + +<p> +この例では、{@code DEBIT_ACCT} パーミッションは <code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code> エレメントで宣言されているだけではなく、その使用が <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> エレメントで要求されている点に注意してください。 + + + + +アプリケーション自身によって保護が設定されている場合でも、アプリケーションの他のコンポーネントが保護されたアクティビティを起動するために、その使用を要求する必要があります。 + + +</p> + +<p> +同じ例で、別の場所で宣言されたパーミッションに {@code permission} 属性が設定されている場合({@code android.permission.CALL_EMERGENCY_NUMBERS} など)は、<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code> エレメントを使って再度宣言する必要があります。 + + + + +その場合も <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> でその使用を要求する必要があります。 + +</p> + +<p> +<code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html"><permission-tree></a></code> エレメントは、コードに定義されるパーミッションの集まりに対するネームスペースを宣言します。 + + +<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html"><permission-group></a></code> エレメントは、パーミッションのセットに対するラベル(マニフェスト ファイルに <code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code> エレメントを使って宣言されたもの、その他の場所で宣言されたものの両方)を定義します。 + + + +これは、ユーザーに提示される際のパーミッションのグループ分けのみに影響します。 +<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html"><permission-group></a></code> エレメントでは、パーミッションのグループへの所属は指定されません。グループ名のみが指定されます。 + + +パーミッションは、<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code> エレメントの <code><a href="{@docRoot}guide/topics/manifest/permission-element.html#pgroup">permissionGroup</a></code> 属性にグループ名を割り当てることによって、グループに配置されます。 + + + + + +</p> + + +<h3 id="libs">ライブラリ</h3> + +<p> +すべてのアプリケーションはデフォルトの Android ライブラリにリンクされています。このライブラリには、Activity、Service、Intent、View、Button、Application、ContentProvider などの共通クラスを含む、アプリケーションをビルドするための基本パッケージが含まれています。 + + + +</p> + +<p> +しかし、独自のライブラリに含まれているパッケージもあります。開発中のアプリケーションがこれらのパッケージのコードを使用している場合は、該当するライブラリにリンクするよう明示的に求める必要があります。 + +この場合は、マニフェスト ファイルに各ライブラリを指定する <code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><uses-library></a></code> エレメントが別途含まれている必要があります。 + +(ライブラリ名は該当するパッケージのドキュメントに記載されています)。 + +</p> diff --git a/docs/html-intl/intl/ja/guide/topics/providers/calendar-provider.jd b/docs/html-intl/intl/ja/guide/topics/providers/calendar-provider.jd new file mode 100644 index 000000000000..7b97c3083341 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/providers/calendar-provider.jd @@ -0,0 +1,1184 @@ +page.title=カレンダー プロバイダ +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>本書の内容</h2> + <ol> + <li><a href="#overview">基本</a></li> + <li><a href="#manifest">ユーザー パーミッション</a></li> + <li><a href="#calendar">Calendars テーブル</a> +<ol> + <li><a href="#query">カレンダーへのクエリ</a></li> + <li><a href="#modify-calendar">カレンダーの変更</a></li> + <li><a href="#insert-calendar">カレンダーの挿入</a></li> + </ol> + </li> + <li><a href="#events">Events テーブル</a> +<ol> + <li><a href="#add-event">イベントの追加</a></li> + <li><a href="#update-event">イベントのアップデート</a></li> + <li><a href="#delete-event">イベントの削除</a></li> + </ol> + </li> + <li><a href="#attendees">Attendees テーブル</a> +<ol> + <li><a href="#add-attendees">参加者の追加</a></li> + </ol> + </li> + <li><a href="#reminders">Reminders テーブル</a> +<ol> + <li><a href="#add-reminders">リマインダーの追加</a></li> + </ol> + </li> + <li><a href="#instances">Instances テーブル</a> + <ol> + <li><a href="#query-instances">Instances テーブルへのクエリ</a></li> + </ol></li> + <li><a href="#intents">カレンダーのインテント</a> + <ol> + <li><a href="#intent-insert">インテントを使用したイベントの挿入</a></li> + <li><a href="#intent-edit">インテントを使用したイベントの編集</a></li> + <li><a href="#intent-view">インテントを使用したカレンダー データの参照</a></li> + </ol> + </li> + + <li><a href="#sync-adapter">同期アダプタ</a></li> +</ol> + + <h2>キークラス</h2> + <ol> + <li>{@link android.provider.CalendarContract.Calendars}</li> + <li>{@link android.provider.CalendarContract.Events}</li> + <li>{@link android.provider.CalendarContract.Attendees}</li> + <li>{@link android.provider.CalendarContract.Reminders}</li> + </ol> +</div> +</div> + +<p>カレンダー プロバイダは、ユーザーのカレンダー イベントのためのリポジトリです。カレンダー プロバイダ API を使用すると、カレンダー、イベント、参加者、リマインダーなどに対するクエリ、挿入、アップデート、削除の操作を実行できます。 + +</p> + + +<p>カレンダー プロバイダ API は、アプリケーションや同期アダプタで使用できます。ルールは、呼び出しを実行しているプログラムのタイプによって異なります。 +本書では主に、カレンダー プロバイダ API のアプリケーションとしての使用について説明します。 +同期アダプタの場合の違いについては、<a href="#sync-adapter">同期アダプタ</a>をご覧ください。 + +</p> + + +<p>通常、カレンダー データを読み取ったり書き込んだりするためには、アプリケーションのマニフェストに<a href="#manifest">ユーザー パーミッション</a>で説明している適切なパーミッションが含まれている必要があります。 + +一般的な操作を簡単に実行できるようにするため、カレンダー プロバイダには、いくつかのインテントが用意されています。これらについては、<a href="#intents">カレンダーのインテント</a>で説明しています。 + +これらのインテントは、ユーザーをカレンダー アプリケーションに誘導して、イベントを挿入、参照、編集できるようにします。 +ユーザーは、カレンダー アプリケーションを操作した後、元のアプリケーションに戻ります。 +これにより、アプリケーションがパーミッションを要求したり、イベントの参照や作成のためのインターフェースを提供したりする必要がなくなります。 +</p> + +<h2 id="overview">基本</h2> + +<p><a href="{@docRoot}guide/topics/providers/content-providers.html">コンテンツ プロバイダ</a>は、データを保存してアプリケーションからアクセスできるようにします。 +Android プラットフォームによって提供されるコンテンツ プロバイダ(カレンダー プロバイダを含む)は、一般にリレーショナル データベース モデルに基づくテーブルのセットとしてデータを公開します。このモデルにおいて、各行はレコード、各列は特定のタイプと意味のデータになっています。 + +アプリケーションと同期アダプタは、ユーザーのカレンダー データを保持するデータベース テーブルの読み取りおよび書き込みアクセスを、カレンダー プロバイダ API を使用して取得できます。 + +</p> + +<p>各コンテンツ プロバイダは、データセットを一意に指定するパブリック URI({@link android.net.Uri} オブジェクトとしてラップされています)を公開します。 + +複数のデータセット(複数のテーブル)を制御するコンテンツ プロバイダは、データセットごとに個別の URI を公開します。 +プロバイダの URI はすべて、文字列「content://」で始まります。 +これは、コンテンツ プロバイダによって管理されているデータであることを示します。 +カレンダー プロバイダは、クラス(テーブル)それぞれの URI のための定数を定義します。 +URI の形式は <code><em><class></em>.CONTENT_URI</code> です。 +たとえば、{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} のようになります。 +</p> + +<p>図 1 に、カレンダー プロバイダのデータモデルを図示します。メイン テーブルとそれらを相互にリンクしているフィールドが示されています。 +</p> + +<img src="{@docRoot}images/providers/datamodel.png" alt="Calendar Provider Data Model" /> +<p class="img-caption"><strong>図 1.</strong> カレンダー プロバイダのデータモデル。</p> + +<p>ユーザーは複数のカレンダーを持つことができ、カレンダーをそれぞれ異なるタイプのアカウント(Google カレンダー、Exchange など)と関連付けることができます。</p> + +<p>{@link android.provider.CalendarContract} は、カレンダーのデータモデルとイベント関連の情報を定義します。データは、次に示すいくつかのテーブルに保存されます。</p> + +<table> + <tr> + <th>テーブル(クラス)</th> + <th>説明</th> + </tr> + <tr> + <td><p>{@link android.provider.CalendarContract.Calendars}</p></td> + + <td>このテーブルは、該当するカレンダー固有の情報を保持します。 +各行には、名前、色、同期情報など、1 つのカレンダーに関する詳細が格納されます。 +</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Events}</td> + + <td>このテーブルは、該当するイベント固有の情報を保持します。 +各行には、1 つのイベントに関する情報が格納されます—イベントのタイトル、場所、開始時刻、終了時刻などが該当します。 + +イベントは、単発だったり繰り返し発生したりすることが考えられます。参加者、リマインダー、拡張プロパティは、個別のテーブルに格納されます。 +これらのテーブルにはそれぞれ、Events テーブルの {@link android.provider.BaseColumns#_ID} を参照する {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} があります。 + +</td> + + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Instances}</td> + + <td>このテーブルは、あるイベントの発生ごとの開始時刻と終了時刻を保持します。 +各行は、イベントの発生 1 回を表します。 +単発イベントには、イベントのインスタンスが 1 対 1 で対応します。 +繰り返しのイベントには、そのイベントの複数回の発生それぞれに対応する複数の行が自動生成されます。 +</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Attendees}</td> + + <td>このテーブルは、イベントの参加者(ゲスト)の情報を保持します。 +各行は、1 回のイベントの 1 人のゲストを表します。 +ゲストのタイプと、ゲストのイベントへの出欠の回答を指定します。 +</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Reminders}</td> + + <td>このテーブルは、アラートや通知のデータを保持します。 +各行は、1 回のイベントの 1 つのアラートを表します。1 つのイベントが複数のリマインダーを持つことができます。 +1 イベントあたりの最大リマインダー数は {@link android.provider.CalendarContract.CalendarColumns#MAX_REMINDERS} で指定され、指定されたカレンダーを所有する同期アダプタによって設定されます。 + + + +リマインダーは、イベント開始前の分単位で指定され、ユーザーに注意喚起する手段を示す情報を保持します。 +</td> + </tr> + +</table> + +<p>カレンダー プロバイダ API は、柔軟で効果的な設計になっています。ですが同時に、エンドユーザーにとって使いやすくすることや、カレンダーとそのデータの整合性を保護することが重要です。 + +次に、そのために API の使用に際して留意すべきことを示します。 +</p> + +<ul> + +<li><strong>カレンダー イベントの挿入、アップデート、参照</strong>カレンダー プロバイダからイベントの挿入、変更、読み取りを直接実行するためには、適切な<a href="#manifest">パーミッション</a>が必要です。ただし、作成しているのが本格的なカレンダー アプリケーションや同期アダプタではない場合は、そうしたパーミッションを要求する必要はありません。その代わりに、Android のカレンダー アプリケーションがサポートしているインテントを使用し、読み取りと書き込みの操作をそのアプリケーションに引き渡すことができます。インテントを使用すると、アプリケーションがユーザーをカレンダー アプリケーションに誘導し、自動入力されたフォームで目的の操作を実行するようになります。 +操作を完了したユーザーは、アプリケーションに戻されます。一般的な操作をカレンダーを介して実行するようにアプリケーションを設計することで、ユーザーに一貫性のある堅牢なユーザー インターフェースが提供できます。 + +これが推奨アプローチです。 +詳細については、<a href="#intents">カレンダーのインテント</a>をご覧ください。 +</p> + + +<li><strong>同期アダプタ。</strong>同期アダプタは、ユーザーの端末上にあるカレンダー データを別のサーバーやデータソースと同期します。 +{@link android.provider.CalendarContract.Calendars} テーブルと {@link android.provider.CalendarContract.Events} テーブルには、同期アダプタ用に予約された列があります。プロバイダやアプリケーションがそれらを変更しないようにする必要があります。 + + + +実際には、同期アダプタとしてアクセスしない限り、それらの列は参照できません。 +同期アダプタの詳細については、<a href="#sync-adapter">同期アダプタ</a>をご覧ください。 +</li> + +</ul> + + +<h2 id="manifest">ユーザー パーミッション</h2> + +<p>カレンダー データを読み込むためには、アプリケーションはマニフェスト ファイルに {@link android.Manifest.permission#READ_CALENDAR} パーミッションを含める必要があります。 +カレンダー データを削除、挿入、アップデートするためには、{@link android.Manifest.permission#WRITE_CALENDAR} パーミッションを含める必要があります。 + +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android"...> + <uses-sdk android:minSdkVersion="14" /> + <uses-permission android:name="android.permission.READ_CALENDAR" /> + <uses-permission android:name="android.permission.WRITE_CALENDAR" /> + ... +</manifest> +</pre> + + +<h2 id="calendar">Calendars テーブル</h2> + +<p>{@link android.provider.CalendarContract.Calendars} テーブルには、個々のカレンダーの詳細情報が格納されます。 +次に示す Calendars の列は、アプリケーションと<a href="#sync-adapter">同期アダプタ</a>のどちらからも書き込み可能です。 +サポートされているすべてのフィールドの一覧については、{@link android.provider.CalendarContract.Calendars} のリファレンスをご覧ください。 + +</p> +<table> + <tr> + <th>定数</th> + <th>説明</th> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Calendars#NAME}</td> + <td>カレンダーの名前。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Calendars#CALENDAR_DISPLAY_NAME}</td> + <td>ユーザーに表示されるこのカレンダーの名前。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Calendars#VISIBLE}</td> + + <td>カレンダーが表示対象として選択されているかどうかを示すブール値。値 0 は、このカレンダーに関連付けられているイベントを表示しないことを示します。 + +値 1 は、このカレンダーに関連付けられているイベントを表示することを示します。 +この値は、{@link android.provider.CalendarContract.Instances} テーブルの行の生成に影響を与えます。 +</td> + + + </tr> + <tr> + <td>{@link android.provider.CalendarContract.CalendarColumns#SYNC_EVENTS}</td> + + <td>カレンダーを同期してそのイベントを端末に格納するかどうかを示すブール値。 +値 0 は、このカレンダーを同期せず、イベントを端末に格納しないことを指定します。 +値 1 は、このカレンダーのイベントを同期し、イベントを端末に格納することを指定します。 +</td> + </tr> +</table> + +<h3 id="query">カレンダーへのクエリ</h3> + +<p>次の例は、特定のユーザーが所有するカレンダーを取得する方法を示しています。 +簡潔にするため、この例のクエリ操作はユーザー インターフェース スレッド(「メインスレッド」)内に示されています。 +実際には、メインスレッドではなく非同期スレッドで実行してください。 +詳細については、「<a href="{@docRoot}guide/components/loaders.html">ローダ</a>」をご覧ください。 +データを読み込むだけでなく変更する場合は、{@link android.content.AsyncQueryHandler} をご覧ください。 + +</p> + + +<pre> +// Projection array. Creating indices for this array instead of doing +// dynamic lookups improves performance. +public static final String[] EVENT_PROJECTION = new String[] { + Calendars._ID, // 0 + Calendars.ACCOUNT_NAME, // 1 + Calendars.CALENDAR_DISPLAY_NAME, // 2 + Calendars.OWNER_ACCOUNT // 3 +}; + +// The indices for the projection array above. +private static final int PROJECTION_ID_INDEX = 0; +private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1; +private static final int PROJECTION_DISPLAY_NAME_INDEX = 2; +private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;</pre> + + +<div class="sidebox-wrapper"> <div class="sidebox"> <h3>ACCOUNT_TYPE を含める必要がある理由 +</h3> <p>{@link android.provider.CalendarContract.Calendars#ACCOUNT_NAME Calendars.ACCOUNT_NAME} にクエリする場合は、このセクションに {@link android.provider.CalendarContract.Calendars#ACCOUNT_TYPE Calendars.ACCOUNT_TYPE} も含める必要があります。 + + + +これは、指定されたアカウントは <code>ACCOUNT_NAME</code> とその <code>ACCOUNT_TYPE</code> がどちらも与えられることで一意とみなされるからです。 + +<code>ACCOUNT_TYPE</code> は、そのアカウントが {@link android.accounts.AccountManager} で登録されたときに使用されたアカウント認証システムです。 + +また、端末アカウントに関連付けられていないカレンダー用に、{@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} という特殊なタイプのアカウントがあります。{@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} アカウントは同期されません。 + + + +</p> </div> </div> + + +<p> この例の次の部分では、クエリを作成します。クエリの条件は selection に指定しています。 +この例のクエリは、<code>ACCOUNT_NAME</code> が「sampleuser@google.com」で、<code>ACCOUNT_TYPE</code> が「com.google」で、<code>OWNER_ACCOUNT</code> が「sampleuser@google.com」であるカレンダーを検索します。 + + + +ユーザーが所有しているだけでなく参照したことのあるすべてのカレンダーを確認するには、<code>OWNER_ACCOUNT</code> を省略します。このクエリは、データベース クエリが返した結果セットをトラバースするのに使用できる {@link android.database.Cursor} オブジェクトを返します。 + + + +コンテンツ プロバイダでのクエリの使用については、「<a href="{@docRoot}guide/topics/providers/content-providers.html">コンテンツ プロバイダ</a>」をご覧ください。 +</p> + + +<pre>// Run query +Cursor cur = null; +ContentResolver cr = getContentResolver(); +Uri uri = Calendars.CONTENT_URI; +String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" + + Calendars.ACCOUNT_TYPE + " = ?) AND (" + + Calendars.OWNER_ACCOUNT + " = ?))"; +String[] selectionArgs = new String[] {"sampleuser@gmail.com", "com.google", + "sampleuser@gmail.com"}; +// Submit the query and get a Cursor object back. +cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);</pre> + +<p>次のセクションでは、カーソルを使用して結果セットをステップ単位で移動します。例の冒頭で設定した定数を使用して各フィールドの値を返します。 + +</p> + +<pre>// Use the cursor to step through the returned records +while (cur.moveToNext()) { + long calID = 0; + String displayName = null; + String accountName = null; + String ownerName = null; + + // Get the field values + calID = cur.getLong(PROJECTION_ID_INDEX); + displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX); + accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX); + ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX); + + // Do something with the values... + + ... +} +</pre> + +<h3 id="modify-calendar">カレンダーの変更</h3> + +<p>カレンダーのアップデートを実行する場合、カレンダーの {@link android.provider.BaseColumns#_ID} を、URI({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})の末尾に追加された ID として、または最初の selection 項目として指定できます。 + + + + +先ほどの selection を <code>"_id=?"</code> で始め、最初の <code>selectionArg</code> をカレンダーの {@link android.provider.BaseColumns#_ID} にする必要があります。 + + +URL に含まれる ID をエンコードすることでも、アップデートを実行できます。この例では、カレンダーの表示名をこの({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()} を使用する)アプローチで変更しています。 + + + +</p> + +<pre>private static final String DEBUG_TAG = "MyActivity"; +... +long calID = 2; +ContentValues values = new ContentValues(); +// The new display name for the calendar +values.put(Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar"); +Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID); +int rows = getContentResolver().update(updateUri, values, null, null); +Log.i(DEBUG_TAG, "Rows updated: " + rows);</pre> + +<h3 id="insert-calendar">カレンダーの挿入</h2> + +<p>カレンダーは主に同期アダプタで管理するように設計されているため、新しいカレンダーは必ず同期アダプタとして挿入してください。 +ほとんどの場合、アプリケーションはカレンダーに対し、表示名の変更のような表面的な変更しかできません。 +アプリケーションがローカル カレンダーを作成する必要がある場合は、{@link android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} として {@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} を使用し、カレンダーの挿入を同期アダプタとして実行することで作成できます。{@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} は、端末アカウントと関連付けられていないカレンダー用の特殊なアカウント タイプです。 + + + + + + +このタイプのカレンダーは、サーバーと同期されません。同期アダプタの詳細については、<a href="#sync-adapter">同期アダプタ</a>をご覧ください。 +</p> + +<h2 id="events">Events テーブル</h2> + +<p>{@link android.provider.CalendarContract.Events} テーブルには、個々のイベントの詳細情報が格納されます。 + +イベントを追加、アップデート、削除するためには、アプリケーションは<a href="#manifest">マニフェスト ファイル</a>に {@link android.Manifest.permission#WRITE_CALENDAR} パーミッションを含める必要があります。 +</p> + +<p>次に示す Events の列は、アプリケーションと同期アダプタのどちらからも書き込み可能です。 +サポートされているすべてのフィールドの一覧については、{@link android.provider.CalendarContract.Events} のリファレンスをご覧ください。 +</p> + +<table> + <tr> + <th>定数</th> + <th>説明</th> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#CALENDAR_ID}</td> + <td>イベントが属するカレンダーの {@link android.provider.BaseColumns#_ID}。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#ORGANIZER}</td> + <td>イベントの主催者(所有者)のメールアドレス。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#TITLE}</td> + <td>イベントのタイトル。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION}</td> + <td>イベントが開催される場所。 </td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION}</td> + <td>イベントの説明。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#DTSTART}</td> + <td>エポックからの UTC ミリ秒単位で表現されたイベント開始時刻。 </td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#DTEND}</td> + <td>エポックからの UTC ミリ秒単位で表現されたイベント終了時刻。 </td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}</td> + <td>イベントのタイムゾーン。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_END_TIMEZONE}</td> + <td>イベントの終了時刻のタイムゾーン。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#DURATION}</td> + + <td><a href="http://tools.ietf.org/html/rfc5545#section-3.8.2.5">RFC5545</a> 形式でのイベントの期間。たとえば、<code>"PT1H"</code> という値はイベントが 1 時間であること、<code>"P2W"</code> という値は期間が 2 週間であることを示します。 + + + </td> + + + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#ALL_DAY}</td> + + <td>値 1 は、そのイベントがローカルのタイムゾーンで定義された終日を占めることを示します。 +値 0 は、1 日のどこかで始まって終わる定例のイベントであることを示します。 +</td> + + + </tr> + + + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#RRULE}</td> + + <td>イベント形式の繰り返し発生ルール。たとえば、<code>"FREQ=WEEKLY;COUNT=10;WKST=SU"</code> のようになります。 +その他の例については、<a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.3">こちら</a>をご覧ください。 +</td> + + </tr> + + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#RDATE}</td> + <td>イベントの繰り返し発生日。通常、{@link android.provider.CalendarContract.EventsColumns#RDATE} は {@link android.provider.CalendarContract.EventsColumns#RRULE} と組み合わせて、繰り返し発生全体を定義するのに使用します。 + + + +詳細については、<a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.2">RFC5545 の仕様</a>をご覧ください。</td> +</tr> + + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY}</td> + + <td>このイベントを埋まっている時間に数えるか、それともスケジュールのやり直しが利く空き時間とみなすか。 + </td> + + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_MODIFY}</td> + <td>ゲストがイベントを変更できるかどうか。 </td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_INVITE_OTHERS}</td> + <td>ゲストが他のゲストを招待できるかどうか。 </td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_SEE_GUESTS}</td> + <td>ゲストが他の参加者のリストを参照できるかどうか。</td> + </tr> +</table> + +<h3 id="add-event">イベントの追加</h3> + +<p>アプリケーションが新しいイベントを挿入する場合は、{@link android.content.Intent#ACTION_INSERT INSERT} インテントを使用することをお勧めします。詳細については、<a href="#intent-insert">インテントを使用したイベントの挿入</a>をご覧ください。 +ただし、必要があればイベントを直接挿入できます。 +ここではその方法について説明します。 +</p> + + +<p>新しいイベントを挿入するためのルールは次のとおりです。 </p> +<ul> + + <li>{@link android.provider.CalendarContract.EventsColumns#CALENDAR_ID} と {@link android.provider.CalendarContract.EventsColumns#DTSTART} を含める必要があります。 + +</li> + +<li>{@link android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE} を含める必要があります。 +システムにインストールされているタイムゾーン ID のリストを取得するには、{@link java.util.TimeZone#getAvailableIDs()} を使用します。 + +<a href="#intent-insert">インテントを使用したイベントの挿入</a>で説明しているように、{@link android.content.Intent#ACTION_INSERT INSERT} インテントを使用してイベントを挿入している場合、このルールは該当しません—その場合はデフォルトのタイムゾーンが指定されます。 + + +</li> + + <li>繰り返されないイベントには、{@link android.provider.CalendarContract.EventsColumns#DTEND} を含める必要があります。 + </li> + + + <li>繰り返されるイベントには、{@link android.provider.CalendarContract.EventsColumns#RRULE} と {@link android.provider.CalendarContract.EventsColumns#RDATE} に加えて {@link android.provider.CalendarContract.EventsColumns#DURATION} を含める必要があります。 + + +<a href="#intent-insert">インテントを使用したイベントの挿入</a>で説明しているように、{@link android.content.Intent#ACTION_INSERT INSERT} インテントを使用してイベントを挿入している場合、このルールは該当しません—その場合は、{@link android.provider.CalendarContract.EventsColumns#RRULE} を {@link android.provider.CalendarContract.EventsColumns#DTEND} と {@link android.provider.CalendarContract.EventsColumns#DTSTART} と組み合わせて使用でき、カレンダー アプリケーションはこれを自動で期間に変換します。 + + + + +</li> + +</ul> + +<p>イベントの挿入の例を次に示します。簡潔にするため、この例は UI スレッドで実行されています。 +実際には、挿入やアップデートは非同期スレッドで実行して、アクションをバックグラウンド スレッドに移してください。 +詳細については、{@link android.content.AsyncQueryHandler} をご覧ください。 +</p> + + +<pre> +long calID = 3; +long startMillis = 0; +long endMillis = 0; +Calendar beginTime = Calendar.getInstance(); +beginTime.set(2012, 9, 14, 7, 30); +startMillis = beginTime.getTimeInMillis(); +Calendar endTime = Calendar.getInstance(); +endTime.set(2012, 9, 14, 8, 45); +endMillis = endTime.getTimeInMillis(); +... + +ContentResolver cr = getContentResolver(); +ContentValues values = new ContentValues(); +values.put(Events.DTSTART, startMillis); +values.put(Events.DTEND, endMillis); +values.put(Events.TITLE, "Jazzercise"); +values.put(Events.DESCRIPTION, "Group workout"); +values.put(Events.CALENDAR_ID, calID); +values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles"); +Uri uri = cr.insert(Events.CONTENT_URI, values); + +// get the event ID that is the last element in the Uri +long eventID = Long.parseLong(uri.getLastPathSegment()); +// +// ... do something with event ID +// +//</pre> + +<p class="note"><strong>注:</strong> イベントの作成後にイベント ID を取得していることに注目してください。 +これがイベント ID を取得する最も簡単な方法です。他のカレンダー操作を実行するためにイベント ID が必要になることはよくあります—イベントに対する参加者やリマインダーの追加などが該当します。 + +</p> + + +<h3 id="update-event">イベントのアップデート</h3> + +<p>アプリケーションでユーザーによるイベントの編集を許可する場合は、{@link android.content.Intent#ACTION_EDIT EDIT} インテントを使用することをお勧めします。詳細については、<a href="#intent-edit">インテントを使用したイベントの挿入</a>をご覧ください。ただし、イベントは必要に応じて直接編集できます。 + + +イベントのアップデートを実行する場合は、イベントの <code>_ID</code> を、URI({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})の末尾に追加された ID として、または前出の selection の最初の項目として指定できます。 + + + +前出の selection を <code>"_id=?"</code> で始め、最初の <code>selectionArg</code> をカレンダーの <code>_ID</code> にする必要があります。 + +ID なしの selection を使用してアップデートすることもできます。次に、イベントのアップデートの例を示します。 + +ここでは、{@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()} を使用するアプローチでイベントのタイトルを変更しています。 + +</p> + + +<pre>private static final String DEBUG_TAG = "MyActivity"; +... +long eventID = 188; +... +ContentResolver cr = getContentResolver(); +ContentValues values = new ContentValues(); +Uri updateUri = null; +// The new title for the event +values.put(Events.TITLE, "Kickboxing"); +updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); +int rows = getContentResolver().update(updateUri, values, null, null); +Log.i(DEBUG_TAG, "Rows updated: " + rows); </pre> + +<h3 id="delete-event">イベントの削除</h3> + +<p>イベントは、目的のイベントの {@link android.provider.BaseColumns#_ID} を URI の末尾に追加する ID として使用するか、標準的な選択を使用して削除できます。 + +ID の追加で削除を実行する場合、選択はできません。削除には、アプリケーションとして実行する方法と同期アダプタとして実行する方法の 2 種類があります。 +アプリケーションとしての削除では、削除される<em></em>列が 1 に設定されます。 +このフラグは同期アダプタに対して、その行が削除されたことを通知し、この削除をサーバーに通知するよう指示します。 + +同期アダプタとしての削除では、すべての関連データとともにデータベースからイベントが削除されます。 +次の例では、アプリケーションがイベントをその {@link android.provider.BaseColumns#_ID} を使用して削除しています。 +</p> + + +<pre>private static final String DEBUG_TAG = "MyActivity"; +... +long eventID = 201; +... +ContentResolver cr = getContentResolver(); +ContentValues values = new ContentValues(); +Uri deleteUri = null; +deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); +int rows = getContentResolver().delete(deleteUri, null, null); +Log.i(DEBUG_TAG, "Rows deleted: " + rows); +</pre> + +<h2 id="attendees">Attendees テーブル</h2> + +<p>{@link android.provider.CalendarContract.Attendees} テーブルの各行は、あるイベントの 1 人の参加者ないしゲストを表します。 +{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} を呼び出すと、指定された {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} を持つイベントの参加者リストが返されます。 + + +この {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} は特定のイベントの {@link android.provider.BaseColumns#_ID} と一致している必要があります。 + + +</p> + +<p>次の表に、書き込み可能なフィールドを示します。 +新しい参加者を挿入する際には、<code>ATTENDEE_NAME</code> を除くすべてを含める必要があります。 + +</p> + + +<table> + <tr> + <th>定数</th> + <th>説明</th> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}</td> + <td>イベントの ID。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_NAME}</td> + <td>参加者の名前。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_EMAIL}</td> + <td>参加者のメールアドレス。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_RELATIONSHIP}</td> + <td><p>参加者のイベントに対する関係。次のどれかです。</p> + <ul> + <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ATTENDEE}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_NONE}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ORGANIZER}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_PERFORMER}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_SPEAKER}</li> + </ul> + </td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_TYPE}</td> + <td><p>参加者のタイプ。次のどれかです。 </p> + <ul> + <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_REQUIRED}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_OPTIONAL}</li> + </ul></td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS}</td> + <td><p>参加者の出席ステータス。次のどれかです。</p> + <ul> + <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_ACCEPTED}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_DECLINED}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_INVITED}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_NONE}</li> + <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_TENTATIVE}</li> + </ul></td> + </tr> +</table> + +<h3 id="add-attendees">参加者の追加</h3> + +<p>次の例では、あるイベントに 1 人の参加者を挿入しています。{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} は必須です。 + +</p> + +<pre> +long eventID = 202; +... +ContentResolver cr = getContentResolver(); +ContentValues values = new ContentValues(); +values.put(Attendees.ATTENDEE_NAME, "Trevor"); +values.put(Attendees.ATTENDEE_EMAIL, "trevor@example.com"); +values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE); +values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL); +values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED); +values.put(Attendees.EVENT_ID, eventID); +Uri uri = cr.insert(Attendees.CONTENT_URI, values); +</pre> + +<h2 id="reminders">Reminders テーブル</h2> + +<p>{@link android.provider.CalendarContract.Reminders} テーブルの各行は、あるイベントの 1 つのリマインダーを表します。 +{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} を呼び出すと、指定された {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} を持つイベントのリマインダー リストが返されます。 + + +</p> + + +<p>次の表に、リマインダーに関する書き込み可能なフィールドを示します。新しいリマインダーを挿入する際には、これらをすべて含める必要があります。 +同期アダプタは、サポートするリマインダーのタイプを {@link android.provider.CalendarContract.Calendars} テーブルで指定しています。 + +詳細については、{@link android.provider.CalendarContract.CalendarColumns#ALLOWED_REMINDERS} をご覧ください。 + +</p> + + +<table> + <tr> + <th>定数</th> + <th>説明</th> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.RemindersColumns#EVENT_ID}</td> + <td>イベントの ID。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.RemindersColumns#MINUTES}</td> + <td>リマインダーが通知されるまでの分単位の時間。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.RemindersColumns#METHOD}</td> + <td><p>アラーム手段。サーバーに設定されます。次のどれかです。</p> + <ul> + <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_ALERT}</li> + <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_DEFAULT}</li> + <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_EMAIL}</li> + <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_SMS}</li> + </ul></td> + </tr> +</table> + +<h3 id="add-reminders">リマインダーの追加</h3> + +<p>この例では、イベントにリマインダーを追加します。このリマインダーは、イベントの 15 分前に通知されます。 +</p> +<pre> +long eventID = 221; +... +ContentResolver cr = getContentResolver(); +ContentValues values = new ContentValues(); +values.put(Reminders.MINUTES, 15); +values.put(Reminders.EVENT_ID, eventID); +values.put(Reminders.METHOD, Reminders.METHOD_ALERT); +Uri uri = cr.insert(Reminders.CONTENT_URI, values);</pre> + +<h2 id="instances">Instances テーブル</h2> + +<p>{@link android.provider.CalendarContract.Instances} テーブルは、あるイベントの発生の開始時刻と終了時刻を保持します。 + +各行は、イベントの発生 1 回を表します。 +Instances テーブルは書き込みできません。イベントの発生をクエリする手段を提供するためだけのものです。 + </p> + +<p>次の表に、インスタンスに関してクエリできるフィールドの一部を示します。タイムゾーンは {@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_TYPE} と {@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_INSTANCES} で定義されます。 + + + +</p> + + +<table> + <tr> + <th>定数</th> + <th>説明</th> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Instances#BEGIN}</td> + <td>インスタンスの開始時刻(UTC ミリ秒単位)。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Instances#END}</td> + <td>インスタンスの終了時刻(UTC ミリ秒単位)。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Instances#END_DAY}</td> + + <td>インスタンスの、カレンダーのタイムゾーンにおけるユリウス暦での終了日。 + + +</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Instances#END_MINUTE}</td> + + <td>カレンダーのタイムゾーンにおける午前零時を基準にしたインスタンスの終了分。 +</td> + + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Instances#EVENT_ID}</td> + <td>このインスタンスのイベントの <code>_ID</code>。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Instances#START_DAY}</td> + <td>インスタンスの、カレンダーのタイムゾーンにおけるユリウス暦での開始日。 + </td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.Instances#START_MINUTE}</td> + + <td>カレンダーのタイムゾーンにおける午前零時を基準にしたインスタンスの開始分。 + +</td> + + </tr> + +</table> + +<h3 id="query-instances">Instances テーブルへのクエリ</h3> + +<p>Instances テーブルにクエリするには、クエリの範囲を示す時刻を URI に指定する必要があります。この例で、{@link android.provider.CalendarContract.Instances} は {@link android.provider.CalendarContract.EventsColumns} インターフェースの実装を介して {@link android.provider.CalendarContract.EventsColumns#TITLE} フィールドへのアクセスを取得します。 + + + +言い換えると、{@link android.provider.CalendarContract.EventsColumns#TITLE} はデータベースの参照に対して返されているのであって、{@link android.provider.CalendarContract.Instances} テーブルそのものへのクエリに対して返されているのではありません。 + + + +</p> + +<pre> +private static final String DEBUG_TAG = "MyActivity"; +public static final String[] INSTANCE_PROJECTION = new String[] { + Instances.EVENT_ID, // 0 + Instances.BEGIN, // 1 + Instances.TITLE // 2 + }; + +// The indices for the projection array above. +private static final int PROJECTION_ID_INDEX = 0; +private static final int PROJECTION_BEGIN_INDEX = 1; +private static final int PROJECTION_TITLE_INDEX = 2; +... + +// Specify the date range you want to search for recurring +// event instances +Calendar beginTime = Calendar.getInstance(); +beginTime.set(2011, 9, 23, 8, 0); +long startMillis = beginTime.getTimeInMillis(); +Calendar endTime = Calendar.getInstance(); +endTime.set(2011, 10, 24, 8, 0); +long endMillis = endTime.getTimeInMillis(); + +Cursor cur = null; +ContentResolver cr = getContentResolver(); + +// The ID of the recurring event whose instances you are searching +// for in the Instances table +String selection = Instances.EVENT_ID + " = ?"; +String[] selectionArgs = new String[] {"207"}; + +// Construct the query with the desired date range. +Uri.Builder builder = Instances.CONTENT_URI.buildUpon(); +ContentUris.appendId(builder, startMillis); +ContentUris.appendId(builder, endMillis); + +// Submit the query +cur = cr.query(builder.build(), + INSTANCE_PROJECTION, + selection, + selectionArgs, + null); + +while (cur.moveToNext()) { + String title = null; + long eventID = 0; + long beginVal = 0; + + // Get the field values + eventID = cur.getLong(PROJECTION_ID_INDEX); + beginVal = cur.getLong(PROJECTION_BEGIN_INDEX); + title = cur.getString(PROJECTION_TITLE_INDEX); + + // Do something with the values. + Log.i(DEBUG_TAG, "Event: " + title); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(beginVal); + DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); + Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime())); + } + }</pre> + +<h2 id="intents">カレンダーのインテント</h2> +<p>アプリケーションがカレンダー データの読み取りや書き込みを実行するのに<a href="#manifest">パーミッション</a>は要りません。その代わり、Android のカレンダー アプリケーションがサポートするインテントを使用し、読み取りと書き込みの操作をそのアプリケーションに引き渡します。次の表に、カレンダー プロバイダによってサポートされているインテントを示します。</p> +<table> + <tr> + <th>アクション</th> + <th>URI</th> + + <th>説明</th> + <th>エクストラ</th> + </tr> + <tr> + <td><br> + {@link android.content.Intent#ACTION_VIEW VIEW} <br></td> + <td><p><code>content://com.android.calendar/time/<ms_since_epoch></code></p> + URI は、{@link android.provider.CalendarContract#CONTENT_URI CalendarContract.CONTENT_URI} を使用しても参照できます。 +このインテントの使用例については、<a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">インテントを使用したカレンダー データの参照</a>をご覧ください。 + + + </td> + <td><code><ms_since_epoch></code> に指定された時刻でカレンダーを開きます。</td> + <td>なし</td> + </tr> + <tr> + <td><p>{@link android.content.Intent#ACTION_VIEW VIEW} </p> + + </td> + <td><p><code>content://com.android.calendar/events/<event_id></code></p> + + URI は、{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} を使用しても参照できます。 +このインテントの使用例については、<a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">インテントを使用したカレンダー データの参照</a>をご覧ください。 + + + </td> + <td><code><event_id></code> で指定されたイベントを参照します。</td> + + <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br> + <br> + <br> + {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td> + </tr> + + <tr> + <td>{@link android.content.Intent#ACTION_EDIT EDIT} </td> + <td><p><code>content://com.android.calendar/events/<event_id></code></p> + + URI は、{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} を使用しても参照できます。 +このインテントの使用例については、<a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-edit">インテントを使用したカレンダー データの編集</a>をご覧ください。 + + + + </td> + <td><code><event_id></code> で指定されたイベントを編集します。</td> + + <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br> + <br> + <br> + {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td> + </tr> + + <tr> + <td>{@link android.content.Intent#ACTION_EDIT EDIT} <br> + <br> + {@link android.content.Intent#ACTION_INSERT INSERT} </td> + <td><p><code>content://com.android.calendar/events</code></p> + + URI は、{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} を使用しても参照できます。 +このインテントの使用例については、<a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-insert">インテントを使用したカレンダー データの挿入</a>をご覧ください。 + + + </td> + + <td>イベントを作成します。</td> + <td>次の表に示された任意のエクストラ。</td> + </tr> +</table> + +<p>次の表に、カレンダー プロバイダによってサポートされているインテント エクストラを示します。 +</p> +<table> + <tr> + <th>インテント エクストラ</th> + <th>説明</th> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE}</td> + <td>イベントの名前。</td> + </tr> + <tr> + + <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME} +</td> + <td>イベントの開始時刻(エポックからのミリ秒単位)。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME} +</td> + + <td>イベントの終了時刻(エポックからのミリ秒単位)。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract#EXTRA_EVENT_ALL_DAY CalendarContract.EXTRA_EVENT_ALL_DAY} +</td> + + <td>イベントが終日かどうかを示すブール値。使用できる値は <code>true</code> または <code>false</code> です。 +</td> </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION Events.EVENT_LOCATION} +</td> + + <td>イベントの場所。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION Events.DESCRIPTION} +</td> + + <td>イベントの説明。</td> + </tr> + <tr> + <td> + {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}</td> + <td>招待者のメールアドレス(コンマ区切りリスト形式)。</td> + </tr> + <tr> + <td> + {@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE}</td> + <td>イベントの反復ルール。</td> + </tr> + <tr> + <td> + {@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL Events.ACCESS_LEVEL} +</td> + + <td>イベントが公開か非公開か。</td> + </tr> + <tr> + <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY Events.AVAILABILITY} +</td> + + <td>このイベントを埋まっている時間に数えるか、それともスケジュールのやり直しが利く空き時間とみなすか。</td> + +</table> +<p>次のセクションでは、これらのインテント使用方法を説明します。</p> + + +<h3 id="intent-insert">インテントを使用したイベントの挿入</h3> + +<p>{@link android.content.Intent#ACTION_INSERT INSERT} インテントを使用すると、アプリケーションはイベント挿入タスクをカレンダーそのものに引き渡すことができます。このアプローチでは、アプリケーションは {@link android.Manifest.permission#WRITE_CALENDAR} パーミッションを<a href="#manifest">マニフェスト ファイル</a>に含める必要さえなくなります。 + + +</p> + + +<p>このアプローチのアプリケーションをユーザーが実行すると、アプリケーションによってユーザーがカレンダーに誘導されイベントを追加できるようになります。 +{@link android.content.Intent#ACTION_INSERT INSERT} インテントは、追加フィールドを使用して、カレンダーに格納されている詳細情報をフォームに自動入力します。 + +それに対して、ユーザーはイベントのキャンセル、必要に応じたイベントの編集、イベントのカレンダーへの保存ができます。 + +</p> + + + +<p>次に示すのは、2012 年 1 月 19 日の午前 7:30 から 午前 8:30 までのイベントをスケジュールするコード スニペットです。 +このコード スニペットの以下の点に注目してください。</p> + +<ul> + <li>URI として {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} を指定しています。 +</li> + + <li>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME} と {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME} の各エクストラ フィールドを使用して、イベントの時間をフォームに自動入力しています。 + + + + +これらの値は、エポックからの UTC ミリ秒単位であることが必要です。 +</li> + + <li>{@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL} エクストラ フィールドを使用して、参加者をメールアドレスで示したコンマ区切りリストを指定しています。 +</li> + +</ul> +<pre> +Calendar beginTime = Calendar.getInstance(); +beginTime.set(2012, 0, 19, 7, 30); +Calendar endTime = Calendar.getInstance(); +endTime.set(2012, 0, 19, 8, 30); +Intent intent = new Intent(Intent.ACTION_INSERT) + .setData(Events.CONTENT_URI) + .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()) + .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()) + .putExtra(Events.TITLE, "Yoga") + .putExtra(Events.DESCRIPTION, "Group class") + .putExtra(Events.EVENT_LOCATION, "The gym") + .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY) + .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com"); +startActivity(intent); +</pre> + +<h3 id="intent-edit">インテントを使用したイベントの編集</h3> + +<p>イベントは、<a href="#update-event">イベントのアップデート</a>で説明したように、直接アップデートできます。ただし、{@link android.content.Intent#ACTION_EDIT EDIT} インテントを使用すれば、パーミッションのないアプリケーションが、カレンダー アプリケーションにイベント編集を引き渡すことができます。カレンダーでのイベント編集を終えたユーザーは、元のアプリケーションに戻ります。 + + + +</p> <p>次の例のインテントは、指定されたイベントの新しいタイトルを設定して、ユーザーがそのイベントをカレンダーで編集できるようにしています。 +</p> + + +<pre>long eventID = 208; +Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); +Intent intent = new Intent(Intent.ACTION_EDIT) + .setData(uri) + .putExtra(Events.TITLE, "My New Title"); +startActivity(intent);</pre> + +<h3 id="intent-view">インテントを使用したカレンダー データの参照</h3> +<p>カレンダー プロバイダには、{@link android.content.Intent#ACTION_VIEW VIEW} インテントを使用する次の 2 つの方法が用意されています。</p> +<ul> + <li>特定の日付のカレンダーを開く方法。</li> + <li>イベントを参照する方法。</li> + +</ul> +<p>次の例は、特定の日付のカレンダーを開く方法を示しています。</p> +<pre>// A date-time specified in milliseconds since the epoch. +long startMillis; +... +Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon(); +builder.appendPath("time"); +ContentUris.appendId(builder, startMillis); +Intent intent = new Intent(Intent.ACTION_VIEW) + .setData(builder.build()); +startActivity(intent);</pre> + +<p>次の例は、参照するためにイベントを開く方法を示しています。</p> +<pre>long eventID = 208; +... +Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); +Intent intent = new Intent(Intent.ACTION_VIEW) + .setData(uri); +startActivity(intent); +</pre> + + +<h2 id="sync-adapter">同期アダプタ</h2> + + +<p>アプリケーションと同期アダプタとの間で、カレンダー プロバイダにアクセスする方法の違いは、次のいくつかだけです。 +</p> + +<ul> + <li>同期アダプタは、{@link android.provider.CalendarContract#CALLER_IS_SYNCADAPTER} を <code>true</code> に設定して、それが同期アダプタであることを示す必要があります。</li> + + + <li>同期アダプタは、{@link android.provider.CalendarContract.SyncColumns#ACCOUNT_NAME} と {@link android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} をクエリ パラメータとして URI に指定する必要があります。 + + </li> + + <li>同期アダプタは、アプリケーションやウィジェットより多くの列に書き込みアクセスできます。 + たとえば、アプリケーションで変更できるのは、名前、表示名、可視性の設定、カレンダーが同期対象かどうかなど、カレンダーの特性の一部のみです。 + +それに対し、同期アダプタはこれらの列の他に、カレンダーの色、タイムゾーン、アクセスレベル、場所など、数多くにアクセスできます。ただし、<code>ACCOUNT_NAME</code> と <code>ACCOUNT_TYPE</code> で指定されるものだけに限定されます。 + + +</li> </ul> + +<p>次に示すヘルパー メソッドを使用すると、同期アダプタで使用するための URI が返されます。</p> +<pre> static Uri asSyncAdapter(Uri uri, String account, String accountType) { + return uri.buildUpon() + .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true") + .appendQueryParameter(Calendars.ACCOUNT_NAME, account) + .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build(); + } +</pre> +<p>同期アダプタの実装例(カレンダーに特化されたものではありません)については、<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a> をご覧ください。 + diff --git a/docs/html-intl/intl/ja/guide/topics/providers/contacts-provider.jd b/docs/html-intl/intl/ja/guide/topics/providers/contacts-provider.jd new file mode 100644 index 000000000000..e12b62f222c5 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/providers/contacts-provider.jd @@ -0,0 +1,2356 @@ +page.title=連絡先プロバイダ +@jd:body +<div id="qv-wrapper"> +<div id="qv"> +<h2>クイックビュー</h2> +<ul> + <li>人の情報に関する Android のリポジトリ。</li> + <li> + ウェブとの同期。 + </li> + <li> + ソーシャル ストリーム データの統合。 + </li> +</ul> +<h2>本書の内容</h2> +<ol> + <li> + <a href="#InformationTypes">連絡先プロバイダの構成</a> + </li> + <li> + <a href="#RawContactBasics">未加工連絡先</a> + </li> + <li> + <a href="#DataBasics">データ</a> + </li> + <li> + <a href="#ContactBasics">連絡先</a> + </li> + <li> + <a href="#Sources">同期アダプタからのデータ</a> + </li> + <li> + <a href="#Permissions">必要なパーミッション</a> + </li> + <li> + <a href="#UserProfile">ユーザー プロファイル</a> + </li> + <li> + <a href="#ContactsProviderMetadata">連絡先プロバイダのメタデータ</a> + </li> + <li> + <a href="#Access">連絡先プロバイダへのアクセス</a> + <li> + </li> + <li> + <a href="#SyncAdapters">連絡先プロバイダの同期アダプタ</a> + </li> + <li> + <a href="#SocialStream">ソーシャル ストリーム データ</a> + </li> + <li> + <a href="#AdditionalFeatures">連絡先プロバイダの追加機能</a> + </li> +</ol> +<h2>キークラス</h2> +<ol> + <li>{@link android.provider.ContactsContract.Contacts}</li> + <li>{@link android.provider.ContactsContract.RawContacts}</li> + <li>{@link android.provider.ContactsContract.Data}</li> + <li>{@code android.provider.ContactsContract.StreamItems}</li> +</ol> +<h2>関連サンプル</h2> +<ol> + <li> + <a href="{@docRoot}resources/samples/ContactManager/index.html"> Contact Manager </a> + + + </li> + <li> + <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html"> サンプル同期アダプタ</a> + + </li> +</ol> +<h2>関連ドキュメント</h2> +<ol> + <li> + <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> コンテンツ プロバイダの基本 </a> + + + </li> +</ol> +</div> +</div> +<p> + 連絡先プロバイダは、人のデータに関する端末の中央リポジトリを管理する、柔軟で効果的な Android コンポーネントです。 +連絡先プロバイダは、端末の連絡先アプリケーションに表示されるデータのソースであり、さらに独自アプリケーションで連絡先プロバイダのデータにアクセスし、端末とオンライン サービスとの間でデータを転送することもできます。 + +このプロバイダは幅広いデータソースに対応しており、各人に関してできるだけ多くのデータを管理しようとするため、複雑な構造をしています。 + +そのため、連絡先プロバイダの API には、データの取得と変更をどちらもやりやすくするクラスやインターフェースが多数用意されています。 + + +</p> +<p> + このガイドでは、以下について説明します。 +</p> + <ul> + <li> + プロバイダの基本構造。 + </li> + <li> + プロバイダからのデータの取得方法。 + </li> + <li> + プロバイダでのデータの変更方法。 + </li> + <li> + サーバーから連絡先プロバイダとデータを同期する同期アダプタの作成方法。 + + </li> + </ul> +<p> + このガイドは、Android のコンテンツ プロバイダの基礎知識がある読者を対象としています。Android のコンテンツ プロバイダについて詳しくは、「<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>」をご覧ください。 + + +<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a> サンプルアプリは、同期アダプタを使用して連絡先プロバイダと Google ウェブ サービスでホストされているサンプル アプリケーションとの間でデータを転送する例です。 + + + +</p> +<h2 id="InformationTypes">連絡先プロバイダの構成</h2> +<p> + 連絡先プロバイダは、Android のコンテンツ プロバイダ コンポーネントです。人に関する 3 種類のデータを保持しており、それぞれがコンテンツ プロバイダによって提供される 1 つのテーブルに対応しています。この構成を図 1 に示します。 + + +</p> +<img src="{@docRoot}images/providers/contacts_structure.png" alt="" height="364" id="figure1" /> +<p class="img-caption"> + <strong>図 1.</strong> 連絡先プロバイダのテーブル構造。 +</p> +<p> + この 3 つのテーブルは、一般にそれぞれのコントラクト クラス名で呼ばれます。各クラスは、テーブルによって使用されるコンテンツ URI、列名、列の値のための定数を定義しています。 + +</p> +<dl> + <dt> + {@link android.provider.ContactsContract.Contacts} テーブル + </dt> + <dd> + 各行は、未加工連絡先の行の集約に基づいて異なる人を表します。 + </dd> + <dt> + {@link android.provider.ContactsContract.RawContacts} テーブル + </dt> + <dd> + 各行には、ユーザーのアカウントとタイプに固有の、人に関するデータの概要が格納されています。 + </dd> + <dt> + {@link android.provider.ContactsContract.Data} テーブル + </dt> + <dd> + 各行には、メールアドレスや電話番号など、未加工連絡先の詳細情報が格納されています。 + </dd> +</dl> +<p> + {@link android.provider.ContactsContract} に含まれるコントラクト クラスによって表現される他のテーブルは補助テーブルであり、連絡先プロバイダがその操作を管理したり、端末の連絡先アプリや電話アプリの特定機能をサポートしたりするために使用します。 + + +</p> +<h2 id="RawContactBasics">未加工連絡先</h2> +<p> + 未加工連絡先は、アカウント タイプとアカウント名の 1 つのペアを使用して得られる人に関するデータです。 +連絡先プロバイダでは、1 人に関するデータのソースとして複数のオンライン サーバーを使用できるため、同じ個人に対して複数の未加工連絡先が許されます。 + + 未加工連絡先が複数ある場合、ユーザーは同じアカウント タイプの複数のアカウントから取得したその人のデータを組み合わせることができます。 + +</p> +<p> + 未加工連絡先データの大半は、{@link android.provider.ContactsContract.RawContacts} テーブルには格納されません。 +その代わり、{@link android.provider.ContactsContract.Data} テーブルの 1 つまたは複数の行に格納されています。 +各データ行には列 {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID Data.RAW_CONTACT_ID} があり、親 {@link android.provider.ContactsContract.RawContacts} 行の {@code android.provider.BaseColumns#_ID RawContacts._ID} 値が格納されています。 + + + +</p> +<h3 id="RawContactsColumns">重要な未加工連絡先列</h3> +<p> + 表 1 に、{@link android.provider.ContactsContract.RawContacts} の重要な列を示します。 +表の後の注もお読みください。 +</p> +<p class="table-caption" id="table1"> + <strong>表 1.</strong> 重要な未加工連絡先列。 +</p> +<table> + <tr> + <th scope="col">列名</th> + <th scope="col">用途</th> + <th scope="col">注</th> + </tr> + <tr> + <td> + {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_NAME} + </td> + <td> + この未加工連絡先のソースであるアカウント タイプにおけるアカウント名。 + たとえば、Google アカウントのアカウント名は、デバイス オーナーの Gmail アドレスのどれかです。 +詳しくは、次の {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} の項目をご覧ください。 + + + </td> + <td> + この名前の形式は、アカウント タイプによって異なります。必ずしもメールアドレスとは限りません。 + + </td> + </tr> + <tr> + <td> + {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} + </td> + <td> + この未加工連絡先のソースであるアカウント タイプ。たとえば、Google アカウントのアカウント タイプは <code>com.google</code> です。 +アカウント タイプは必ず、所有または管理しているドメインのドメイン ID で修飾してください。 +そうすることで、アカウント タイプが確実に一意になります。 + + </td> + <td> + 連絡先データを提供するアカウント タイプには、通常、連絡先プロバイダと同期する関連同期アダプタが用意されています。 + + </tr> + <tr> + <td> + {@link android.provider.ContactsContract.RawContactsColumns#DELETED} + </td> + <td> + 未加工連絡先の「削除済み」フラグ。 + </td> + <td> + 連絡先プロバイダは、同期アダプタが該当行をサーバーから削除し、最終的にリポジトリから削除するまで、このフラグを基に行を内部的に管理します。 + + + </td> + </tr> +</table> +<h4>注</h4> +<p> + 次に、{@link android.provider.ContactsContract.RawContacts} テーブルに関する重要な注を示します。 + +</p> +<ul> + <li> + 未加工連絡先の名前は、{@link android.provider.ContactsContract.RawContacts} の行には格納されません。 +その代わり、{@link android.provider.ContactsContract.Data} テーブルの {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 行に格納されます。 + +未加工連絡先は、このタイプの行を {@link android.provider.ContactsContract.Data} テーブルに 1 行だけ持ちます。 + + </li> + <li> + <strong>警告:</strong> 未加工連絡先の行で独自のアカウント データを使用する場合は、まずそれを {@link android.accounts.AccountManager} に登録する必要があります。 +登録するには、ユーザーに対し、アカウントのリストにアカウント タイプとアカウント名を追加するよう求めます。 +そうしないと、連絡先プロバイダによって未加工連絡先の行が自動的に削除されてしまいます。 + + <p> + たとえば、ドメインが {@code com.example.dataservice} であるウェブベースのサービス用に連絡先データをアプリで管理する場合、そのサービス用のユーザー アカウントが {@code becky.sharp@dataservice.example.com} であれば、そのユーザーが先にそのアカウントの「タイプ」({@code com.example.dataservice})と「名前」({@code becky.smart@dataservice.example.com})を追加しておくことで、アプリが未加工連絡先の行を追加できるようになります。 + + + + + この要件については、文書で説明するか、ユーザーにタイプと名前を追加するよう求めるか、あるいはその両方を実施してください。 +アカウントのタイプと名前については、次のセクションで詳しく説明します。 + + </li> +</ul> +<h3 id="RawContactsExample">未加工連絡先データのソース</h3> +<p> + 未加工連絡先の働きを理解するために、「Emily Dickinson」というユーザーについて考えてみましょう。彼女は自分の端末に次の 3 つのアカウントを定義しています。 + +</p> +<ul> + <li><code>emily.dickinson@gmail.com</code></li> + <li><code>emilyd@gmail.com</code></li> + <li>Twitter アカウント「belle_of_amherst」</li> +</ul> +<p> + このユーザーは、[<em>アカウント</em>] の設定でこの 3 つのアカウントすべてについて [<em>連絡先を同期</em>] を有効にしています。 + +</p> +<p> + Emily Dickinson がブラウザのウィンドウを開き、Gmail に <code>emily.dickinson@gmail.com</code> としてログインし、[連絡先] を開いて「Thomas Higginson」を追加したとしましょう。 + +後日、彼女が Gmail に <code>emilyd@gmail.com</code> としてログインし、メールを「Thomas Higginson」宛てに送信すると、彼は自動的に連絡先として追加されます。 + +彼女はまた、Twitter で「colonel_tom」(Thomas Higginson の Twitter ID)をフォローしています。 + +</p> +<p> + 連絡先プロバイダは、この操作の結果として次の 3 行の未加工連絡先を作成します。 +</p> +<ol> + <li> + 「Thomas Higginson」の、<code>emily.dickinson@gmail.com</code> に関連付けられた未加工連絡先。 + ユーザー アカウントのタイプは Google です。 + </li> + <li> + 「Thomas Higginson」の、<code>emilyd@gmail.com</code> に関連付けられた新たな未加工連絡先。 + ユーザー アカウントのタイプはやはり Google です。名前が前の行とまったく同じなのに新たな未加工連絡先が作成されたのは、この個人が異なるユーザー アカウントに追加されたからです。 + + + </li> + <li> + 「Thomas Higginson」の、「belle_of_amherst」に関連付けられた未加工連絡先。ユーザー アカウントのタイプは Twitter です。 + + </li> +</ol> +<h2 id="DataBasics">データ</h2> +<p> + 前にも説明したように、未加工連絡先のデータは未加工連絡先の <code>_ID</code> 値にリンクされている {@link android.provider.ContactsContract.Data} 行に格納されます。 + +これにより、1 つの未加工連絡先が同じタイプのデータ(メールアドレスや電話番号など)のインスタンスを複数持つことができます。 +たとえば、{@code emilyd@gmail.com} に対する「Thomas Higginson」(Google アカウント <code>emilyd@gmail.com</code> に関連付けられた、Thomas Higginson の未加工連絡先の行)には、<code>thigg@gmail.com</code> という個人用アドレスと <code>thomas.higginson@gmail.com</code> という仕事用アドレスがあり、連絡先プロバイダはこの 2 つのメールアドレスの行を格納し、両方とも同じ未加工連絡先にリンクします。 + + + + + +</p> +<p> + 異なるタイプのデータが同じテーブルに格納されることに注目してください。表示名、電話番号、メール、住所、写真、ウェブサイトに関する詳細行はすべて、{@link android.provider.ContactsContract.Data} テーブルにあります。 + +これを管理しやすくするため、{@link android.provider.ContactsContract.Data} テーブルの一部の行には説明的な名前が、それ以外には一般的な名前がそれぞれ付いています。 + +説明的な名前が付いた列の内容は、行データのタイプによらず意味が同じなのに対し、一般的な名前が付いた列の内容は、データのタイプによって意味が異なります。 + + +</p> +<h3 id="DescriptiveColumns">説明的な名前の列</h3> +<p> + 説明的な名前が付いた列の例をいくつか示します。 +</p> +<dl> + <dt> + {@link android.provider.ContactsContract.Data#RAW_CONTACT_ID} + </dt> + <dd> + このデータの、未加工連絡先の <code>_ID</code> 列の値。 + </dd> + <dt> + {@link android.provider.ContactsContract.Data#MIMETYPE} + </dt> + <dd> + カスタム MIME タイプで表現した、この行に格納されているデータのタイプ。連絡先プロバイダは、{@link android.provider.ContactsContract.CommonDataKinds} のサブクラスに定義されている MIME タイプを使用します。 + +これらの MIME タイプはオープンソースで、連絡先プロバイダと連携する任意のアプリケーションまたは同期アダプタで使用できます。 + + </dd> + <dt> + {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} + </dt> + <dd> + このタイプのデータ行が 1 つの未加工連絡先に対して複数発生する場合、{@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} 列はそのタイプに対するプライマリ データを含むデータ行を示します。 + +たとえば、ユーザーがある連絡先の電話番号を長押しし、[<strong>デフォルトに設定</strong>] を選択すると、その番号を含む {@link android.provider.ContactsContract.Data} 行の {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} 列にゼロでない値が設定されます。 + + + + + </dd> +</dl> +<h3 id="GenericColumns">汎用名の列</h3> +<p> + 自由に使用できる <code>DATA1</code> ~ <code>DATA15</code> という 15 個の汎用列の他に、同期アダプタしか使用してはいけない <code>SYNC1</code> ~ <code>SYNC4</code> という 4 個の列があります。 + + +汎用名列の定数は、行に指定されているデータのタイプによらず、常に機能します。 + +</p> +<p> + <code>DATA1</code> 列はインデックス付きです。連絡先プロバイダは常に、この列を、最も頻繁にクエリの対象となるとプロバイダが予想するデータ用の列として使用します。 +たとえば、メールの行では、この列には実際のメールアドレスが格納されます。 + +</p> +<p> + <code>DATA15</code> は慣例として、写真サムネイルのようなバイナリ ラージ オブジェクト(BLOB)データ用に予約されています。 + +</p> +<h3 id="TypeSpecificNames">タイプ固有の列名</h3> +<p> + 特定タイプの行に含まれる列に対する作業をやりやすくするため、連絡先プロバイダではタイプ固有の列名定数もあり、たとえば {@link android.provider.ContactsContract.CommonDataKinds} のサブクラスに定義されています。 + +こうした定数は、同じ列名に異なる定数名を充てて、特定タイプの行に含まれるデータにアクセスしやすくしているだけのものです。 + + +</p> +<p> + たとえば、{@link android.provider.ContactsContract.CommonDataKinds.Email} クラスには、MIME タイプが {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE Email.CONTENT_ITEM_TYPE} である{@link android.provider.ContactsContract.Data} 行向けにタイプ固有の列名定数が定義されています。 + + + +このクラスには、メールアドレス 列用に {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} という定数が含まれています。 + +{@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} の実際の値は「data1」で、これはこの列の汎用名と同じです。 + + +</p> +<p class="caution"> + <strong>警告:</strong> 連絡先プロバイダにあらかじめ定義されている MIME タイプのどれかである行を使用している {@link android.provider.ContactsContract.Data} テーブルには、独自のカスタムデータを追加しないでください。 + +追加すると、データが失われたり、連絡先プロバイダが誤動作したりすることがあります。 +たとえば、メールアドレスではなくユーザー名が格納されている MIME タイプ {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE Email.CONTENT_ITEM_TYPE} の行は、列 <code>DATA1</code> には追加しないでください。 + + +一方、行に独自のカスタム MIME タイプを使用している場合は、独自のタイプ固有名を定義して列を自由に使用してかまいません。 + +</p> +<p> + 図 2 に、説明的な名前の列とデータ列で {@link android.provider.ContactsContract.Data} 行がどう見えるか、そしてタイプ固有の列名が汎用列名をどう「オーバーレイ」するかを示します。 + + +</p> +<img src="{@docRoot}images/providers/data_columns.png" alt="How type-specific column names map to generic column names" height="311" id="figure2" /> +<p class="img-caption"> + <strong>図 2.</strong> タイプ固有の列名と汎用列名 +</p> +<h3 id="ColumnMaps">タイプ固有列名が使用されるクラス</h3> +<p> + 表 2 に、最もよく用いられるタイプ固有列名クラスを示します。 +</p> +<p class="table-caption" id="table2"> + <strong>表 2.</strong> タイプ固有列名が使用されるクラス</p> +<table> + <tr> + <th scope="col">対応クラス</th> + <th scope="col">データのタイプ</th> + <th scope="col">注</th> + </tr> + <tr> + <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredName}</td> + <td>このデータ行に関連付けられている未加工連絡先の名前データ。</td> + <td>1 つの未加工連絡先は、この行を 1 行だけ持ちます。</td> + </tr> + <tr> + <td>{@link android.provider.ContactsContract.CommonDataKinds.Photo}</td> + <td>このデータ行に関連付けられている未加工連絡先のメインの写真。</td> + <td>1 つの未加工連絡先は、この行を 1 行だけ持ちます。</td> + </tr> + <tr> + <td>{@link android.provider.ContactsContract.CommonDataKinds.Email}</td> + <td>このデータ行に関連付けられている未加工連絡先のメールレアドレス。</td> + <td>1 つの未加工連絡先は複数のメールアドレスを持つことができます。</td> + </tr> + <tr> + <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal}</td> + <td>このデータ行に関連付けられている未加工連絡先の住所。</td> + <td>1 つの未加工連絡先は複数の住所を持つことができます。</td> + </tr> + <tr> + <td>{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}</td> + <td>その未加工連絡先を連絡先プロバイダのグループのどれかにリンクする識別子。</td> + <td> + グループは、アカウント タイプとアカウント名のオプション機能です。詳しくは、<a href="#Groups">連絡先グループ</a>をご覧ください。 + + </td> + </tr> +</table> +<h3 id="ContactBasics">連絡先</h3> +<p> + 連絡先プロバイダは、すべてのアカウント タイプとアカウント名にわたって未加工連絡先の行を結び付けて 1 つの<strong>連絡先</strong>を形成します。 +これにより、1 人の人についてユーザーが集めた全データを表示したり変更したりしやすくなります。 +連絡先プロバイダは、新しい連絡先の行の作成と、既存の連絡先の行を使用した未加工連絡先の集約とを管理します。 +アプリケーションと同期アダプタは連絡先の追加はできず、連絡先の行の一部の列は読み取り専用です。 + +</p> +<p class="note"> + <strong>注:</strong> 連絡先を連絡先プロバイダに {@link android.content.ContentResolver#insert(Uri,ContentValues) insert()} を使用して追加しようとすると、{@link java.lang.UnsupportedOperationException} 例外が発生します。 + +「読み取り専用」になっている列をアップデートしようとしても、そのアップデートは無視されます。 + +</p> +<p> + 連絡先プロバイダは、既存の連絡先と一致しない新しい未加工連絡先が追加されると、それに対して新しい連絡先を作成します。 +また、既存の未加工連絡先のデータが変更され、それまで関連付けられていた連絡先と一致しなくなった場合にも、同じ処理がなされます。 + +アプリケーションまたは同期アダプタが、既存の連絡先と一致する新しい未加工連絡先を作成すると、その新しい未加工連絡先は既存の連絡先に集約されます。<em></em> + + +</p> +<p> + 連絡先プロバイダは、連絡先の行を未加工連絡先とリンクするのに、{@link android.provider.ContactsContract.Contacts Contacts} テーブルの <code>_ID</code> 列を使用します。 + +未加工連絡先テーブル {@link android.provider.ContactsContract.RawContacts} の <code>CONTACT_ID</code> 列には、未加工連絡先の各行に関連付けられている連絡先の行の <code>_ID</code> 値が格納されます。 + + +</p> +<p> + {@link android.provider.ContactsContract.Contacts} テーブルには列 {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} もあり、こちらは連絡先の行への「永久」リンクです。 + +連絡先プロバイダは連絡先を自動的に管理するため、集約や同期が行われると、それに応じて連絡先の行の {@code android.provider.BaseColumns#_ID} 値が変更される場合があります。 + +この処理が行われても、コンテンツ URI {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} と連絡先の {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} の組み合わせは、引き続きその連絡先の行を指すため、{@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} を使用して「お気に入り」の連絡先へのリンクを管理するなどができます。 + + + + +この列には、{@code android.provider.BaseColumns#_ID} 列の形式と関係のない独自の形式があります。 + +</p> +<p> + 図 3 に、3 つのテーブルの相互関係を示します。 +</p> +<img src="{@docRoot}images/providers/contacts_tables.png" alt="Contacts provider main tables" height="514" id="figure4" /> +<p class="img-caption"> + <strong>図 3.</strong> Contacts、RawContacts、Data の各テーブル間の関係。 +</p> +<h2 id="Sources">同期アダプタからのデータ</h2> +<p> + ユーザーは端末に連絡先データを直接入力しますが、データはウェブサービスから<strong>同期アダプタ</strong>を経由して連絡先プロバイダにも流れます。同期アダプタは、端末とサービスの間のデータ転送を自動化します。 + +同期アダフタはシステムの管理下でバックグラウンドで実行され、{@link android.content.ContentResolver} のメソッドを呼び出してデータを管理します。 + + +</p> +<p> + Android では、同期アダプタと連携するウェブサービスをアカウント タイプで識別します。 + 各同期アダプタが扱うアカウント タイプは 1 つですが、そのタイプのアカウント名を複数サポートできます。 +アカウント名とアカウント タイプについては、<a href="#RawContactsExample">未加工連絡先データのソース</a>で簡単に説明しています。 +次に、アカウント タイプとアカウント名が同期アダプタやサービスとどのような関係にあるかを詳しく説明します。 + +</p> +<dl> + <dt> + アカウント タイプ + </dt> + <dd> + ユーザーがデータを格納しているサービスを示します。ほとんどの場合、ユーザーにはサービスに対する認証が求められます。 +たとえば、Google Contacts はアカウント タイプの 1 つで、コード <code>google.com</code> で識別されます。 +この値は、{@link android.accounts.AccountManager} によって使用されるアカウント タイプに対応します。 + + </dd> + <dt> + アカウント名 + </dt> + <dd> + あるアカウント タイプで使用する特定のアカウントまたはログインを示します。Google Contacts アカウントは Google アカウントと同じで、アカウント名としてメールアドレスを使用します。 + + 他のサービスでは、1 語のユーザー名や数字の ID が使われていることもあります。 + </dd> +</dl> +<p> + アカウント タイプは、一意である必要はありません。1 人のユーザーが複数の Google Contacts アカウントを設定し、それぞれのデータを連絡先プロバイダにダウンロードする、ということが可能です。このような使い方は、そのユーザーが個人用のアカウント名で私用の連絡先を、仕事用のアカウント名で仕事用の連絡先を管理している場合にありえます。 + +アカウント名は、普通は一意です。 +この 2 つを組み合わせて、連絡先プロバイダと外部サービスとの間のある決まったデータフローを識別します。 + +</p> +<p> + 独自サービスのデータを連絡先プロバイダに転送する場合は、独自の同期アダプタを作成する必要があります。 +詳しくは、<a href="#SyncAdapters">連絡先プロバイダの同期アダプタ</a>をご覧ください。 + +</p> +<p> + 図 4 に、人に関するデータの流れにおける連絡先プロバイダの位置付けを示します。 +右から 2 列目の各ボックス内のアダプタには、そのアダプタのアカウント タイプが示されています。 +</p> +<img src="{@docRoot}images/providers/ContactsDataFlow.png" alt="Flow of data about people" height="252" id="figure5" /> +<p class="img-caption"> + <strong>図 4.</strong> 連絡先プロバイダに絡んだデータフロー。 +</p> +<h2 id="Permissions">必要なパーミッション</h2> +<p> + 連絡先プロバイダにアクセスするアプリケーションは、次のパーミッションを要求する必要があります。 + +</p> +<dl> + <dt>1 つ以上のテーブルに対する読み取りアクセス</dt> + <dd> + {@link android.Manifest.permission#READ_CONTACTS}。<code>AndroidManifest.xml</code> に <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"> + <uses-permission></a></code> 要素を使用して <code><uses-permission android:name="android.permission.READ_CONTACTS"></code> のように指定します。 + + + + </dd> + <dt>1 つ以上のテーブルに対する書き込みアクセス</dt> + <dd> + {@link android.Manifest.permission#WRITE_CONTACTS}。<code>AndroidManifest.xml</code> に <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"> + <uses-permission></a></code> 要素を使用して <code><uses-permission android:name="android.permission.WRITE_CONTACTS"></code> のように指定します。 + + + + </dd> +</dl> +<p> + これらのパーミッションは、ユーザー プロファイル データにまでは拡張されません。ユーザー プロファイルとそれに必要なパーミッションについては、次のセクションである<a href="#UserProfile">ユーザー プロファイル</a>で説明しています。 + + +</p> +<p> + ユーザーの連絡先データは個人的で秘密性の高い情報であることを再度ご確認ください。ユーザーはプライバシーに敏感であり、アプリケーションが自分や自分の連絡先に関するデータを集めることを望みません。 + + 連絡先データにアクセスするためのパーミッションが必要な理由が明らかでないと、ユーザーがアプリケーションを低く評価したりインストールを拒否したりすることがあります。 + +</p> +<h2 id="UserProfile">ユーザー プロファイル</h2> +<p> + {@link android.provider.ContactsContract.Contacts} テーブルには、その端末のユーザーのプロファイル データを格納している行が 1 行あります。 +このデータが記述しているのは端末の <code>user</code> であって、そのユーザーの連絡先ではありません。 +プロファイルの連絡先の行は、プロファイルを使用する各システムの未加工連絡先の行にリンクされています。 + + プロファイルの未加工連絡先の各行は、複数のデータ行を持つことができます。ユーザー プロファイルにアクセスするための定数は、{@link android.provider.ContactsContract.Profile} クラスに用意されています。 + +</p> +<p> + ユーザー プロファイルにアクセスするには、特別なパーミッションが必要です。読み取りと書き込みに必要な {@link android.Manifest.permission#READ_CONTACTS} パーミッションと {@link android.Manifest.permission#WRITE_CONTACTS} パーミッションの他に、ユーザー プロファイルに対する読み取りと書き込みのために {@code android.Manifest.permission#READ_PROFILE} パーミッションと {@code android.Manifest.permission#WRITE_PROFILE} パーミッションがそれぞれ必要です。 + + + + + +</p> +<p> + ユーザーのプロファイルは秘密性の高い情報であることを再度ご確認ください。パーミッション {@code android.Manifest.permission#READ_PROFILE} を使用すると、端末ユーザーの個人識別データにアクセスできます。 + +アプリケーションの説明には、ユーザー プロファイルへのアクセス パーミッションが必要な理由を必ず記載してください。 + +</p> +<p> + ユーザーのプロファイルが格納された連絡先の行を取得するには、{@link android.content.ContentResolver#query(Uri,String[], String, String[], String) ContentResolver.query()} を呼び出します。 + +コンテンツ URI を {@link android.provider.ContactsContract.Profile#CONTENT_URI} に設定し、選択条件は何も指定しません。 + +このコンテンツ URI は、そのプロファイルの未加工連絡先やデータを取得するためのベース URI としても使用できます。 +たとえば、次のスニペットは指定されたプロファイルのデータを取得します。 +</p> +<pre> +// Sets the columns to retrieve for the user profile +mProjection = new String[] + { + Profile._ID, + Profile.DISPLAY_NAME_PRIMARY, + Profile.LOOKUP_KEY, + Profile.PHOTO_THUMBNAIL_URI + }; + +// Retrieves the profile from the Contacts Provider +mProfileCursor = + getContentResolver().query( + Profile.CONTENT_URI, + mProjection , + null, + null, + null); +</pre> +<p class="note"> + <strong>注:</strong> 連絡先の行を複数取得する場合、そのなかの 1 つがユーザー プロファイルかどうかを確認するには、行の {@link android.provider.ContactsContract.ContactsColumns#IS_USER_PROFILE} 列をテストします。 + +その連絡先がユーザー プロファイルであれば、この列は「1」に設定されています。 + +</p> +<h2 id="ContactsProviderMetadata">連絡先プロバイダのメタデータ</h2> +<p> + 連絡先プロバイダは、連絡先データの状態を継続的に追跡するためのデータをリポジトリで管理します。 +リポジトリに関するこのメタデータは、RawContacts、Data、Contacts の各テーブルの行、{@link android.provider.ContactsContract.Settings} テーブル、{@link android.provider.ContactsContract.SyncState} テーブルなど、さまざまな場所に格納されています。 + + +次の表に、各メタデータの効果を示します。 + +</p> +<p class="table-caption" id="table3"> + <strong>表 3.</strong> 連絡先プロバイダに用意されているメタデータ</p> +<table> + <tr> + <th scope="col">テーブル</th> + <th scope="col">列</th> + <th scope="col">値</th> + <th scope="col">意味</th> + </tr> + <tr> + <td rowspan="2">{@link android.provider.ContactsContract.RawContacts}</td> + <td rowspan="2">{@link android.provider.ContactsContract.SyncColumns#DIRTY}</td> + <td>「0」 - 前回の同期以降、変更はありません。</td> + <td rowspan="2"> + 端末上で変更があり、サーバーと同期する必要がある未加工連絡先をマークします。 +Android アプリケーションが行をアップデートすると、連絡先プロバイダによって値が自動的に設定されます。 + + <p> + 未加工連絡先やデータのテーブルを変更する同期アダプタは、使用するコンテンツ URI の末尾に文字列 {@link android.provider.ContactsContract#CALLER_IS_SYNCADAPTER} を必ず追加してください。 + +これにより、プロバイダが行をダーティとマークするのを防ぐことができます。 + こうしないと、同期アダプタによる変更がローカルな変更と認識され、変更のソースがサーバーであるにもかかわらず、その変更がサーバーに送信されます。 + + </p> + </td> + </tr> + <tr> + <td>「1」 - 前回の同期以降に変更があり、サーバーへの同期が必要です。</td> + </tr> + <tr> + <td>{@link android.provider.ContactsContract.RawContacts}</td> + <td>{@link android.provider.ContactsContract.SyncColumns#VERSION}</td> + <td>この行のバージョン番号。</td> + <td> + この行またはその関連データが変更されるたび、連絡先プロバイダがこの値を自動的にインクリメントします。 + + </td> + </tr> + <tr> + <td>{@link android.provider.ContactsContract.Data}</td> + <td>{@link android.provider.ContactsContract.DataColumns#DATA_VERSION}</td> + <td>この行のバージョン番号。</td> + <td> + このデータ行が変更されるたび、連絡先プロバイダがこの値を自動的にインクリメントします。 + + </td> + </tr> + <tr> + <td>{@link android.provider.ContactsContract.RawContacts}</td> + <td>{@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}</td> + <td> + この未加工連絡先をそれが作成されたアカウントと一意に結び付ける文字列値。 + + </td> + <td> + 同期アダプタが新しい未加工連絡先を作成するたび、この列はその未加工連絡先に対するサーバーの一意の ID に設定される必要があります。 +Android アプリケーションが新しい未加工連絡先を作成した場合、そのアプリケーションはこの列を空欄のままにする必要があります。 +同期アダプタはこれを確認して、サーバー上に新しい未加工連絡先を作成し、{@link android.provider.ContactsContract.SyncColumns#SOURCE_ID} の値を取得します。 + + + <p> + 特に、ソース ID はアカウント タイプごとに<strong>一意</strong>で、同期中に安定している必要があります。 + + </p> + <ul> + <li> + Unique: アカウントの各未加工連絡先には独自のソース ID が必要です。これを強制しないと、連絡先アプリケーションに問題を引き起こすことになります。 + + 同じアカウント <em>タイプ</em>に対する 2 つの未加工連絡先が、同じソース ID を持つことがありえます。 +たとえば、アカウント {@code emily.dickinson@gmail.com} の未加工連絡先「Thomas Higginson」は、アカウント {@code emilyd@gmail.com} の未加工連絡先「Thomas Higginson」と同じソース ID を持つことができます。 + + + + </li> + <li> + Stable: ソース ID は、未加工連絡先のオンライン サービス データにおいて変わらない部分です。 +たとえば、ユーザーが [アプリ] 設定から [連絡先ストレージ] を消去し、再同期したとしても、復元された未加工連絡先のソース ID は以前と同じになります。 + +これを強制しないと、ショートカットが機能しなくなります。 + + </li> + </ul> + </td> + </tr> + <tr> + <td rowspan="2">{@link android.provider.ContactsContract.Groups}</td> + <td rowspan="2">{@link android.provider.ContactsContract.GroupsColumns#GROUP_VISIBLE}</td> + <td>「0」 - このグループに属する連絡先が Android アプリケーションの UI に表示されなくなります。</td> + <td> + この列は、ユーザーが特定のグループに属する連絡先を非表示にすることを許可するサーバーに対して互換性を確保するために用意されています。 + + </td> + </tr> + <tr> + <td>「1」 - このグループに属する連絡先を Android アプリケーションの UI に表示できます。</td> + </tr> + <tr> + <td rowspan="2">{@link android.provider.ContactsContract.Settings}</td> + <td rowspan="2"> + {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE}</td> + <td> + 「0」 - このアカウントとアカウント タイプについて、グループに属さない連絡先は Android アプリケーションの UI に表示されなくなります。 + + </td> + <td rowspan="2"> + デフォルトでは、グループに属する未加工連絡先がないなら連絡先は表示されません(未加工連絡先のグループ メンバーシップは、{@link android.provider.ContactsContract.Data} テーブルの 1 つないし複数の {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} 行によって示されます)。 + + + + あるアカウントとアカウント タイプについて、{@link android.provider.ContactsContract.Settings} テーブルの行でこのフラグを設定すると、グループのない連絡先を強制的に表示できます。 + + このフラグの用途の 1 つとして、グループを使用しないサーバーから連絡先を取得して表示することが考えられます。 + </td> + </tr> + <tr> + <td> + 「0」 - このアカウントとアカウント タイプについて、グループに属さない連絡先が Android アプリケーションの UI に表示されます。 + + </td> + + </tr> + <tr> + <td>{@link android.provider.ContactsContract.SyncState}</td> + <td>(すべて)</td> + <td> + このテーブルを使用して、同期アダプタのメタデータを格納します。 + </td> + <td> + このテーブルを使用すると、同期状態などの同期関連データを永続的に端末上に格納できます。 + + </td> + </tr> +</table> +<h2 id="Access">連絡先プロバイダへのアクセス</h2> +<p> + このセクションでは、連絡先プロバイダからのデータにアクセスするためのガイドラインについて、以下に注目して説明します。 + +</p> +<ul> + <li> + エンティティ クエリ。 + </li> + <li> + バッチ変更。 + </li> + <li> + インテントを使用した取得と変更。 + </li> + <li> + データ整合性。 + </li> +</ul> +<p> + 同期アダプタからの変更については、<a href="#SyncAdapters">連絡先プロバイダの同期アダプタ</a>でも詳しく説明しています。 + +</p> +<h3 id="Entities">エンティティのクエリ</h3> +<p> + 連絡先プロバイダのテーブルは階層構造になっており、ある行とその「子」の行すべてを取得すると便利なことがよくあります。 +たとえば、ある人に関するすべての情報を表示するために、{@link android.provider.ContactsContract.Contacts} 行 1 行に対するすべての {@link android.provider.ContactsContract.RawContacts} 行や、{@link android.provider.ContactsContract.RawContacts} 行 1 行に対するすべての {@link android.provider.ContactsContract.CommonDataKinds.Email} 行を取得することが考えられます。 + + + + +こうした処理をやりやすくするため、連絡先プロバイダには<strong>エンティティ</strong>構造が用意されています。これは、テーブル間でのデータベースの和集合のように機能します。 + + +</p> +<p> + 1 つのエンティティは、ある親テーブルとその子テーブルから選ばれた列からなるテーブルのようなものです。 + エンティティをクエリする場合は、そのエンティティで使用できる列に基づいてプロジェクションと検索の条件を指定します。 +その結果が {@link android.database.Cursor} で、取得された各子テーブル行につき 1 行を含みます。 +たとえば、ある連絡先名と、その名前のすべての未加工連絡先の {@link android.provider.ContactsContract.CommonDataKinds.Email} 行について、{@link android.provider.ContactsContract.Contacts.Entity} をクエリすると、各 {@link android.provider.ContactsContract.CommonDataKinds.Email} 行につき 1 行を含む {@link android.database.Cursor} が得られます。 + + + + +</p> +<p> + エンティティにより、クエリが簡素化されます。エンティティを使用することで、ある連絡先または未加工連絡先の連絡先データをすべて取得できるため、まず親テーブルにクエリして ID を取得し、次にその ID 使用して子テーブルにクエリする必要がありません。また、連絡先プロバイダは、エンティティに対するクエリを 1 回のトランザクションで処理することから、取得されたデータの内部的な整合性が保証されます。 + + + + +</p> +<p class="note"> + <strong>注:</strong> エンティティには通常、親テーブルと子テーブルのすべての列が含まれるわけではありません。 +そのエンティティの列名定数のリストにない列名に対して作業しようとすると、{@link java.lang.Exception} が発生します。 + +</p> +<p> + 次のスニペットは、ある連絡先のすべての未加工連絡先を取得する方法を示しています。このスニペットは、「メイン」と「詳細」という 2 つのアクティビティを持つ、もっと大きなアプリケーションの一部です。 +メイン アクティビティは、連絡先の行の一覧を示します。ユーザーが 1 つを選択すると、このアクティビティはその ID を詳細アクティビティに送ります。 + +詳細アクティビティは {@link android.provider.ContactsContract.Contacts.Entity} を使用して、選択した連絡先と関連付けられているすべての未加工連絡先から取得したすべてのデータ行を示します。 + + +</p> +<p> + このスニペットは「詳細」アクティビティからの抜粋です。 +</p> +<pre> +... + /* + * Appends the entity path to the URI. In the case of the Contacts Provider, the + * expected URI is content://com.google.contacts/#/entity (# is the ID value). + */ + mContactUri = Uri.withAppendedPath( + mContactUri, + ContactsContract.Contacts.Entity.CONTENT_DIRECTORY); + + // Initializes the loader identified by LOADER_ID. + getLoaderManager().initLoader( + LOADER_ID, // The identifier of the loader to initialize + null, // Arguments for the loader (in this case, none) + this); // The context of the activity + + // Creates a new cursor adapter to attach to the list view + mCursorAdapter = new SimpleCursorAdapter( + this, // the context of the activity + R.layout.detail_list_item, // the view item containing the detail widgets + mCursor, // the backing cursor + mFromColumns, // the columns in the cursor that provide the data + mToViews, // the views in the view item that display the data + 0); // flags + + // Sets the ListView's backing adapter. + mRawContactList.setAdapter(mCursorAdapter); +... +@Override +public Loader<Cursor> onCreateLoader(int id, Bundle args) { + + /* + * Sets the columns to retrieve. + * RAW_CONTACT_ID is included to identify the raw contact associated with the data row. + * DATA1 contains the first column in the data row (usually the most important one). + * MIMETYPE indicates the type of data in the data row. + */ + String[] projection = + { + ContactsContract.Contacts.Entity.RAW_CONTACT_ID, + ContactsContract.Contacts.Entity.DATA1, + ContactsContract.Contacts.Entity.MIMETYPE + }; + + /* + * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw + * contact collated together. + */ + String sortOrder = + ContactsContract.Contacts.Entity.RAW_CONTACT_ID + + " ASC"; + + /* + * Returns a new CursorLoader. The arguments are similar to + * ContentResolver.query(), except for the Context argument, which supplies the location of + * the ContentResolver to use. + */ + return new CursorLoader( + getApplicationContext(), // The activity's context + mContactUri, // The entity content URI for a single contact + projection, // The columns to retrieve + null, // Retrieve all the raw contacts and their data rows. + null, // + sortOrder); // Sort by the raw contact ID. +} +</pre> +<p> + 読み込みが完了すると、{@link android.app.LoaderManager} は {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished(Loader, D) onLoadFinished()} に対するコールバックを起動します。 + +このメソッドへの入力引数の 1 つは、クエリの結果を含む {@link android.database.Cursor} です。 +独自アプリでは、データをこの {@link android.database.Cursor} から取得して表示したりさらに処理したりできます。 + +</p> +<h3 id="Transactions">バッチ変更</h3> +<p> + 可能であれば必ず、連絡先プロバイダのデータを「バッチモード」で挿入、アップデート、削除してください。そのためには、{@link android.content.ContentProviderOperation} オブジェクトの {@link java.util.ArrayList} を作成し、{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} を呼び出します。 + + +連絡先プロバイダはすべての操作を 1 つのトランザクションの 1 つの {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} で行うため、変更内容が連絡先リポジトリで不整合のままになることは決してありません。 + + + +また、バッチ変更では、未加工連絡先とその詳細データを同時に挿入しやすくなっています。 + +</p> +<p class="note"> + <strong>注:</strong> <em>1 つ</em>の未加工連絡先を変更する場合は、変更を独自アプリ内で処理するのではなく、インテントを端末の連絡先アプリケーションに送信することを検討してください。この方法については、<a href="#Intents">インテントを使用した取得と変更</a>で詳しく説明しています。 + + + +</p> +<h4>明け渡し点</h4> +<p> + 多数の操作を伴うバッチ変更は、他のプロセスをブロックしてユーザーにとっての全体的な使用感を悪化させかねません。 +意図したすべての変更をできるだけ少ない個別リストに整理するとともに、それらがシステムをブロックしないようにするために、1 つまたは複数の操作に<strong>明け渡し点</strong>を設定してください。 + + + 明け渡し点の実体は、{@link android.content.ContentProviderOperation#isYieldAllowed()} の値が <code>true</code> に設定された {@link android.content.ContentProviderOperation} オブジェクトです。 + +連絡先プロバイダが明け渡し点に遭遇すると、作業を一時中断して他のプロセスを実行させ、現在のトランザクションをクローズします。 +作業を再開した連絡先プロバイダは、{@link java.util.ArrayList} に含まれている次の操作を行い、新しいトランザクションを始めます。 + + +</p> +<p> + 明け渡し点により、{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} の呼び出し 1 回につき複数のトランザクションが発生します。 +そのため、明け渡し点は 1 組の関連する行への最後の操作に設定してください。 + + たとえば、未加工連絡先の行とその関連データ行を追加する一連の操作の最後に、あるいは 1 人の連絡先に関連する 1 組の行に対する最後の操作に、明け渡し点を設定します。 + + +</p> +<p> + 明け渡し点は、アトミック操作の単位でもあります。2 つの明け渡し点間のすべてのアクセスは、1 つのまとまりとして成功または失敗します。 +明け渡し点を設定しない場合、最小のアトミック操作は操作のバッチ全体になります。 +明け渡し点を使用すると、操作がシステムのパフォーマンスを低下させるのを防ぐと同時に、操作の一部分が確実にアトミックになります。 + + +</p> +<h4>変更の後方参照</h4> +<p> + 新しい未加工連絡先の行とその関連データの行を 1 組の {@link android.content.ContentProviderOperation} オブジェクトとして挿入している場合は、データの行を未加工連絡先の行にリンクする必要があります。そのためには、未加工連絡先の {@code android.provider.BaseColumns#_ID} 値を {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} 値として挿入します。 + + + +ただし、この値は、データの行のために{@link android.content.ContentProviderOperation} を作成している間は使用できません。未加工連絡先に {@link android.content.ContentProviderOperation} 操作がまだ適用されていないからです。 + + +これを回避するため、{@link android.content.ContentProviderOperation.Builder} クラスにはメソッド {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} が用意されています。 + + + このメソッドを使用すると、前の操作の結果を使用して列を挿入または変更できます。 + +</p> +<p> + {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} メソッドには引数が 2 つあります。 + +</p> + <dl> + <dt> + <code>key</code> + </dt> + <dd> + キーと値のペアのキーです。この引数の値は、変更中のテーブルに含まれる列であることが必要です。 + + </dd> + <dt> + <code>previousResult</code> + </dt> + <dd> + {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} から取得した {@link android.content.ContentProviderResult} オブジェクトの配列に含まれる値の、0 ベースのインデックスです。 + +バッチ操作が適用されると、各操作の結果は結果用の中間配列に格納されます。 + +<code>previousResult</code> 値はそうした結果の 1 つのインデックスで、<code>key</code> 値を使用して取得され、格納されます。 + +これにより、新しい未加工連絡先レコードを挿入してその {@code android.provider.BaseColumns#_ID} 値に戻り、次に {@link android.provider.ContactsContract.Data} 行を追加するときにその値を「後方参照」できます。 + + + <p> + {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} を初めて呼び出すと、指定した {@link android.content.ContentProviderOperation} オブジェクトの {@link java.util.ArrayList} と同じサイズを使用して、結果配列全体が作成されます。 + + +ただし、結果配列に含まれるすべての要素は <code>null</code> に設定され、そのためまだ適用されていない操作から結果を後方参照しようとすると {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} が {@link java.lang.Exception} をスローします。 + + + + + + </p> + </dd> + </dl> +<p> + 次のスニペットは、新しい未加工連絡先とデータをバッチで挿入する方法を示しています。その中には、明け渡し点を指定し、後方参照を使用するコードが含まれています。 +これらのスニペットは、<code><a href="{@docRoot}resources/samples/ContactManager/index.html"> + Contact Manager</a></code> サンプル アプリケーションの <code>ContactAdder</code> クラスの一部である <code>createContacEntry()</code> メソッドの拡張版です。 + + + +</p> +<p> + 最初のスニペットは、連絡先データを UI から取得します。この時点で、ユーザーは新しい未加工連絡先の追加先となるアカウントを既に選択してあります。 + +</p> +<pre> +// Creates a contact entry from the current UI values, using the currently-selected account. +protected void createContactEntry() { + /* + * Gets values from the UI + */ + String name = mContactNameEditText.getText().toString(); + String phone = mContactPhoneEditText.getText().toString(); + String email = mContactEmailEditText.getText().toString(); + + int phoneType = mContactPhoneTypes.get( + mContactPhoneTypeSpinner.getSelectedItemPosition()); + + int emailType = mContactEmailTypes.get( + mContactEmailTypeSpinner.getSelectedItemPosition()); +</pre> +<p> + 次のスニペットは、未加工連絡先の行を {@link android.provider.ContactsContract.RawContacts} テーブルに挿入する操作を作成します。 + +</p> +<pre> + /* + * Prepares the batch operation for inserting a new raw contact and its data. Even if + * the Contacts Provider does not have any data for this person, you can't add a Contact, + * only a raw contact. The Contacts Provider will then add a Contact automatically. + */ + + // Creates a new array of ContentProviderOperation objects. + ArrayList<ContentProviderOperation> ops = + new ArrayList<ContentProviderOperation>(); + + /* + * Creates a new raw contact with its account type (server type) and account name + * (user's account). Remember that the display name is not stored in this row, but in a + * StructuredName data row. No other data is required. + */ + ContentProviderOperation.Builder op = + ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) + .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType()) + .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName()); + + // Builds the operation and adds it to the array of operations + ops.add(op.build()); +</pre> +<p> + 次に、表示名、電話、メールのデータ行を作成します。 +</p> +<p> + 操作の各ビルダー オブジェクトは、{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} を使用して {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} を取得します。 + + +この参照が最初の操作からの {@link android.content.ContentProviderResult} オブジェクトを後方参照しており、それが未加工連絡先の行を追加し、新しい {@code android.provider.BaseColumns#_ID} 値を返します。 + + +その結果、各データ行はその {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} によって、属する新しい {@link android.provider.ContactsContract.RawContacts} 行に自動的にリンクされます。 + + +</p> +<p> + メール行を追加する {@link android.content.ContentProviderOperation.Builder} オブジェクトは、明け渡し点を設定する {@link android.content.ContentProviderOperation.Builder#withYieldAllowed(boolean) withYieldAllowed()} でフラグ付けされます。 + + +</p> +<pre> + // Creates the display name for the new raw contact, as a StructuredName data row. + op = + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + /* + * withValueBackReference sets the value of the first argument to the value of + * the ContentProviderResult indexed by the second argument. In this particular + * call, the raw contact ID column of the StructuredName data row is set to the + * value of the result returned by the first operation, which is the one that + * actually adds the raw contact row. + */ + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + + // Sets the data row's MIME type to StructuredName + .withValue(ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) + + // Sets the data row's display name to the name in the UI. + .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name); + + // Builds the operation and adds it to the array of operations + ops.add(op.build()); + + // Inserts the specified phone number and type as a Phone data row + op = + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + /* + * Sets the value of the raw contact id column to the new raw contact ID returned + * by the first operation in the batch. + */ + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + + // Sets the data row's MIME type to Phone + .withValue(ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) + + // Sets the phone number and type + .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone) + .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType); + + // Builds the operation and adds it to the array of operations + ops.add(op.build()); + + // Inserts the specified email and type as a Phone data row + op = + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + /* + * Sets the value of the raw contact id column to the new raw contact ID returned + * by the first operation in the batch. + */ + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + + // Sets the data row's MIME type to Email + .withValue(ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) + + // Sets the email address and type + .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email) + .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType); + + /* + * Demonstrates a yield point. At the end of this insert, the batch operation's thread + * will yield priority to other threads. Use after every set of operations that affect a + * single contact, to avoid degrading performance. + */ + op.withYieldAllowed(true); + + // Builds the operation and adds it to the array of operations + ops.add(op.build()); +</pre> +<p> + 最後のスニペットは、新しい未加工連絡先とデータ行を挿入する {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} を呼び出しています。 + + +</p> +<pre> + // Ask the Contacts Provider to create a new contact + Log.d(TAG,"Selected account: " + mSelectedAccount.getName() + " (" + + mSelectedAccount.getType() + ")"); + Log.d(TAG,"Creating contact: " + name); + + /* + * Applies the array of ContentProviderOperation objects in batch. The results are + * discarded. + */ + try { + + getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); + } catch (Exception e) { + + // Display a warning + Context ctx = getApplicationContext(); + + CharSequence txt = getString(R.string.contactCreationFailure); + int duration = Toast.LENGTH_SHORT; + Toast toast = Toast.makeText(ctx, txt, duration); + toast.show(); + + // Log exception + Log.e(TAG, "Exception encountered while inserting contact: " + e); + } +} +</pre> +<p> + バッチ処理を使用すると、<strong>楽観的並行性制御</strong>を実装できます。これは、背後のリポジトリをロックする必要なく変更トランザクションを適用する手法です。 + + この手法を使用するには、トランザクションを適用してから、同時に行うことのできる可能性のある他の変更をチェックします。 +一貫性のない変更が発生していることがわかった場合は、トランザクションをロールバックしてやり直します。 + +</p> +<p> + 楽観的並行性制御は、一度に使用するユーザーが 1 人でデータリポジトリへの同時アクセスがまれなモバイル端末に便利です。 +ロックが使用されないため、ロックの設定や他のトランザクションによるロックの解放待ちで時間を無駄にしません。 + +</p> +<p> + {@link android.provider.ContactsContract.RawContacts} 行を 1 行更新している間に楽観的並行性制御を使用する方法は次のとおりです。 + +</p> +<ol> + <li> + 取得する他のデータとともに、未加工連絡先の {@link android.provider.ContactsContract.SyncColumns#VERSION} 列を取得します。 + + </li> + <li> + 制約を強制するのに適した {@link android.content.ContentProviderOperation.Builder} オブジェクトを、メソッド {@link android.content.ContentProviderOperation#newAssertQuery(Uri)} を使用して作成します。 + +コンテンツ URI に、未加工連絡先の {@code android.provider.BaseColumns#_ID} が末尾に追加された {@link android.provider.ContactsContract.RawContacts#CONTENT_URI RawContacts.CONTENT_URI} を使用します。 + + + + </li> + <li> + {@link android.content.ContentProviderOperation.Builder} オブジェクトに対し、{@link android.content.ContentProviderOperation.Builder#withValue(String, Object) withValue()} を呼び出して、{@link android.provider.ContactsContract.SyncColumns#VERSION} 列と取得したばかりのバージョン番号を比較します。 + + + + </li> + <li> + 同じ {@link android.content.ContentProviderOperation.Builder} に対し、{@link android.content.ContentProviderOperation.Builder#withExpectedCount(int) withExpectedCount()} を呼び出して、このアサーションで 1 行だけがテストされるようにします。 + + + </li> + <li> + {@link android.content.ContentProviderOperation.Builder#build()} を呼び出して {@link android.content.ContentProviderOperation} オブジェクトを作成し、次のこのオブジェクトを {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} に渡す {@link java.util.ArrayList} に先頭オブジェクトとして追加します。 + + + + </li> + <li> + バッチトランザクションを適用します。 + </li> +</ol> +<p> + 目的の未加工連絡先の行が、行の読み込みからその変更の試行までの間に別の操作によってアップデートされた場合、{@link android.content.ContentProviderOperation} の「アサート」が失敗し、操作のバッチ全体がバックアウトされます。 + +バックアウトが終わったら、バッチをやり直すこと、または他のアクションを行うことができます。 + +</p> +<p> + 次のスニペットは、{@link android.content.CursorLoader} を使用して未加工連絡先を 1 つクエリした後に、{@link android.content.ContentProviderOperation} を「アサート」します。 + + +</p> +<pre> +/* + * The application uses CursorLoader to query the raw contacts table. The system calls this method + * when the load is finished. + */ +public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { + + // Gets the raw contact's _ID and VERSION values + mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)); + mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION)); +} + +... + +// Sets up a Uri for the assert operation +Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID); + +// Creates a builder for the assert operation +ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri); + +// Adds the assertions to the assert operation: checks the version and count of rows tested +assertOp.withValue(SyncColumns.VERSION, mVersion); +assertOp.withExpectedCount(1); + +// Creates an ArrayList to hold the ContentProviderOperation objects +ArrayList ops = new ArrayList<ContentProviderOperationg>; + +ops.add(assertOp.build()); + +// You would add the rest of your batch operations to "ops" here + +... + +// Applies the batch. If the assert fails, an Exception is thrown +try + { + ContentProviderResult[] results = + getContentResolver().applyBatch(AUTHORITY, ops); + + } catch (OperationApplicationException e) { + + // Actions you want to take if the assert operation fails go here + } +</pre> +<h3 id="Intents">インテントを使用した取得と変更</h3> +<p> + インテントを端末の連絡先アプリケーションに送信すると、連絡先プロバイダに間接的にアクセスできます。 +インテントが端末の連絡先アプリケーション UI を起動し、ユーザーはそこで連絡先関連の作業を行えます。 +このタイプのアクセスで、ユーザーは次の作業ができます。 + <ul> + <li>連絡先をリストから選び、アプリケーションに返してさらに作業する。</li> + <li>既存の連絡先データを編集する。</li> + <li>任意のアカウントに新しい未加工連絡先を挿入する。</li> + <li>連絡先または連絡先データを削除する。</li> + </ul> +<p> + ユーザーがデータを挿入またはアップデートしている場合は、まずデータを収集し、次にそれをインテントの一部として送信できます。 + +</p> +<p> + インテントを使用して端末の連絡先アプリケーション経由で連絡先プロバイダにアクセスする場合、連絡先プロバイダにアクセスするための独自の UI やコードを作成する必要はありません。 +また、連絡先プロバイダに対する読み取りや書き込みのパーミッションを要求する必要もありません。 +端末の連絡先アプリケーションは、連絡先に対する読み取りパーミッションをデリゲートできます。また、連絡先プロバイダへの変更を他のアプリケーション経由で行っていることから、書き込みパーミッションは不要です。 + + +</p> +<p> + プロバイダにアクセスするためのインテントを送信する汎用プロセスについては、<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>のセクション「インテント経由のデータアクセス」で詳しく説明しています。 + +表 4 に、利用可能なタスクで使用できるアクション、MIME タイプ、データ値をまとめます。{@link android.content.Intent#putExtra(String, String) putExtra()} で使用できるエクストラ値については、{@link android.provider.ContactsContract.Intents.Insert} のリファレンス ドキュメントに一覧があります。 + + + + +</p> +<p class="table-caption" id="table4"> + <strong>表 4.</strong> 連絡先プロバイダのインテント +</p> +<table style="width:75%"> + <tr> + <th scope="col" style="width:10%">タスク</th> + <th scope="col" style="width:5%">アクション</th> + <th scope="col" style="width:10%">データ</th> + <th scope="col" style="width:10%">MIME タイプ</th> + <th scope="col" style="width:25%">注</th> + </tr> + <tr> + <td><strong>連絡先をリストから選ぶ</strong></td> + <td>{@link android.content.Intent#ACTION_PICK}</td> + <td> + 次のどれかです。 + <ul> + <li> +{@link android.provider.ContactsContract.Contacts#CONTENT_URI Contacts.CONTENT_URI}。連絡先のリストを表示します。 + + </li> + <li> +{@link android.provider.ContactsContract.CommonDataKinds.Phone#CONTENT_URI Phone.CONTENT_URI}。未加工連絡先の電話番号のリストを表示します。 + + </li> + <li> +{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal#CONTENT_URI StructuredPostal.CONTENT_URI}。未加工連絡先の住所のリストを表示します。 + + + </li> + <li> +{@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_URI Email.CONTENT_URI}。未加工連絡先のメールアドレスのリストを表示します。 + + </li> + </ul> + </td> + <td> + 使用せず + </td> + <td> + 指定したコンテンツ URI のタイプに応じて、未加工連絡先のリストか、未加工連絡先から取得されたデータのリストを表示します。 + + <p> + {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()} を呼び出してください。それにより、選択した行のコンテンツ URI が返されます。 + +URI の形式は、テーブルのコンテンツ URI の末尾にその行の <code>LOOKUP_ID</code> が追加されたものです。 + + 端末の連絡先アプリは、このアクティビティの実行中を通して、読み取りと書き込みのパーミッションをこのコンテンツ URI にデリゲートします。 +詳しくは、「<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>」をご覧ください。 + + + </p> + </td> + </tr> + <tr> + <td><strong>新しい未加工連絡先を挿入する</strong></td> + <td>{@link android.provider.ContactsContract.Intents.Insert#ACTION Insert.ACTION}</td> + <td>該当せず</td> + <td> + {@link android.provider.ContactsContract.RawContacts#CONTENT_TYPE RawContacts.CONTENT_TYPE}。未加工連絡先のセットに対する MIME タイプです。 + + </td> + <td> + 端末の連絡先アプリケーションの [<strong>連絡先の追加</strong>] 画面を表示します。インテントに追加したエクストラ値が表示されます。 +{@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()} を使用して送信すると、新たに追加された未加工連絡先の URI が、アクティビティの {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()} コールバック メソッドの {@link android.content.Intent} 引数の「data」フィールドに格納されて戻ってきます。 + + + + +この値を取得するには、{@link android.content.Intent#getData()} を呼び出します。 + </td> + </tr> + <tr> + <td><strong>連絡先を編集する</strong></td> + <td>{@link android.content.Intent#ACTION_EDIT}</td> + <td> + 連絡先の {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}。 +エディタ アクティビティを使用すると、ユーザーがその連絡先に関連付けられている任意のデータを編集できます。 + + </td> + <td> + {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE Contacts.CONTENT_ITEM_TYPE}。1 つの連絡先です。 +</td> + <td> + 連絡先アプリケーションに連絡先の編集画面を表示します。インテントに追加したエクストラ値が表示されます。 +ユーザーが [<strong>完了</strong>] をタップして編集内容を保存すると、アクティビティがフォアグラウンドに戻ります。 + + </td> + </tr> + <tr> + <td><strong>ピッカー(やはりデータを追加できる)を表示する。</strong></td> + <td>{@link android.content.Intent#ACTION_INSERT_OR_EDIT}</td> + <td> + 該当せず + </td> + <td> + {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE} + </td> + <td> + このインテントは、連絡先アプリのピッカー画面を常に表示します。ユーザーは、編集する連絡先を選ぶか、新しい連絡先を追加できます。 +ユーザーの選択に応じて編集画面か追加画面が開き、インテントに含めて渡したエクストラ データが表示されます。 + +メールアドレスや電話番号などの連絡先データを独自アプリに表示する場合は、このインテントを使用すると、ユーザーが既存の連絡先にデータを追加できます。 + + + <p class="note"> + <strong>注:</strong> このインテントのエクストラで名前の値を送信する必要はありません。ユーザーは必ず既存の名前を選ぶか新しい名前を追加するからです。 +そのうえ、アプリが名前を送信し、ユーザーが編集することを選んだ場合、連絡先アプリは送信した名前を表示し、以前の値を上書きします。 + +ユーザーがこのことに気付かず、編集内容を保存すると、以前の値が失われます。 + + </p> + </td> + </tr> +</table> +<p> + 端末の連絡先アプリは、インテントを使用して未加工連絡先や任意のデータを削除することを許可しません。 +そのため、未加工連絡先を削除するには {@link android.content.ContentResolver#delete(Uri, String, String[]) ContentResolver.delete()} または {@link android.content.ContentProviderOperation#newDelete(Uri) ContentProviderOperation.newDelete()} を使用してください。 + + + +</p> +<p> + 次のスニペットは、新しい未加工連絡先とデータをバッチで挿入するインテントをコンストラクトして送信する方法を示しています。 + +</p> +<pre> +// Gets values from the UI +String name = mContactNameEditText.getText().toString(); +String phone = mContactPhoneEditText.getText().toString(); +String email = mContactEmailEditText.getText().toString(); + +String company = mCompanyName.getText().toString(); +String jobtitle = mJobTitle.getText().toString(); + +// Creates a new intent for sending to the device's contacts application +Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION); + +// Sets the MIME type to the one expected by the insertion activity +insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE); + +// Sets the new contact name +insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name); + +// Sets the new company and job title +insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company); +insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle); + +/* + * Demonstrates adding data rows as an array list associated with the DATA key + */ + +// Defines an array list to contain the ContentValues objects for each row +ArrayList<ContentValues> contactData = new ArrayList<ContentValues>(); + + +/* + * Defines the raw contact row + */ + +// Sets up the row as a ContentValues object +ContentValues rawContactRow = new ContentValues(); + +// Adds the account type and name to the row +rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType()); +rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName()); + +// Adds the row to the array +contactData.add(rawContactRow); + +/* + * Sets up the phone number data row + */ + +// Sets up the row as a ContentValues object +ContentValues phoneRow = new ContentValues(); + +// Specifies the MIME type for this data row (all data rows must be marked by their type) +phoneRow.put( + ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE +); + +// Adds the phone number and its type to the row +phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone); + +// Adds the row to the array +contactData.add(phoneRow); + +/* + * Sets up the email data row + */ + +// Sets up the row as a ContentValues object +ContentValues emailRow = new ContentValues(); + +// Specifies the MIME type for this data row (all data rows must be marked by their type) +emailRow.put( + ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE +); + +// Adds the email address and its type to the row +emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email); + +// Adds the row to the array +contactData.add(emailRow); + +/* + * Adds the array to the intent's extras. It must be a parcelable object in order to + * travel between processes. The device's contacts app expects its key to be + * Intents.Insert.DATA + */ +insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData); + +// Send out the intent to start the device's contacts app in its add contact activity. +startActivity(insertIntent); +</pre> +<h3 id="DataIntegrity">データの整合性</h3> +<p> + 連絡先リポジトリにはユーザーによる修正や更新が予想される重要で秘密性の高いデータが格納されるため、連絡先プロバイダにはデータの整合性に関して明確に定義されたルールがあります。 +連絡先データを変更する際にこれらのルールを守ることは、開発側の責任です。 +ここでは、重要なルールを示します。 + +</p> +<dl> + <dt> + {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 行を、追加する {@link android.provider.ContactsContract.RawContacts} 行ごとに必ず追加してください。 + + </dt> + <dd> + {@link android.provider.ContactsContract.Data} テーブルに {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 行のない {@link android.provider.ContactsContract.RawContacts} 行は、集約中に問題を引き起こすことがあります。 + + + + </dd> + <dt> + 新しい {@link android.provider.ContactsContract.Data} 行を、その親 {@link android.provider.ContactsContract.RawContacts} 行に必ずリンクしてください。 + + </dt> + <dd> + {@link android.provider.ContactsContract.RawContacts} にリンクされていない {@link android.provider.ContactsContract.Data} 行は端末の連絡先アプリケーションで可視にならず、同期アダプタで問題になることがあります。 + + + </dd> + <dt> + 変更するのは、所有する未加工連絡先のデータに限ってください。 + </dt> + <dd> + 通常、連絡先プロバイダは複数の異なるアカウント タイプやオンライン サービスから取得したデータを管理しています。 +そのため、アプリケーションが所有しているデータのみ変更または削除されるようにし、アプリケーションが管理しているアカウント タイプとアカウント名のデータのみ挿入するようにすることが必要です。 + + + </dd> + <dt> + 権限、コンテンツ URI、URI パス、列名、MIME タイプ、{@link android.provider.ContactsContract.CommonDataKinds.CommonColumns#TYPE} 値については、{@link android.provider.ContactsContract} とそのサブクラスに定義されている定数を必ず使用してください。 + + + </dt> + <dd> + そのような定数を使用することがエラーの予防に役立ちます。また、使われなくなった定数があれば、コンパイラーから警告として通知されます。 + + </dd> +</dl> +<h3 id="CustomData">カスタムデータ行</h3> +<p> + 独自のカスタム MIME タイプを作成して使用すると、{@link android.provider.ContactsContract.Data} テーブルで独自データ行を挿入、編集、削除、取得できます。 +独自行で使用できるのは {@link android.provider.ContactsContract.DataColumns} に定義された列だけですが、独自タイプに固有の列名をデフォルトの列名にマッピングできます。 + + +端末の連絡先アプリケーションで、独自行のデータは表示されますが、編集または削除はできず、ユーザーはデータの追加ができません。 + +ユーザーがカスタムデータ行を変更できるようにするには、独自のアプリケーションでエディタ アクティビティを提供する必要があります。 + +</p> +<p> + カスタムデータを表示するには、1 つの <code><ContactsAccountType></code> 要素と 1 つまたは複数の <code><ContactsDataKind></code> 子要素を含む <code>contacts.xml</code> ファイルを提供します。 + +詳しくは、<a href="#SocialStreamDataKind"><code><ContactsDataKind> element</code></a>に関するセクションで説明しています。 + +</p> +<p> + カスタム MIME タイプについて詳しくは、「<a href="{@docRoot}guide/topics/providers/content-provider-creating.html">コンテンツ プロバイダの作成</a>」をご覧ください。 + + +</p> +<h2 id="SyncAdapters">連絡先プロバイダの同期アダプタ</h2> +<p> + 連絡先プロバイダは、特に端末とオンライン サービスとの間における連絡先データの<strong>同期</strong>を処理するために設計されています。 +これを使用することで、ユーザーは既存のデータを新しい端末にダウンロードしたり、既存のデータを新しいアカウントにアップロードしたりできています。 + + また、同期によって、追加や変更のソースに関係なく、ユーザーは最新データを入手できます。 +同期の利点としては他にも、端末がネットワークに接続されていなくても連絡先データを使用できるようになることが挙げられます。 + +</p> +<p> + 同期はさまざまな手法で実装できますが、Android システムでは次のタスクを自動化するプラグイン同期フレームワークを提供しています。 + + <ul> + + <li> + ネットワークの可用性のチェック。 + </li> + <li> + ユーザーのプリファレンスに基づく同期のスケジュールと実施。 + </li> + <li> + 停止された同期の再開。 + </li> + </ul> +<p> + このフレームワークを使用するには、同期アダプタ プラグインを提供する必要があります。各同期アダプタはサービスと連絡先プロバイダに対して一意ですが、同じサービスに対して複数のアカウント名を処理できます。 +また、このフレームワークでは同じサービスとプロバイダに対して複数の同期アダプタが可能です。 + +</p> +<h3 id="SyncClassesFiles">同期アダプタのクラスとファイル</h3> +<p> + 同期アダプタは、{@link android.content.AbstractThreadedSyncAdapter} のサブクラスとして実装し、Android アプリケーションの一部としてインストールします。 + +システムは同期アダプタに関する知識を、アプリケーション マニフェストの要素からと、マニフェストが指す専用の XML ファイルから取得します。 +この XML ファイルは、オンライン サービスのアカウント タイプと連絡先プロバイダに絡む権限を定義しており、この組み合わせでアダプタを一意に識別します。 + +同期アダプタは、ユーザーが同期アダプタのアカウント タイプに対してアカウントを追加し、同期アダプタの同期対象である連絡先プロバイダで同期を有効にすることで、アクティブになります。 + +この時点で、システムはアダプタの管理を開始し、連絡先プロバイダとサーバーとの同期が必要になるとそれを呼び出します。 + +</p> +<p class="note"> + <strong>注:</strong> アカウント タイプを同期アダプタの識別の一環として使用することにより、システムは同じ組織から異なるサービスにアクセスする同期アダプタを検出してグループ化できます。 + +たとえば、Google オンライン サービス用の同期アダプタでは、すべて同じアカウント タイプ <code>com.google</code> です。 +ユーザーが Google アカウントを端末に追加すると、Google サービス用にインストールされているすべての同期アダプタがひとまとめにリストされ、リストされている各同期アダプタは端末上の異なる連絡先プロバイダと同期します。 + + +</p> +<p> + データにアクセスするたび、ほとんどのサービスがユーザーに ID の確認を要求するため、Android システムでは、同期アダプタ フレームワークと類似した認証フレームワークを提供しており、往々にして同期アダプタ フレームワークと組み合わせて使用します。 + +この認証フレームワークでは、{@link android.accounts.AbstractAccountAuthenticator} のサブクラスであるプラグイン認証システムを使用します。 + +認証システムは、次の手順でユーザーの身元を検証します。 + + <ol> + <li> + ユーザー名とパスワードか、それに準ずる情報(ユーザーの<strong>資格情報</strong>)を収集します。 + + </li> + <li> + 収集した資格情報をサービスに送信します。 + </li> + <li> + サービスの返答を検証します。 + </li> + </ol> +<p> + サービスが資格情報を受け入れた場合、認証システムはその資格情報を後での使用のために格納します。 +{@link android.accounts.AccountManager} はプラグイン認証フレームワークのおかげで、OAuth2 認証トークンなど、認証システムがサポートして公開することを選択している任意の認証トークンへのアクセスを提供できます。 + + +</p> +<p> + 認証は必須ではありませんが、たいていの連絡先サービスが使用しています。 + ただし、認証に Android 認証フレームワークを使用する必要はありません。 +</p> +<h3 id="SyncAdapterImplementing">同期アダプタの実装</h3> +<p> + 連絡先プロバイダ用の同期アダプタを実装するには、まず以下を備えた Android アプリケーションを作成します。 + +</p> + <dl> + <dt> + システムからの同期アダプタとのバインド要求に対処する {@link android.app.Service} コンポーネント。 + + </dt> + <dd> + システムは、同期しようとするとき、サービスの {@link android.app.Service#onBind(Intent) onBind()} メソッドを呼び出して、同期アダプタの {@link android.os.IBinder} を取得します。 + +これにより、システムはアダプタのメソッドに対するプロセス間呼び出しを実行できます。 + + <p> + <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプルアプリで、このサービスのクラス名は <code>com.example.android.samplesync.syncadapter.SyncService</code> です。 + + + </p> + </dd> + <dt> + {@link android.content.AbstractThreadedSyncAdapter} の具象サブクラスとして実装された、実際の同期アダプタ。 + + </dt> + <dd> + このクラスが、サーバーからのデータのダウンロード、端末からのデータのアップロード、競合の解消といった作業を実施します。 +アダフタの主な作業は、メソッド {@link android.content.AbstractThreadedSyncAdapter#onPerformSync( Account, Bundle, String, ContentProviderClient, SyncResult) onPerformSync()} で実行されます。 + + +このクラスは、シングルトンとしてインスタンス化する必要があります。 + <p> + <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプルアプリで、同期アダプタはクラス <code>com.example.android.samplesync.syncadapter.SyncAdapter</code> に定義されています。 + + + </p> + </dd> + <dt> + {@link android.app.Application} のサブクラス。 + </dt> + <dd> + このクラスは同期アダプタ シングルトンのファクトリとして機能します。同期アダプタのインスタンス化には {@link android.app.Application#onCreate()} メソッドを使用し、同期アダプタ シングルトンを同期アダプタのサービスの {@link android.app.Service#onBind(Intent) onBind()} メソッドに返すための静的な「getter」メソッドを提供します。 + + + + + </dd> + <dt> + <strong>省略可能:</strong> システムからのユーザー認証要求に対処する {@link android.app.Service} コンポーネント。 + + </dt> + <dd> + {@link android.accounts.AccountManager} は、このサービスを開始することによって認証プロセスを始めます。 +サービスの {@link android.app.Service#onCreate()} メソッドは、認証システム オブジェクトをインスタンス化します。 +システムは、アプリケーションの同期アダプタのためにユーザー アカウントを認証しようとするとき、サービスの {@link android.app.Service#onBind(Intent) onBind()} メソッドを呼び出して、認証システムの {@link android.os.IBinder} を取得します。 + + +これにより、システムは認証システムのメソッドに対するプロセス間呼び出しを実行できます。 + + <p> + <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプルアプリで、このサービスのクラス名は <code>com.example.android.samplesync.authenticator.AuthenticationService</code> です。 + + + </p> + </dd> + <dt> + <strong>省略可能:</strong> 認証の要求を処理する {@link android.accounts.AbstractAccountAuthenticator} の具象サブクラス。 + + + </dt> + <dd> + このクラスは、ユーザーの資格情報をサーバーに対して認証するために {@link android.accounts.AccountManager} が呼び出すメソッドを提供します。認証プロセスの詳細は、使用されているサーバー技術に応じて多岐にわたります。 + +認証について詳しくは、使用するサーバー ソフトウェアのドキュメントをご覧ください。 + + <p> + <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプルアプリで、認証はクラス <code>com.example.android.samplesync.authenticator.Authenticator</code> に定義されています。 + + + </p> + </dd> + <dt> + システムに対する同期アダプタと認証システムを定義する XML ファイル。 + </dt> + <dd> + 前述の同期アダプタと認証システム サービスのコンポーネントは、アプリケーション マニフェストの <code><<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>></code> 要素に定義されます。 + + +これらの要素には、特定のデータをシステムに提供する次のような <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></code> 子要素が含まれます。 + + + + + <ul> + <li> + 同期アダプタ サービス用の <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></code> 要素は、XML ファイル <code>res/xml/syncadapter.xml</code> を指します。 + + +このファイルが、連絡先プロバイダと同期されるウェブサービスの URI と、そのウェブサービスで使用するアカウント タイプを指定します。 + + + </li> + <li> + <strong>省略可能:</strong> 認証システム用の <code><<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>></code> 要素は、XML ファイル <code>res/xml/authenticator.xml</code> を指します。 + + +このファイルが、この認証システムがサポートするアカウント タイプと、認証プロセスの最中に表示される UI リソースを指定します。 + +この要素に指定されるアカウント タイプは、同期アダプタ用に指定されるアカウント タイプと同じであることが必要です。 + + + </li> + </ul> + </dd> + </dl> +<h2 id="SocialStream">ソーシャル ストリーム データ</h2> +<p> + {@code android.provider.ContactsContract.StreamItems} テーブルと {@code android.provider.ContactsContract.StreamItemPhotos} テーブルは、ソーシャル ネットワークからの受信データを管理します。 + +独自ネットワークからのストリーム データをこれらのテーブルに追加する同期アダプタを作成したり、ストリーム データをこれらのテーブルから読み込んで独自アプリケーションに表示したり、この両方を行ったりできます。 + +このような機能があると、ソーシャル ネットワーキングのサービスやアプリケーションを Android のソーシャル ネットワーキング機能に統合できます。 + +</p> +<h3 id="StreamText">ソーシャル ストリーム テキスト</h3> +<p> + ストリーム アイテムは、必ず未加工連絡先に関連付けられます。{@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID} は、未加工連絡先の <code>_ID</code> 値にリンクされます。 + +未加工連絡先のアカウント タイプとアカウント名は、ストリーム アイテム行にも格納されます。 + +</p> +<p> + ストリームからのデータを次の列に格納します。 +</p> +<dl> + <dt> + {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE} + </dt> + <dd> + <strong>必須</strong>。このストリーム アイテムに関連付けられている未加工連絡先の、ユーザーのアカウント タイプ。 +ストリーム アイテムを挿入する際には、この値を忘れずに設定してください。 + </dd> + <dt> + {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME} + </dt> + <dd> + <strong>必須</strong>。このストリーム アイテムに関連付けられている未加工連絡先の、ユーザーのアカウント名。 +ストリーム アイテムを挿入する際には、この値を忘れずに設定してください。 + </dd> + <dt> + 識別用列 + </dt> + <dd> + <strong>必須</strong>。ストリーム アイテムを挿入する際には、次の識別用列を挿入する必要があります。 + + <ul> + <li> + {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}:このストリーム アイテムが関連付けられている連絡先の {@code android.provider.BaseColumns#_ID} 値。 + + + </li> + <li> + {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: このストリーム アイテムが関連付けられている連絡先の {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} 値。 + + + </li> + <li> + {@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}:このストリーム アイテムが関連付けられている未加工連絡先の {@code android.provider.BaseColumns#_ID} 値。 + + + </li> + </ul> + </dd> + <dt> + {@code android.provider.ContactsContract.StreamItemsColumns#COMMENTS} + </dt> + <dd> + 省略可能。ストリーム アイテムの冒頭に表示できる概要情報を格納します。 + </dd> + <dt> + {@code android.provider.ContactsContract.StreamItemsColumns#TEXT} + </dt> + <dd> + ストリーム アイテムのテキスト。アイテムのソースによって投稿されたコンテンツか、そのストリーム アイテムを生成した何らかのアクションに関する説明です。 +この列には、{@link android.text.Html#fromHtml(String) fromHtml()} でレンダリングできる任意の書式や埋め込みリソース画像を含めることができます。 + +プロバイダは、長いコンテンツを切り捨てたり省いたりすることがありますが、タグは壊さないようにします。 + + </dd> + <dt> + {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP} + </dt> + <dd> + ストリーム アイテムが挿入またはアップデートされた時刻を含むテキスト。エポックからのミリ秒<em></em>の形式です。 +ストリーム アイテムを挿入またはアップデートするアプリケーションは、この列の管理を担当します。この列は、連絡先プロバイダによって自動的に管理されるわけではありません。 + + + </dd> +</dl> +<p> + ストリーム アイテムの識別情報を表示するには、{@code android.provider.ContactsContract.StreamItemsColumns#RES_ICON}、{@code android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}、{@code android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} を使用してアプリケーション内のリソースにリンクします。 + + + + +</p> +<p> + {@code android.provider.ContactsContract.StreamItems} テーブルには、同期アダプタ専用に列 {@code android.provider.ContactsContract.StreamItemsColumns#SYNC1} ~ {@code android.provider.ContactsContract.StreamItemsColumns#SYNC4} も格納されます。 + + + +</p> +<h3 id="StreamPhotos">ソーシャル ストリーム フォト</h3> +<p> + {@code android.provider.ContactsContract.StreamItemPhotos} テーブルには、ストリーム アイテムに関連付けられた写真が格納されます。 +このテーブルの {@code android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} 列は、{@code android.provider.ContactsContract.StreamItems} テーブルの {@code android.provider.BaseColumns#_ID} 列の値にリンクされます。 + + +写真の参照は、テーブルの次の列に格納されます。 + +</p> +<dl> + <dt> + {@code android.provider.ContactsContract.StreamItemPhotos#PHOTO} 列(BLOB)。 + </dt> + <dd> + 写真のバイナリ表現。格納や表示のためにプロバイダによってサイズが変更されます。 + この列は、写真を格納するために使用されていた連絡先プロバイダの従来のバージョンとの下方互換性のために用意されています。 +ただし、現在のバージョンでは、写真の格納にこの列を使用しないでください。 +代わりに、{@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} または {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI}(どちらについても次の項目で説明します)を使用して、写真をファイルに保存します。 + + +現状では、この列には写真のサムネイルが格納されており、読み出し可能です。 + + </dd> + <dt> + {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} + </dt> + <dd> + 未加工連絡先の写真の数値 ID。この値を定数 {@link android.provider.ContactsContract.DisplayPhoto#CONTENT_URI DisplayPhoto.CONTENT_URI} の末尾に追加して、1 つの写真ファイルを指すコンテンツ URI を取得し、{@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String) openAssetFileDescriptor()} を呼び出して、その写真ファイルのハンドルを取得します。 + + + + + </dd> + <dt> + {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI} + </dt> + <dd> + この行によって表されている写真の写真ファイルを直接指すコンテンツ URI。 + この URI を使用して {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String) openAssetFileDescriptor()} を呼び出して、写真ファイルのハンドルを取得します。 + + </dd> +</dl> +<h3 id="SocialStreamTables">ソーシャル ストリーム テーブルの使用</h3> +<p> + これらのテーブルは、連絡先プロバイダの他の主なテーブルと同じように機能しますが、次のような例外があります。 +</p> + <ul> + <li> + これらのテーブルには、追加のアクセス パーミッションが必要です。これらからの読み出しには、アプリケーションにパーミッション {@code android.Manifest.permission#READ_SOCIAL_STREAM} が必要です。 +これらの変更には、アプリケーションにパーミッション {@code android.Manifest.permission#WRITE_SOCIAL_STREAM} が必要です。 + + + </li> + <li> + {@code android.provider.ContactsContract.StreamItems} テーブルについては、各未加工連絡先に格納できる行数に上限があります。 +上限に達すると、連絡先プロバイダは最も古い {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP} を持つ行を自動的に削除して、新しいストリーム アイテムのための領域を作ります。 + + +この上限を取得するには、コンテンツ URI {@code android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI} にクエリを発行します。 + +コンテンツ URI を除くすべての引数は、<code>null</code> のままでかまいません。 +このクエリは、列 {@code android.provider.ContactsContract.StreamItems#MAX_ITEMS} だけの 1 行を含む Cursor を返します。 + + + </li> + </ul> + +<p> + クラス {@code android.provider.ContactsContract.StreamItems.StreamItemPhotos} は、1 つのストリーム アイテムの写真行を含む {@code android.provider.ContactsContract.StreamItemPhotos} のサブテーブルを定義します。 + + +</p> +<h3 id="SocialStreamInteraction">ソーシャル ストリーム操作</h3> +<p> + 連絡先プロバイダによって端末の連絡先アプリケーションと連携して管理されるソーシャル ストリーム データは、ソーシャル ネットワーキング システムと既存の連絡先を接続するためのとても便利な手段を用意しています。 + +利用できる機能は次のとおりです。 +</p> + <ul> + <li> + ソーシャル ネットワーキング サービスを連絡先プロバイダに同期アダプタを使用して同期することで、ユーザーの連絡先による最近のアクティビティを取得し、それを {@code android.provider.ContactsContract.StreamItems} テーブルや {@code android.provider.ContactsContract.StreamItemPhotos} テーブルに格納して後で使えるようにできます。 + + + + </li> + <li> + ユーザーが連絡先を選択して表示したときには、定期的な同期とは別に同期アダプタを起動して追加データを取得できます。 +この機能により、同期アダプタは連絡先の高解像度の写真や直近のストリーム アイテムを取得できます。 + + </li> + <li> + 端末の連絡先アプリケーションと連絡先プロバイダに関する通知を登録すると、連絡先が表示された場合にインテントを受信<em></em>し、その時点で連絡先のステータスをサービスからアップデートできます。 + +このアプローチは、同期アダプタを使用してフル同期を実施するより、処理が速く、帯域幅が節約されます。 + + </li> + <li> + ユーザーが端末の連絡先アプリケーションで連絡先を見ている間に、その連絡先をソーシャル ネットワーキング サービスに追加できます。 +この機能は「連絡先の招待」機能を使用して実現できます。連絡先の招待は、既存の連絡先をネットワークに追加するアクティビティと、端末の連絡先アプリケーションと連絡先プロバイダにアプリケーションの詳細を提供する XML ファイルとを組み合わせて実現できます。 + + + + </li> + </ul> +<p> + 連絡先プロバイダを使用したストリーム アイテムの定期的な同期は、他の同期と同じです。 +同期について詳しくは、<a href="#SyncAdapters">連絡先プロバイダの同期アダプタ</a>をご覧ください。 +通知の登録と連絡先の招待については、次の 2 つのセクションで説明します。 + +</p> +<h4>ソーシャル ネットワーキング表示を処理するための登録</h4> +<p> + 同期アダプタを登録し、同期アダプタによって管理されている連絡先をユーザーが表示したときに通知されるようにする方法は、次のとおりです。 + +</p> +<ol> + <li> + <code>contacts.xml</code> という名前のファイルをプロジェクトの <code>res/xml/</code> ディレクトリに作成します。 +このファイルが既に存在する場合は、この手順を省略できます。 + </li> + <li> + このファイルに要素 <code><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></code> を追加します。 + + この要素が既に存在する場合は、この手順を省略できます。 + </li> + <li> + ユーザーが端末の連絡先アプリケーションで連絡先の詳細ページを開いたときに通知されるサービスを登録するには、属性 <code>viewContactNotifyService="<em>serviceclass</em>"</code> を要素に追加します。<code><em>serviceclass</em></code> は、端末の連絡先アプリケーションからインテントを受け取ることになるサービスの完全修飾クラス名です。 + + + +通知側サービスのために、{@link android.app.IntentService} を機能拡張したクラスを使用して、そのサービスがインテントを受け取れるようにします。 + +受け取るインテントに含まれるデータには、ユーザーがクリックした未加工連絡先のコンテンツ URI が格納されます。 +通知側サービスから、同期アダプタをバインドして呼び出し、未加工連絡先のデータをアップデートできます。 + + </li> +</ol> +<p> + ユーザーがストリーム アイテムかストリーム フォトかその両方をクリックしたときに呼び出されるアクティビティを登録する方法は次のとおりです。 +</p> +<ol> + <li> + <code>contacts.xml</code> という名前のファイルをプロジェクトの <code>res/xml/</code> ディレクトリに作成します。 +このファイルが既に存在する場合は、この手順を省略できます。 + </li> + <li> + このファイルに要素 <code><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></code> を追加します。 + + この要素が既に存在する場合は、この手順を省略できます。 + </li> + <li> + アクティビティのどれかを登録して、ユーザーが端末の連絡先アプリケーションでストリーム アイテムをタップしたことに対処するには、属性 <code>viewStreamItemActivity="<em>activityclass</em>"</code> を要素に追加します。<code><em>activityclass</em></code> は、端末の連絡先アプリケーションからインテントを受け取ることになるアクティビティの完全修飾クラス名です。 + + + + + </li> + <li> + アクティビティのどれかを登録して、ユーザーが端末の連絡先アプリケーションでストリーム フォトをタップしたことに対処するには、属性 <code>viewStreamItemPhotoActivity="<em>activityclass</em>"</code> を要素に追加します。<code><em>activityclass</em></code> は、端末の連絡先アプリケーションからインテントを受け取ることになるアクティビティの完全修飾クラス名です。 + + + + + </li> +</ol> +<p> + <code><ContactsAccountType></code> 要素については、<a href="#SocialStreamAcctType"><ContactsAccountType> 要素</a>で詳しく説明しています。 + +</p> +<p> + 受け取るインテントには、ユーザーがクリックしたアイテムまたは写真のコンテンツ URI が格納されます。 + テキスト アイテムと写真とで異なるアクティビティを使用するには、同じファイルで両方の属性を使用します。 +</p> +<h4>ソーシャル ネットワーキング サービスの操作</h4> +<p> + ユーザーは、連絡先をソーシャル ネットワーキング サービスに招待するのに、端末の連絡先アプリケーションを離れる必要はありません。 +その代わりとして、連絡先をアクティビティのどれかに招待するインテントを端末の連絡先アプリケーションに送信させることができます。 +これをセットアップする方法は次のとおりです。 +</p> +<ol> + <li> + <code>contacts.xml</code> という名前のファイルをプロジェクトの <code>res/xml/</code> ディレクトリに作成します。 +このファイルが既に存在する場合は、この手順を省略できます。 + </li> + <li> + このファイルに要素 <code><ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"></code> を追加します。 + + この要素が既に存在する場合は、この手順を省略できます。 + </li> + <li> + 次の属性を追加します。 + <ul> + <li><code>inviteContactActivity="<em>activityclass</em>"</code></li> + <li> + <code>inviteContactActionLabel="@string/<em>invite_action_label</em>"</code> + </li> + </ul> + <code><em>activityclass</em></code> 値は、インテントを受信するアクティビティの完全修飾クラス名です。 +<code><em>invite_action_label</em></code> 値は、端末の連絡先アプリケーションの [<strong>Add Connection</strong>] メニューに表示される文字列です。 + + + </li> +</ol> +<p class="note"> + <strong>注:</strong> <code>ContactsSource</code> は廃止されたタグ名で、<code>ContactsAccountType</code> に置き換わっています。 + +</p> +<h3 id="ContactsFile">contacts.xml リファレンス</h3> +<p> + ファイル <code>contacts.xml</code> には、同期アダプタやアプリケーションと連絡先アプリケーションや連絡先プロバイダとのやり取りを管理する XML 要素が含まれています。 +これらの要素について、以降のセクションで説明します。 + +</p> +<h4 id="SocialStreamAcctType"><ContactsAccountType> 要素</h4> +<p> + <code><ContactsAccountType></code> 要素は、アプリケーションと連絡先アプリケーションとのやり取りを管理します。 +構文は次のとおりです。 +</p> +<pre> +<ContactsAccountType + xmlns:android="http://schemas.android.com/apk/res/android" + inviteContactActivity="<em>activity_name</em>" + inviteContactActionLabel="<em>invite_command_text</em>" + viewContactNotifyService="<em>view_notify_service</em>" + viewGroupActivity="<em>group_view_activity</em>" + viewGroupActionLabel="<em>group_action_text</em>" + viewStreamItemActivity="<em>viewstream_activity_name</em>" + viewStreamItemPhotoActivity="<em>viewphotostream_activity_name</em>"> +</pre> +<p> + <strong>含まれているファイル:</strong> +</p> +<p> + <code>res/xml/contacts.xml</code> +</p> +<p> + <strong>含めることのできる要素:</strong> +</p> +<p> + <strong><code><ContactsDataKind></code></strong> +</p> +<p> + <strong>説明:</strong> +</p> +<p> + ユーザーが連絡先の 1 人をソーシャル ネットワーキングに招待できるようにしたり、ソーシャル ネットワーキング ストリームのどれかがアップデートされたらユーザーに通知したりするための、Android コンポーネントや UI ラベルを宣言します。 + + +</p> +<p> + 属性プレフィックス <code>android:</code> は、<code><ContactsAccountType></code> の属性に必須ではないことに注目してください。 + +</p> +<p> + <strong>属性:</strong> +</p> +<dl> + <dt>{@code inviteContactActivity}</dt> + <dd> + ユーザーが端末の連絡先アプリケーションで [<strong>Add Connection</strong>] を選択したときに起動する、アプリケーション内のアクティビティの完全修飾クラス名。 + + + </dd> + <dt>{@code inviteContactActionLabel}</dt> + <dd> + [<strong>Add Connection</strong>] メニューで、{@code inviteContactActivity} に指定されたアクティビティ用に表示されるテキスト。 + + たとえば、文字列「Follow in my network」を指定できます。このラベルには文字列リソース ID を使用できます。 + + </dd> + <dt>{@code viewContactNotifyService}</dt> + <dd> + ユーザーが連絡先を表示したときに通知を受け取ることになる、独自アプリケーション内のサービスの完全修飾クラス名。 +この通知は端末の連絡先アプリケーションによって送信されます。これを使用することで、アプリケーションはデータ処理の多い操作を必要になるまで延期できます。 + +たとえば、アプリケーションはこの通知への対応として、連絡先の高解像度写真と直近のソーシャル ストリーム アイテムを読み込んで表示できます。 + +この機能について詳しくは、<a href="#SocialStreamInteraction">ソーシャル ストリーム操作</a>で説明しています。 +<code>NotifierService.java</code> ファイルに指定された通知サービスの例は、<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a> サンプル アプリケーションにあります。 + + + + </dd> + <dt>{@code viewGroupActivity}</dt> + <dd> + グループ情報を表示できる、独自アプリケーション内のアクティビティの完全修飾クラス名。 +ユーザーが端末の連絡先アプリケーションでグループラベルをタップすると、このアクティビティの UI が表示されます。 + + </dd> + <dt>{@code viewGroupActionLabel}</dt> + <dd> + ユーザーがアプリケーションでグループを表示できるようにする UI コントロールに対し、連絡先アプリケーションが表示するラベル。 + + <p> + たとえば、端末に Google+ アプリケーションをインストールし、Google+ を連絡先アプリケーションと同期すると、Google+ のサークルが連絡先アプリケーションの [<strong>グループ</strong>] タブにグループとして表示されます。 + +Google+ サークルのどれかをクリックすると、そのサークルに所属する人が「グループ」として表示されます。 +表示の最上部に、Google+ アイコンが表示されます。それをクリックすると、制御が Google+ アプリに移ります。連絡先アプリケーションはこれを {@code viewGroupActivity} を使用して行い、Google+ アイコンを {@code viewGroupActionLabel} の値として使用します。 + + + + + </p> + <p> + この属性には、文字列リソース ID を使用できます。 + </p> + </dd> + <dt>{@code viewStreamItemActivity}</dt> + <dd> + ユーザーが未加工連絡先のストリーム アイテムをタップしたときに端末の連絡先アプリケーションが起動する、独自アプリケーション内のアクティビティの完全修飾クラス名。 + + </dd> + <dt>{@code viewStreamItemPhotoActivity}</dt> + <dd> + ユーザーが未加工連絡先のストリーム アイテムで写真をタップしたときに端末の連絡先アプリケーションが起動する、独自アプリケーション内のアクティビティの完全修飾クラス名。 + + + </dd> +</dl> +<h4 id="SocialStreamDataKind"><ContactsDataKind> 要素</h4> +<p> + <code><ContactsDataKind></code> 要素は、連絡先アプリケーションにおける独自アプリケーションのカスタムデータ行の表示を管理します。構文は次のとおりです。 + +</p> +<pre> +<ContactsDataKind + android:mimeType="<em>MIMEtype</em>" + android:icon="<em>icon_resources</em>" + android:summaryColumn="<em>column_name</em>" + android:detailColumn="<em>column_name</em>"> +</pre> +<p> + <strong>含まれているファイル:</strong> +</p> +<code><ContactsAccountType></code> +<p> + <strong>説明:</strong> +</p> +<p> + この要素は、カスタムデータ行のコンテンツを未加工連絡先の詳細の一部として連絡先アプリケーションに表示させるために使用します。 +<code><ContactsAccountType></code> の各 <code><ContactsDataKind></code> 子要素は、同期アダプタが {@link android.provider.ContactsContract.Data} テーブルに追加するカスタムデータ行のタイプを表します。 + +使用するカスタム MIME タイプごとに <code><ContactsDataKind></code> 要素を 1 つ追加します。 +データを表示しないカスタムデータ行がある場合は、この要素を追加する必要はありません。 + +</p> +<p> + <strong>属性:</strong> +</p> +<dl> + <dt>{@code android:mimeType}</dt> + <dd> + {@link android.provider.ContactsContract.Data} テーブルに含まれるカスタムデータ行のどれかに定義したカスタム MIME タイプ。 +たとえば、値 <code>vnd.android.cursor.item/vnd.example.locationstatus</code> は、連絡先の最新の場所情報を記録するデータ行のためのカスタム MIME タイプということが考えられます。 + + + </dd> + <dt>{@code android:icon}</dt> + <dd> + 連絡先アプリケーションがデータの隣に表示する Android <a href="{@docRoot}guide/topics/resources/drawable-resource.html">ドローアブル リソース</a>。 + +そのデータが独自サービスからのものであることを示すのに使用します。 + + </dd> + <dt>{@code android:summaryColumn}</dt> + <dd> + データ行から取得された 2 つの値で最初の列名。この値は、このデータ行のエントリの先頭行として表示されます。 +この先頭行は、データの要約として使われることを狙ったものですが、省略可能です。 +<a href="#detailColumn">android:detailColumn</a> もご覧ください。 + + </dd> + <dt>{@code android:detailColumn}</dt> + <dd> + データ行から取得された 2 つの値で 2 番目の列名。この値は、このデータ行のエントリの 2 行目として表示されます。 +{@code android:summaryColumn} もご覧ください。 + + </dd> +</dl> +<h2 id="AdditionalFeatures">連絡先プロバイダの追加機能</h2> +<p> + ここまでのセクションで説明した主な機能の他に、連絡先プロバイダには連絡先データの作業用として次のような便利な機能が用意されています。 + +</p> + <ul> + <li>連絡先グループ</li> + <li>写真機能</li> + </ul> +<h3 id="Groups">連絡先グループ</h3> +<p> + 連絡先プロバイダでは、オプションで、関連連絡先のコレクションを<strong>グループ</strong> データでラベル付けできます。 +あるユーザー アカウントに関連付けられているサーバーがグループを管理する場合、そのアカウントのアカウント タイプ用の同期アダプタが、連絡先プロバイダとサーバーとの間でグループデータを転送する必要があります。 + +ユーザーが新しい連絡先をサーバーに追加し、その連絡先を新しいグループに入れた場合、同期アダプタはその新しいグループを {@link android.provider.ContactsContract.Groups} テーブルに追加する必要があります。 + +ある未加工連絡先が属するグループ(複数の場合あり)は、{@link android.provider.ContactsContract.Data} テーブルに、{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} MIME タイプを使用して格納されます。 + + +</p> +<p> + サーバーからの未加工連絡先データを連絡先プロバイダに追加する同期アダプタを設計している場合、グループを使用しないのであれば、連絡先プロバイダに対してデータが可視であることを通知する必要があります。 + +ユーザーがアカウントを端末に追加したときに実行されるコード内で、連絡先プロバイダがそのアカウントに対して追加する {@link android.provider.ContactsContract.Settings} 行をアップデートします。 + +この行で、{@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE Settings.UNGROUPED_VISIBLE} 列の値を 1 に設定します。 + +こうすると、連絡先プロバイダは、グループを使用していない場合でも、独自の連絡先データを可視にします。 + +</p> +<h3 id="Photos">連絡先の写真</h3> +<p> + {@link android.provider.ContactsContract.Data} テーブルは、写真を MIME タイプ {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE Photo.CONTENT_ITEM_TYPE} の行として格納します。 + +この行の {@link android.provider.ContactsContract.RawContactsColumns#CONTACT_ID} 列は、それが属する未加工連絡先の {@code android.provider.BaseColumns#_ID} 列にリンクされます。 + + + クラス {@link android.provider.ContactsContract.Contacts.Photo} は、連絡先のプライマリ フォトの写真情報を格納する {@link android.provider.ContactsContract.Contacts} のサブテーブルを定義します。ここでプライマリ フォトとは、連絡先のプライマリ未加工連絡先のプライマリ フォトのことを示します。 + +同様に、クラス {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} は、未加工連絡先のプライマリ フォトに関する情報を含む {@link android.provider.ContactsContract.RawContacts} のサブテーブルを定義します。 + + + +</p> +<p> + {@link android.provider.ContactsContract.Contacts.Photo} と {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} の参照ドキュメントには、写真情報の取得例が含まれています。 + +未加工連絡先のプライマリ サムネイルを取得するための便利なクラスはありませんが、{@link android.provider.ContactsContract.Data} テーブルにクエリを送信して、未加工連絡先の {@code android.provider.BaseColumns#_ID}、{@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE Photo.CONTENT_ITEM_TYPE}、{@link android.provider.ContactsContract.Data#IS_PRIMARY} 列を選んでその未加工連絡先のプライマリ フォト行を探すことができます。 + + + + + + +</p> +<p> + 人のソーシャル ストリーム データにも写真が含まれていることがあります。その場合は {@code android.provider.ContactsContract.StreamItemPhotos} テーブルに格納されています。このテーブルについては、<a href="#StreamPhotos">ソーシャル ストリーム フォト</a>で詳しく説明しています + + +</p> diff --git a/docs/html-intl/intl/ja/guide/topics/providers/content-provider-basics.jd b/docs/html-intl/intl/ja/guide/topics/providers/content-provider-basics.jd new file mode 100644 index 000000000000..9eef5d6eed46 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/providers/content-provider-basics.jd @@ -0,0 +1,1196 @@ +page.title=コンテンツ プロバイダの基本 +@jd:body +<div id="qv-wrapper"> +<div id="qv"> +<!-- In this document --> +<h2>本書の内容</h2> +<ol> + <li> + <a href="#Basics">概要</a> + <ol> + <li> + <a href="#ClientProvider">プロバイダにアクセスする</a> + </li> + <li> + <a href="#ContentURIs">コンテンツ URI</a> + </li> + </ol> + </li> + <li> + <a href="#SimpleQuery">プロバイダからデータを取得する</a> + <ol> + <li> + <a href="#RequestPermissions">読み取りアクセス パーミッションを要求する</a> + </li> + <li> + <a href="#Query">クエリを作成する</a> + </li> + <li> + <a href="#DisplayResults">クエリ結果を表示する</a> + </li> + <li> + <a href="#GettingResults">クエリ結果を取得する</a> + </li> + </ol> + </li> + <li> + <a href="#Permissions">コンテンツ プロバイダ パーミッション</a> + </li> + <li> + <a href="#Modifications">データを挿入、更新、削除する</a> + <ol> + <li> + <a href="#Inserting">データを挿入する</a> + </li> + <li> + <a href="#Updating">データを更新する</a> + </li> + <li> + <a href="#Deleting">データを削除する</a> + </li> + </ol> + </li> + <li> + <a href="#DataTypes">プロバイダ データタイプ</a> + </li> + <li> + <a href="#AltForms">プロバイダ アクセスの別の形式</a> + <ol> + <li> + <a href="#Batch">バッチアクセス</a> + </li> + <li> + <a href="#Intents">インテント経由のデータアクセス</a> + </li> + </ol> + </li> + <li> + <a href="#ContractClasses">コントラクト クラス</a> + </li> + <li> + <a href="#MIMETypeReference">MIME タイプ リファレンス</a> + </li> +</ol> + + <!-- Key Classes --> +<h2>キークラス</h2> + <ol> + <li> + {@link android.content.ContentProvider} + </li> + <li> + {@link android.content.ContentResolver} + </li> + <li> + {@link android.database.Cursor} + </li> + <li> + {@link android.net.Uri} + </li> + </ol> + + <!-- Related Samples --> +<h2>関連サンプル</h2> + <ol> + <li> + <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html"> + Cursor (People)</a> + </li> + <li> + <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html"> + Cursor (Phones)</a> + </li> + </ol> + + <!-- See also --> +<h2>関連ドキュメント</h2> + <ol> + <li> + <a href="{@docRoot}guide/topics/providers/content-provider-creating.html"> + コンテンツ プロバイダの作成</a> + </li> + <li> + <a href="{@docRoot}guide/topics/providers/calendar-provider.html"> + カレンダー プロバイダ</a> + </li> + </ol> +</div> +</div> + + <!-- Intro paragraphs --> +<p> + コンテンツ プロバイダは、データの中央リポジトリへのアクセスを管理します。プロバイダは Android アプリケーションの一部であり、通常、データを処理するための独自の UI を備えています。 + +ただし、コンテンツ プロバイダは主に他のアプリケーションでの使用を意図したものです。アプリケーションはプロバイダ クライアント オブジェクトを使用してプロバイダにアクセスします。 +さらに、プロバイダとプロバイダ クライアントにはデータを扱うための一貫性のある標準のインターフェースが備わっており、プロセス間の通信や安全なデータ アクセスを処理します。 + + +</p> +<p> + このトピックでは、次の項目に関する基本的な内容を説明します。 +</p> + <ul> + <li>コンテンツ プロバイダの仕組み。</li> + <li>コンテンツ プロバイダからのデータの取得に使用する API。</li> + <li>コンテンツ プロバイダへのデータの挿入、データの更新や削除に使用する API。</li> + <li>プロバイダでの作業に役立つその他の API 機能。</li> + </ul> + + <!-- Basics --> +<h2 id="Basics">概要</h2> +<p> + 外部アプリケーションでは、コンテンツ プロバイダのデータは、リレーショナル データベースで使用する表と同様に、1 つ以上の表として表示されます。 +行はプロバイダが収集するデータの何らかのタイプのインスタンスを表しており、行内のそれぞれの列はインスタンスに対して収集した個々のデータを表しています。 + + +</p> +<p> + たとえば、Android プラットフォームに組み込まれているプロバイダの 1 つに単語リストがありますが、ここにはユーザーが保存しておく標準以外の単語のスペリングが格納されます +表 1 は、このプロバイダの表にデータがどのように格納されているのかを表しています。 + +</p> +<p class="table-caption"> + <strong>表 1:</strong> サンプルの単語リスト表。 +</p> +<table id="table1" style="width: 50%;"> + <tr> + <th style="width:20%" align="center" scope="col">word</th> + <th style="width:20%" align="center" scope="col">app id</th> + <th style="width:20%" align="center" scope="col">frequency</th> + <th style="width:20%" align="center" scope="col">locale</th> + <th style="width:20%" align="center" scope="col">_ID</th> + </tr> + <tr> + <td align="center" scope="row">mapreduce</td> + <td align="center">user1</td> + <td align="center">100</td> + <td align="center">en_US</td> + <td align="center">1</td> + </tr> + <tr> + <td align="center" scope="row">precompiler</td> + <td align="center">user14</td> + <td align="center">200</td> + <td align="center">fr_FR</td> + <td align="center">2</td> + </tr> + <tr> + <td align="center" scope="row">applet</td> + <td align="center">user2</td> + <td align="center">225</td> + <td align="center">fr_CA</td> + <td align="center">3</td> + </tr> + <tr> + <td align="center" scope="row">const</td> + <td align="center">user1</td> + <td align="center">255</td> + <td align="center">pt_BR</td> + <td align="center">4</td> + </tr> + <tr> + <td align="center" scope="row">int</td> + <td align="center">user5</td> + <td align="center">100</td> + <td align="center">en_UK</td> + <td align="center">5</td> + </tr> +</table> +<p> + 表 1 の各行は、標準の辞書には含まれていない単語のインスタンスを表しています。 +各列は、該当する単語のデータの一部(その単語が最初に見つかったロケールなど)を表しています。 +列の見出しは、プロバイダに格納される列の名前です。 +行のロケールを調べるには、<code>locale</code> 列を参照します。このプロバイダの場合、<code>_ID</code> 列が「プライマリキー」の列の役割を果たし、プロバイダはこの列を自動的に保持します。 + + +</p> +<p class="note"> + <strong>注:</strong> プロバイダはプライマリキーを持つ必要がなく、プライマリキーがある場合は <code>_ID</code> をプライマリキーの列名として使用する必要はありません。 +ただし、プロバイダのデータを {@link android.widget.ListView} にバインドする場合は、いずれかの列の名前を <code>_ID</code> とする必要があります。 + +この要件についての詳細は、<a href="#DisplayResults">クエリ結果を表示する</a>セクションをご覧ください。 + +</p> +<h3 id="ClientProvider">プロバイダにアクセスする</h3> +<p> + アプリケーションは、{@link android.content.ContentResolver} クライアント オブジェクトを使用して、コンテンツ プロバイダのデータにアクセスします。 +このオブジェクトには、プロバイダ オブジェクトの同名のメソッドを呼び出すメソッドが備わっています。これは、{@link android.content.ContentProvider} の具体的なサブクラスのインスタンスのいずれかになります。 + +{@link android.content.ContentResolver} メソッドには、永続ストレージの基本的な「CRUD」(作成、取得、更新、削除)機能が備わっています。 + + +</p> +<p> + クライアント アプリケーションのプロセスにおける {@link android.content.ContentResolver} オブジェクトと、プロバイダを所有するアプリケーションの {@link android.content.ContentProvider} オブジェクトが、プロセス間の通信を自動的に処理します。さらに、{@link android.content.ContentProvider} は、データのリポジトリと、外部に表形式で表示されるデータの間の抽象化レイヤーとして機能します。 + + + + +</p> +<p class="note"> + <strong>注:</strong> 通常、アプリケーションがプロバイダにアクセスする場合、そのマニフェスト ファイルで特定のパーミッションを要求する必要があります。 +詳細は、<a href="#Permissions">コンテンツ プロバイダ パーミッション</a>セクションをご覧ください。 + +</p> +<p> + たとえば、単語リスト プロバイダから単語とそのロケールの一覧を取得するには、{@link android.content.ContentResolver#query ContentResolver.query()} を呼び出します。 + + {@link android.content.ContentResolver#query query()} メソッドによって、単語リスト プロバイダが定義する{@link android.content.ContentProvider#query ContentProvider.query()} メソッドが呼び出されます。 + +コードの次の行は、{@link android.content.ContentResolver#query ContentResolver.query()} 呼び出しを表しています。 + +<p> +<pre> +// Queries the user dictionary and returns results +mCursor = getContentResolver().query( + UserDictionary.Words.CONTENT_URI, // The content URI of the words table + mProjection, // The columns to return for each row + mSelectionClause // Selection criteria + mSelectionArgs, // Selection criteria + mSortOrder); // The sort order for the returned rows +</pre> +<p> + 表 2 は、query(Uri,projection,selection,selectionArgs,sortOrder)} の引数が SQL SELECT 文にどのように一致しているかを示しています。 + + +</p> +<p class="table-caption"> + <strong>表 2:</strong> SQL クエリと比較した Query()。 +</p> +<table id="table2" style="width: 75%;"> + <tr> + <th style="width:25%" align="center" scope="col">query() 引数</th> + <th style="width:25%" align="center" scope="col">SELECT キーワード / パラメータ</th> + <th style="width:50%" align="center" scope="col">注</th> + </tr> + <tr> + <td align="center"><code>Uri</code></td> + <td align="center"><code>FROM <em>table_name</em></code></td> + <td><code>Uri</code> は、<em>table_name</em> という名前のプロバイダの表にマッピングされます。</td> + </tr> + <tr> + <td align="center"><code>projection</code></td> + <td align="center"><code><em>col,col,col,...</em></code></td> + <td> + <code>projection</code> は、取得するそれぞれの行に含まれる列の配列です。 + + </td> + </tr> + <tr> + <td align="center"><code>selection</code></td> + <td align="center"><code>WHERE <em>col</em> = <em>value</em></code></td> + <td><code>selection</code> は、行を選択する際の基準を指定します。</td> + </tr> + <tr> + <td align="center"><code>selectionArgs</code></td> + <td align="center"> + (正確に一致するものはありません。選択句では、<code>?</code> プレースホルダーが選択引数に置き換わります) + + </td> + </tr> + <tr> + <td align="center"><code>sortOrder</code></td> + <td align="center"><code>ORDER BY <em>col,col,...</em></code></td> + <td> + <code>sortOrder</code> は、返される {@link android.database.Cursor} 内で行が表示される順番を指定します。 + + </td> + </tr> +</table> +<h3 id="ContentURIs">コンテンツ URI</h3> +<p> + <strong>コンテンツ URI</strong> は、プロバイダのデータを特定する URI です。コンテンツ URI には、プロバイダ全体の識別名(<strong>認証局</strong>)と表をポイントする名前(<strong>パス</strong>)が含まれます。 + +プロバイダの表にアクセスするためのクライアント メソッドを呼び出す場合、その引数の 1 つがコンテンツ URI になります。 + + +</p> +<p> + コードの前半の行では、定数 {@link android.provider.UserDictionary.Words#CONTENT_URI} に、単語リストの「words」表のコンテンツ URI が入ります。 + +{@link android.content.ContentResolver} オブジェクトは URI の認証局をパースし、認証局を既知のプロバイダのシステム表と比較して、プロバイダを「解決」します。 + +その後、{@link android.content.ContentResolver} は、クエリ引数を正しいプロバイダに送信できます。 + + +</p> +<p> + {@link android.content.ContentProvider} は、アクセスする表を選択するのに、コンテンツ URI のパス部分を使用します。 +通常、プロバイダは公開する各表の<strong>パス</strong>を持ちます。 +</p> +<p> + コードの前半の行では、「words」表の完全な URI は次のようになります。 +</p> +<pre> +content://user_dictionary/words +</pre> +<p> + ここで、<code>user_dictionary</code> 文字列はプロバイダの認証局になり、<code>words</code> 文字列は表のパスになります。 +文字列 <code>content://</code>(<strong>スキーム</strong>)は常に存在し、これがコンテンツ URI であることを示します。 + + +</p> +<p> + 多くのプログラムでは、URI の末尾に ID 値を付加することで、表内の 1 つの行にアクセスできます。たとえば、<code>_ID</code> が <code>4</code> の行を単語リストから取得するには、次のコンテンツ URI を使用します。 + + +</p> +<pre> +Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4); +</pre> +<p> + 通常は、一連の行を取得してからいずれかの行を更新、削除するような場合に ID 値を使用します。 + +</p> +<p class="note"> + <strong>注:</strong> {@link android.net.Uri} クラスと {@link android.net.Uri.Builder} クラスには、正しい形式の URI オブジェクトを文字列から作成するための、便利なメソッドが用意されています。 +{@link android.content.ContentUris} には、URI に ID 値を付加するための便利なメソッドが用意されています。前述のスニペットは {@link android.content.ContentUris#withAppendedId + withAppendedId()} を使用して、UserDictionary コンテンツ URI に ID を付加しています。 + + +</p> + + + <!-- Retrieving Data from the Provider --> +<h2 id="SimpleQuery">プロバイダからデータを取得する</h2> +<p> + このセクションでは、単語リスト プロバイダの例を使い、プロバイダからデータを取得する方法を説明します。 + +</p> +<p class="note"> + わかりやすくするために、このセクションのコード スニペットは「UI スレッド」の {@link android.content.ContentResolver#query ContentResolver.query()} を呼び出しています。 +ただし、実際のコードでは、個別のスレッドで非同期にクエリを実行する必要があります。 +この操作は、{@link android.content.CursorLoader} クラスを使用して行うこともできます。このクラスについての詳細は、「<a href="{@docRoot}guide/components/loaders.html">ローダ</a>」に関するガイドをご覧ください。 + + +さらに、コードの行はスニペットのみであり、完全なアプリケーションにはなっていません。 + +</p> +<p> + プロバイダからデータを取得するには、次の基本的な手順に従います。 +</p> +<ol> + <li> + プロバイダの読み取りアクセスを要求します。 + </li> + <li> + プロバイダにクエリを送信するコードを定義します。 + </li> +</ol> +<h3 id="RequestPermissions">読み取りアクセス パーミッションを要求する</h3> +<p> + プロバイダからデータを取得するには、アプリケーションからプロバイダの読み取りアクセスを要求します。 +実行時にはこのパーミッションを要求できません。その代わりに、<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> 要素とプロバイダで定義した正確なパーミッション名を使用して、このパーミッションを必要としていることをマニフェストで指定する必要があります。 + + + +この要素をマニフェストで指定すると、実際に、このパーミッションをアプリケーションに「要求」することになります。 +ユーザーがアプリケーションをインストールすると、この要求が暗黙的に付与されることになります。 + +</p> +<p> + 使用する読み取りアクセス パーミッションの正確な名前と、プロバイダが使用するその他のアクセス パーミッションの名前については、プロバイダのドキュメントをご覧ください。 + + +</p> +<p> + プロバイダにアクセスする際のパーミッションのロールの詳細は、<a href="#Permissions">コンテンツ プロバイダ パーミッション</a>セクションをご覧ください。 + +</p> +<p> + 単語リスト プロバイダはパーミッション <code>android.permission.READ_USER_DICTIONARY</code> をマニフェスト ファイルで定義するため、プロバイダからの読み取りを行うアプリケーションはこのパーミッションを要求する必要があります。 + + +</p> +<!-- Constructing the query --> +<h3 id="Query">クエリを作成する</h3> +<p> + プロバイダからのデータの取得の次の手順では、クエリを作成します。最初のスニペットで、単語リスト プロバイダにアクセスするための変数をいくつか定義します。 + +</p> +<pre class="prettyprint"> + +// A "projection" defines the columns that will be returned for each row +String[] mProjection = +{ + UserDictionary.Words._ID, // Contract class constant for the _ID column name + UserDictionary.Words.WORD, // Contract class constant for the word column name + UserDictionary.Words.LOCALE // Contract class constant for the locale column name +}; + +// Defines a string to contain the selection clause +String mSelectionClause = null; + +// Initializes an array to contain selection arguments +String[] mSelectionArgs = {""}; + +</pre> +<p> + 次のスニペットでは、単語リスト プロバイダの例を使って、{@link android.content.ContentResolver#query ContentResolver.query()} を使用する方法を示しています。 + +プロバイダ クライアント クエリは SQL クエリに似たものであり、戻り値となる一連の列、一連の選択基準、並べ替えの順番を含みます。 + +</p> +<p> + クエリの戻り値となる一連の列は、<strong>投影</strong>(変数 <code>mProjection</code>)と呼ばれます。 + +</p> +<p> + 取得する行を指定する式は、選択句と選択引数に分割されます。 +選択句は論理式やブール式、列名、値(変数 <code>mSelectionClause</code>)の組み合わせになります。 +値の代わりに置き換え可能パラメータ <code>?</code> を指定すると、クエリ メソッドによって、選択引数の配列(変数 <code>mSelectionArgs</code>)から値が取得されます。 + + +</p> +<p> + 次のスニペットでは、ユーザーが単語を入力しない場合、選択句が <code>null</code> に設定され、クエリによってプロバイダのすべての単語が返されます。 +ユーザーが単語を入力すると、選択句が <code>UserDictionary.Words.WORD + " = ?"</code> に設定され、選択引数の配列の最初の要素が、ユーザーが入力した単語に設定されます。 + + +</p> +<pre class="prettyprint"> +/* + * This defines a one-element String array to contain the selection argument. + */ +String[] mSelectionArgs = {""}; + +// Gets a word from the UI +mSearchString = mSearchWord.getText().toString(); + +// Remember to insert code here to check for invalid or malicious input. + +// If the word is the empty string, gets everything +if (TextUtils.isEmpty(mSearchString)) { + // Setting the selection clause to null will return all words + mSelectionClause = null; + mSelectionArgs[0] = ""; + +} else { + // Constructs a selection clause that matches the word that the user entered. + mSelectionClause = UserDictionary.Words.WORD + " = ?"; + + // Moves the user's input string to the selection arguments. + mSelectionArgs[0] = mSearchString; + +} + +// Does a query against the table and returns a Cursor object +mCursor = getContentResolver().query( + UserDictionary.Words.CONTENT_URI, // The content URI of the words table + mProjection, // The columns to return for each row + mSelectionClause // Either null, or the word the user entered + mSelectionArgs, // Either empty, or the string the user entered + mSortOrder); // The sort order for the returned rows + +// Some providers return null if an error occurs, others throw an exception +if (null == mCursor) { + /* + * Insert code here to handle the error. Be sure not to use the cursor! You may want to + * call android.util.Log.e() to log this error. + * + */ +// If the Cursor is empty, the provider found no matches +} else if (mCursor.getCount() < 1) { + + /* + * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily + * an error. You may want to offer the user the option to insert a new row, or re-type the + * search term. + */ + +} else { + // Insert code here to do something with the results + +} +</pre> +<p> + このクエリは、 SQL 文に似ています。 +</p> +<pre> +SELECT _ID, word, locale FROM words WHERE word = <userinput> ORDER BY word ASC; +</pre> +<p> + この SQL 文では、コントラクト クラスの定数ではなく、実際の列の名前が使用されます。 +</p> +<h4 id="Injection">悪意のある入力から保護する</h4> +<p> + コンテンツ プロバイダが管理するデータが SQL データベース内にある場合、外部の信頼されていないデータを未処理の SQL 文に含めると SQL インジェクションが発生することがあります。 + +</p> +<p> + 次のような選択句を考えてみます。 +</p> +<pre> +// Constructs a selection clause by concatenating the user's input to the column name +String mSelectionClause = "var = " + mUserInput; +</pre> +<p> + このようにすれば、ユーザーが悪意のある SQL を SQL 文に連結できるようになります。 + たとえば、ユーザーが <code>mUserInput</code> に「nothing; DROP TABLE *;」と入力すると、選択句は <code>var = nothing; DROP TABLE *;</code> となります。 +選択句は SQL 文として処理されるため、この場合、基本的な SQLite データベースのすべての表が消去されることがあります(プロバイダに <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL インジェクション</a>の試みの検出が設定されていない場合)。 + + + +</p> +<p> + この問題を回避するには、<code>?</code> を置き換え可能パラメータとして使う選択句と、選択引数の個別の配列を使用します。 +そうすることで、ユーザー入力は、SQL 文の一部として解釈されずに、クエリに直接バインドされます。 + + SQL として扱われないため、ユーザー入力によって悪意のある SQL が挿入されることはありません。ユーザー入力を含める際に連結を使用しないで、次の選択句を使用します。 + +</p> +<pre> +// Constructs a selection clause with a replaceable parameter +String mSelectionClause = "var = ?"; +</pre> +<p> + 選択引数の配列を次のように設定します。 +</p> +<pre> +// Defines an array to contain the selection arguments +String[] selectionArgs = {""}; +</pre> +<p> + 選択引数の配列に次のように値を格納します。 +</p> +<pre> +// Sets the selection argument to the user's input +selectionArgs[0] = mUserInput; +</pre> +<p> + プロバイダが SQL データベースに基づいたものではない場合でも、選択内容を指定する場合は、<code>?</code> を置き換え可能パラメータとして使う選択句と、選択引数の配列を使用することをお勧めします。 + + +</p> +<!-- Displaying the results --> +<h3 id="DisplayResults">クエリ結果を表示する</h3> +<p> + {@link android.content.ContentResolver#query ContentResolver.query()} クライアント メソッドは、常に {@link android.database.Cursor} を返します。これには、クエリの選択基準に一致する、行へのクエリの投影によって指定される列が含まれます。 + +{@link android.database.Cursor} オブジェクトは、含まれる行と列へのランダム読み取りアクセスを提供します。 + +{@link android.database.Cursor} メソッドを使用すると、結果の行の繰り返し、各列のデータタイプの識別、列からのデータの取得、結果のその他のプロパティの確認といった操作が可能となります。 + +一部の {@link android.database.Cursor} を実装すると、プロバイダのデータが変更された場合にオブジェクトが自動的に送信されたり、{@link android.database.Cursor} が変更された場合にオブザーバ オブジェクトのメソッドがトリガーされたり、その両方が実行されたりします。 + + +</p> +<p class="note"> + <strong>注:</strong> クエリを作成するオブジェクトの特性に基づいて、プロバイダによって列へのアクセスが制限されることがあります。 +たとえば、連絡先プロバイダにより同期アダプタは一部の列へのアクセスが制限されるため、その場合はアクティビティやサービスを返しません。 + +</p> +<p> + 選択基準に一致する行がない場合は、{@link android.database.Cursor#getCount Cursor.getCount()} が 0(空のカーソル)の {@link android.database.Cursor} オブジェクトを返します。 + + +</p> +<p> + 内部エラーが発生した場合、クエリの結果はプロバイダによって異なります。<code>null</code> が返されることもあれば、{@link java.lang.Exception} がスローされることもあります。 + +</p> +<p> + {@link android.database.Cursor} は行の「一覧」であることから、{@link android.database.Cursor} のコンテンツを表示する場合は、{@link android.widget.SimpleCursorAdapter} 経由で {@link android.widget.ListView} にリンクすることをお勧めします。 + + +</p> +<p> + 次のスニペットは前のスニペットのコードの続きです。クエリによって取得する {@link android.database.Cursor} を含む {@link android.widget.SimpleCursorAdapter} オブジェクトを作成し、このオブジェクトを {@link android.widget.ListView} のアダプタに設定します。 + + + +</p> +<pre class="prettyprint"> +// Defines a list of columns to retrieve from the Cursor and load into an output row +String[] mWordListColumns = +{ + UserDictionary.Words.WORD, // Contract class constant containing the word column name + UserDictionary.Words.LOCALE // Contract class constant containing the locale column name +}; + +// Defines a list of View IDs that will receive the Cursor columns for each row +int[] mWordListItems = { R.id.dictWord, R.id.locale}; + +// Creates a new SimpleCursorAdapter +mCursorAdapter = new SimpleCursorAdapter( + getApplicationContext(), // The application's Context object + R.layout.wordlistrow, // A layout in XML for one row in the ListView + mCursor, // The result from the query + mWordListColumns, // A string array of column names in the cursor + mWordListItems, // An integer array of view IDs in the row layout + 0); // Flags (usually none are needed) + +// Sets the adapter for the ListView +mWordList.setAdapter(mCursorAdapter); +</pre> +<p class="note"> + <strong>注:</strong> {@link android.database.Cursor} によって {@link android.widget.ListView} を戻すには、カーソルに <code>_ID</code> という名前の列を含める必要があります。 + + そのため、{@link android.widget.ListView} には表示されまませんが、前述のクエリは「words」表に <code>_ID</code> 列を取得します。 + + また、このような制限があることから、大部分のプロバイダがそれぞれの表に <code>_ID</code> 列を持ちます。 + +</p> + + <!-- Getting data from query results --> +<h3 id="GettingResults">クエリ結果を取得する</h3> +<p> + クエリ結果を単に表示するだけでなく、他のタスクに使用することもできます。たとえば、単語リストからスペリングを取得して、それを他のプロバイダで検索するといった操作も可能です。 + +そのためには、次のように {@link android.database.Cursor} の行に操作を繰り返します。 +</p> +<pre class="prettyprint"> + +// Determine the column index of the column named "word" +int index = mCursor.getColumnIndex(UserDictionary.Words.WORD); + +/* + * Only executes if the cursor is valid. The User Dictionary Provider returns null if + * an internal error occurs. Other providers may throw an Exception instead of returning null. + */ + +if (mCursor != null) { + /* + * Moves to the next row in the cursor. Before the first movement in the cursor, the + * "row pointer" is -1, and if you try to retrieve data at that position you will get an + * exception. + */ + while (mCursor.moveToNext()) { + + // Gets the value from the column. + newWord = mCursor.getString(index); + + // Insert code here to process the retrieved word. + + ... + + // end of while loop + } +} else { + + // Insert code here to report an error if the cursor is null or the provider threw an exception. +} +</pre> +<p> + {@link android.database.Cursor} の実装には「取得」メソッドがいくつか備わっており、オブジェクトからさまざまなタイプのデータを取得できます。 +たとえば、前述のスニペットは {@link android.database.Cursor#getString getString()} を使用しています。 +さらに、列のデータタイプを示す値を返す {@link android.database.Cursor#getType getType()} メソッドも使用しています。 + + +</p> + + + <!-- Requesting permissions --> +<h2 id="Permissions">コンテンツ プロバイダ パーミッション</h2> +<p> + プロバイダのアプリケーションでは、他のアプリケーションがプロバイダのデータにアクセスするのに必要なパーミッションを指定できます。 +これらのパーミッションを設定しておけば、ユーザーはアプリケーションがアクセスしようとしているデータの種類を把握できます。 +他のアプリケーションは、プロバイダの要件に基づき、そのプロバイダにアクセスするのに必要なパーミッションを要求します。 +エンドユーザーがアプリケーションをインストールする際には、要求されたパーミッションを確認できます。 + +</p> +<p> + プロバイダのアプリケーションでパーミッションを指定していない場合は、他のアプリケーションはプロバイダのデータにアクセスできません。 +ただし、指定したパーミッションに関係なく、プロバイダのアプリケーションのコンポーネントには完全な読み取り権限と書き込み権限を常に付与する必要があります。 + +</p> +<p> + 前述のとおり、単語リスト プロバイダには、データを取得するための <code>android.permission.READ_USER_DICTIONARY</code> パーミッションが必要です。 + + プロバイダには、データの挿入、更新、削除に対してそれぞれ個別の <code>android.permission.WRITE_USER_DICTIONARY</code> パーミッションがあります。 + +</p> +<p> + プロバイダにアクセスするのに必要なパーミッションを取得するには、アプリケーションのマニフェスト ファイルの <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> 要素を使用してパーミッションを要求する必要があります。 + +Android Package Manager でアプリケーションをインストールする場合は、ユーザーがアプリケーションが要求するすべてのパーミッションを承認する必要があります。 +ユーザーがすべてのパーミッションを承認すると、Package Manager がインストールを続行します。ユーザーが承認しない場合は、Package Manager がインストールを中止します。 + + +</p> +<p> + 次の <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> 要素は、単語リスト プロバイダへの読み取りアクセスを要求します。 + + +</p> +<pre> + <uses-permission android:name="android.permission.READ_USER_DICTIONARY"> +</pre> +<p> + プロバイダ アクセスへのパーミッションの影響については、<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>に関するガイドをご覧ください。 + +</p> + + +<!-- Inserting, Updating, and Deleting Data --> +<h2 id="Modifications">データを挿入、更新、削除する</h2> +<p> + データを収集するには、プロバイダからデータを取得するのと同様に、プロバイダ クライアントとプロバイダの {@link android.content.ContentProvider} 間で操作を行います。 + + 対応する {@link android.content.ContentProvider} のメソッドに渡した引数を使用して、{@link android.content.ContentResolver} のメソッドを呼び出します。 +プロバイダとプロバイダ クライアントが、セキュリティとプロセス間の通信を自動的に処理します。 + +</p> +<h3 id="Inserting">データを挿入する</h3> +<p> + プロバイダにデータを挿入するには、{@link android.content.ContentResolver#insert ContentResolver.insert()} メソッドを呼び出します。 + +このメソッドはプロバイダに新しい行を挿入し、その行のコンテンツ URI を返します。 + このスニペットは、単語リスト プロバイダに新しい単語を挿入する方法を示しています。 +</p> +<pre class="prettyprint"> +// Defines a new Uri object that receives the result of the insertion +Uri mNewUri; + +... + +// Defines an object to contain the new values to insert +ContentValues mNewValues = new ContentValues(); + +/* + * Sets the values of each column and inserts the word. The arguments to the "put" + * method are "column name" and "value" + */ +mNewValues.put(UserDictionary.Words.APP_ID, "example.user"); +mNewValues.put(UserDictionary.Words.LOCALE, "en_US"); +mNewValues.put(UserDictionary.Words.WORD, "insert"); +mNewValues.put(UserDictionary.Words.FREQUENCY, "100"); + +mNewUri = getContentResolver().insert( + UserDictionary.Word.CONTENT_URI, // the user dictionary content URI + mNewValues // the values to insert +); +</pre> +<p> + 新しい行のデータは 1 つの {@link android.content.ContentValues} オブジェクトに入ります。これは 1 行カーソルの形式に似ています。 +このオブジェクト内の列は同じデータタイプを持つ必要はなく、値をまったく指定しない場合は、{@link android.content.ContentValues#putNull ContentValues.putNull()} を使用して列を <code>null</code> に設定できます。 + + +</p> +<p> + この列は自動的に保持されるため、スニペットは <code>_ID</code> 列を追加しません。 +プロバイダは、追加するそれぞれの行に、<code>_ID</code> の一意の値を割り当てます。 +通常、プロバイダはこの値を表のプライマリキーとして使用します。 +</p> +<p> + <code>newUri</code> で返されるコンテンツ URI は、新たに追加された行を特定するものであり、次の形式となります。 + +</p> +<pre> +content://user_dictionary/words/<id_value> +</pre> +<p> + <code><id_value></code> は、新しい行の <code>_ID</code> のコンテンツです。 + ほとんどのプロバイダではコンテンツ URI のこの形式を自動的に検出し、特定の行で要求された操作を実行します。 + +</p> +<p> + 返された {@link android.net.Uri} から <code>_ID</code> の値を取得するには、{@link android.content.ContentUris#parseId ContentUris.parseId()} を呼び出します。 + +</p> +<h3 id="Updating">データを更新する</h3> +<p> + 行を更新するには、挿入操作と同じように、値を更新した {@link android.content.ContentValues} オブジェクトと、クエリ操作のときと同じように選択基準を使用します。 + + 使用するクライアント メソッドは {@link android.content.ContentResolver#update ContentResolver.update()} です。 +更新する列の {@link android.content.ContentValues} オブジェクトに値を追加する操作のみが必要になります。 +列のコンテンツを消去する場合は、値を <code>null</code> に設定します。 + +</p> +<p> + 次のスニペットは、ロケール言語が「en」となっているすべての行のロケールを <code>null</code> に変更します。 +戻り値は、更新された行の数となります。 +</p> +<pre> +// Defines an object to contain the updated values +ContentValues mUpdateValues = new ContentValues(); + +// Defines selection criteria for the rows you want to update +String mSelectionClause = UserDictionary.Words.LOCALE + "LIKE ?"; +String[] mSelectionArgs = {"en_%"}; + +// Defines a variable to contain the number of updated rows +int mRowsUpdated = 0; + +... + +/* + * Sets the updated value and updates the selected words. + */ +mUpdateValues.putNull(UserDictionary.Words.LOCALE); + +mRowsUpdated = getContentResolver().update( + UserDictionary.Words.CONTENT_URI, // the user dictionary content URI + mUpdateValues // the columns to update + mSelectionClause // the column to select on + mSelectionArgs // the value to compare to +); +</pre> +<p> + また、{@link android.content.ContentResolver#update ContentResolver.update()} を呼び出すときには、ユーザー入力をサニタイズする必要があります。 +詳細は、<a href="#Injection">悪意のある入力から保護する</a>セクションをご覧ください。 + +</p> +<h3 id="Deleting">データを削除する</h3> +<p> + 行の削除は行データの取得と似た操作になります。削除する行の選択基準を指定することで、クライアント メソッドが削除した行の数を返します。 + + 次のスニペットは appid が「user」となっている行を削除します。メソッドによって削除された行の数が返されます。 + +</p> +<pre> + +// Defines selection criteria for the rows you want to delete +String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?"; +String[] mSelectionArgs = {"user"}; + +// Defines a variable to contain the number of rows deleted +int mRowsDeleted = 0; + +... + +// Deletes the words that match the selection criteria +mRowsDeleted = getContentResolver().delete( + UserDictionary.Words.CONTENT_URI, // the user dictionary content URI + mSelectionClause // the column to select on + mSelectionArgs // the value to compare to +); +</pre> +<p> + また、{@link android.content.ContentResolver#delete ContentResolver.delete()} を呼び出すときには、ユーザー入力をサニタイズする必要があります。 +詳細は、<a href="#Injection">悪意のある入力から保護する</a>セクションをご覧ください。 + +</p> +<!-- Provider Data Types --> +<h2 id="DataTypes">プロバイダ データタイプ</h2> +<p> + コンテンツ プロバイダではさまざまなデータタイプを利用できます。単語リスト プロバイダで提供できるのはテキストのみですが、次のような形式を提供できます。 + +</p> + <ul> + <li> + 整数 + </li> + <li> + long 整数(long) + </li> + <li> + 浮動小数点 + </li> + <li> + long 浮動小数点(double) + </li> + </ul> +<p> + それ以外にも、プロバイダでは 64KB バイト配列として実装されるバイナリ ラージ オブジェクト(BLOB)もよく使用されます。 +利用可能なデータタイプについては、{@link android.database.Cursor} クラスの「get」メソッドをご覧ください。 + +</p> +<p> + プロバイダの各列のデータタイプは、通常、そのドキュメントに一覧が記載されています。 + 単語リスト プロバイダのデータタイプは、コントラクト クラス {@link android.provider.UserDictionary.Words} のリファレンスに一覧が記載されています(コントラクト クラスの詳細は、<a href="#ContractClasses">コントラクト クラス</a>セクションをご覧ください)。 + + + さらに、{@link android.database.Cursor#getType + Cursor.getType()} を呼び出すことで、データタイプを判断することもできます。 +</p> +<p> + プロバイダは、プロバイダによって定義される各コンテンツ URI の MIME データタイプも保持します。MIME タイプ情報を使用すると、プロバイダが提供するデータをアプリケーションが処理できるかを判断したり、MIME タイプに基づいて処理のタイプを選択したりできます。 + +通常は、複雑なデータ構造やファイルを持つプロバイダで作業をする際に MIME タイプが必要になります。 + +たとえば、連絡先プロバイダの {@link android.provider.ContactsContract.Data} 表は MIME タイプを使用して、それぞれの行に格納される連絡先データのタイプをラベル付けします。 + +コンテンツ URI に対応する MIME タイプを取得するには、{@link android.content.ContentResolver#getType ContentResolver.getType()} を呼び出します。 + +</p> +<p> + 「<a href="#MIMETypeReference">MIME タイプ リファレンス</a>」セクションでは、標準とカスタムの両方の MIME タイプについて説明しています。 + +</p> + + +<!-- Alternative Forms of Provider Access --> +<h2 id="AltForms">プロバイダ アクセスの別の形式</h2> +<p> + アプリケーションの開発では、次に示すプロバイダ アクセスの別の 3 つの形式が重要になります。 +</p> +<ul> + <li> + <a href="#Batch">バッチアクセス</a>: {@link android.content.ContentProviderOperation} クラスのメソッドを使用したアクセス呼び出しのバッチを作成し、{@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()} に適用できます。 + + + </li> + <li> + 非同期クエリ: クエリは個別のスレッドで実行する必要があります。この操作は、{@link android.content.CursorLoader} オブジェクトを使用して行うこともできます。 +「<a href="{@docRoot}guide/components/loaders.html">ローダ</a>」のガイドには、この操作の例が記載されています。 + + + </li> + <li> + <a href="#Intents">インテント経由のデータアクセス</a>: インテントをプロバイダに直接送信できませんが、プロバイダのアプリケーションにはインテントを送信できます。通常、プロバイダのデータの修正に最適な機能を備えたアプリケーションになります。 + + + </li> +</ul> +<p> + バッチアクセスとインテント経由の修正については、次のセクションで説明しています。 +</p> +<h3 id="Batch">バッチアクセス</h3> +<p> + 多数の行を挿入する場合や、同じメソッド呼び出しで複数の表に行を挿入する場合は、プロバイダへのバッチアクセスを使用すると便利です。また、一般的には、境界をまたいでプロセス全体にトランザクションとして一連の操作を実行する場合にもバッチアクセスが便利です。 + + +</p> +<p> + 「バッチモード」でプロバイダにアクセスするには、{@link android.content.ContentProviderOperation} オブジェクトの配列を作成してから、{@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()} を使用してそれらのオブジェクトをコンテンツ プロバイダに送信します。 + + +このメソッドには、特定のコンテンツ URI ではなく、コンテンツ プロバイダの<em>認証局</em>を渡します。そうすることで、配列内のそれぞれの {@link android.content.ContentProviderOperation} オブジェクトを別々の表に対して機能するようになります。 + + +{@link android.content.ContentResolver#applyBatch + ContentResolver.applyBatch()} への呼び出しでは、結果の配列が返されます。 +</p> +<p> + {@link android.provider.ContactsContract.RawContacts} コントラクト クラスの説明には、バッチ挿入を示したコード スニペットが記載されています。 +<a href="{@docRoot}resources/samples/ContactManager/index.html">Contact Manager</a> のサンプル アプリケーションでは、<code>ContactAdder.java</code> ソースファイルでのバッチアクセスの例が紹介されています。 + + + +</p> +<div class="sidebox-wrapper"> +<div class="sidebox"> +<h2>ヘルパーアプリでデータを表示する</h2> +<p> + アプリケーションにアクセス パーミッションが<em>付与されている</em>場合でも、インテントを使用して別のアプリケーションにデータを表示できます。 +たとえば、カレンダー アプリケーションは {@link android.content.Intent#ACTION_VIEW} インテントにアクセスしますが、このインテントは特定の日付やイベントを表示するものです。 + + これにより、独自の UI を作成しなくても、カレンダー情報を表示できます。この機能の詳細は、「<a href="{@docRoot}guide/topics/providers/calendar-provider.html">カレンダー プロバイダ</a>」のガイドをご覧ください。 + + +</p> +<p> + インテントの送信先アプリケーションは、必ずしもプロバイダに関連付けられたアプリケーションである必要はありません。 +たとえば、連絡先プロバイダから連絡先を取得してから、連絡先の画像のコンテンツ URI を含む {@link android.content.Intent#ACTION_VIEW} インテントを画像ビューワに送信するといった操作が可能です。 + + +</p> +</div> +</div> +<h3 id="Intents">インテント経由のデータアクセス</h3> +<p> + インテントを使用すれば、コンテンツ プロバイダに間接的にアクセスできます。アプリケーションにアクセス パーミッションがない場合でも、パーミッションを持つアプリケーションから結果のインテントを取得したり、パーミッションを持つアプリケーションをアクティベートしてそのアプリケーションをユーザーに使用させたりすることで、ユーザーがプロバイダのデータにアクセスできるようになります。 + + + +</p> +<h4>一時的なパーミッションによりアクセスを取得する</h4> +<p> + 適切なアクセス パーミッションがない場合でも、パーミッションを持つアプリケーションにインテントを送信し、「URI」パーミッションを含む結果のインテントを受け取ることで、コンテンツ プロバイダのデータにアクセスできます。 + + + これらのパーミッションは特定のコンテンツ URI のパーミッションであり、パーミッションを受け取ったアクティビティが終了するまで効力を持ちます。 +永続的なパーミッションを持つアプリケーションは、次のように結果のインテントにフラグを設定し、一時的なパーミッションを付与します。 + +</p> +<ul> + <li> + <strong>読み取りパーミッション:</strong> {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} + + </li> + <li> + <strong>書き込みパーミッション:</strong> {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} + + </li> +</ul> +<p class="note"> + <strong>注:</strong> これらのフラグは、認証局がコンテンツ URI に含まれるプロバイダへの全般的な読み取りと書き込みアクセスを付与するものではありません。アクセスは URI 自身に限定されます。 + +</p> +<p> + プロバイダは、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></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"><provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"><grant-uri-permission></a></code> 子要素を使用して、コンテンツ URI の URI パーミッションを自身のマニフェストで定義します。 + + + + + + + +URI パーミッションのメカニズムについての詳細は、URI パーミッション セクションの<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>に関するガイドをご覧ください。 + + +</p> +<p> + たとえば、{@link android.Manifest.permission#READ_CONTACTS} パーミッションを持たない場合でも、連絡先プロバイダの連絡先のデータを取得できます。 +連絡先の誕生日にグリーティング カードをオンラインで送信するアプリケーションなどにこのメカニズムを利用できます。 +ユーザーのすべての連絡先やそのすべての情報へのアクセス件を付与する {@link android.Manifest.permission#READ_CONTACTS} を要求する代わりに、アプリケーションで使用する連絡先をユーザーが制御できるように設定することもできます。 + + +そのためには、次の手順を使用します。 +</p> +<ol> + <li> + アプリケーションが、メソッド {@link android.app.Activity#startActivityForResult + startActivityForResult()} を使用して、アクション {@link android.content.Intent#ACTION_PICK} と「連絡先」MIME タイプ {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} を含むインテントを送信します。 + + + + </li> + <li> + このインテントは連絡帳アプリの「selection」アクティビティのインテント フィルタに一致するため、アクティビティがフォアグラウンドに移動します。 + + </li> + <li> + selection アクティビティでは、更新する連絡先をユーザーが選択します。 +この操作が行われると、selection が {@link android.app.Activity#setResult setResult(resultcode, intent)} を呼び出し、アプリケーションに戻すインテントを設定します。 + +インテントには、ユーザーが選択した連絡先のコンテンツ URI と、「エクストラ」フラグ {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} が含まれます。 + +これらのフラグがあることで、コンテンツ URI がポイントする連絡先のデータを読み取るための URI パーミッションがアプリに付与されます。その後、selection アクティビティによって、アプリケーションに制御を返すための {@link android.app.Activity#finish()} が呼び出されます。 + + + + </li> + <li> + アクティビティがフォアグラウンドに戻り、システムがアクティビティの {@link android.app.Activity#onActivityResult onActivityResult()} メソッドを呼び出します。 + +このメソッドは、連絡帳アプリの selection アクティビティによって作成された結果のインテントを受け取ります。 + + </li> + <li> + 結果のインテントのコンテンツ URI を使用すれば、マニフェストで永続的なアクセス パーミッションをプロバイダに要求していなくても、連絡先プロバイダから連絡先のデータを読み取ることができます。 + +その後、連絡先の誕生日情報やメールアドレスを取得し、グリーティング カードをオンラインで送信できます。 + + </li> +</ol> +<h4>別のアプリケーションを使用する</h4> +<p> + パーミッションを持つアプリケーションをアクティベートし、そのアプリケーションをユーザーが使用すれば、アクセス パーミッションを持たないデータをユーザーが修正できるようになります。 + +</p> +<p> + たとえば、アプリケーションの挿入 UI をアクティベートできる {@link android.content.Intent#ACTION_INSERT} インテントをカレンダー アプリケーションが受け入れるとします。このインテントに「エクストラ」データを渡すことで、アプリケーションがそのデータを使用して、事前に入力された UI を作成します。繰り返し発生するイベントは複雑な構文を持つため、カレンダー プロバイダにイベントを挿入する場合は、{@link android.content.Intent#ACTION_INSERT} でカレンダー アプリをアクティベートしてから、ユーザーにイベントを挿入してもらうことをお勧めします。 + + + + + +</p> +<!-- Contract Classes --> +<h2 id="ContractClasses">コントラクト クラス</h2> +<p> + コントラクト クラスは、アプリケーションがコンテンツ URI、列名、インテント アクション、コンテンツのその他の機能で作業する際に役立つ定数を定義します。 +プロバイダでコントラクト クラスが自動的に含まれることはありません。プロバイダのデベロッパーはコントラクト クラスを定義して、その他のデベロッパーが使用できるようにする必要があります。 + +Android プラットフォームに含まれる多くのプロバイダは、パッケージ {@link android.provider} 内に対応するコントラクト クラスを持ちます。 + +</p> +<p> + たとえば、単語リスト プロバイダは、コンテンツ URI と列名の定数を含む、コントラクト クラス {@link android.provider.UserDictionary} を持つとします。 +「words」表のコンテンツ URI は、定数 {@link android.provider.UserDictionary.Words#CONTENT_URI UserDictionary.Words.CONTENT_URI} で定義されます。 + + + さらに、{@link android.provider.UserDictionary.Words} クラスは、このガイドのサンプルのスニペットで使用される、列名の定数を持ちます。 +たとえば、クエリの投影は次のように定義できます。 + +</p> +<pre> +String[] mProjection = +{ + UserDictionary.Words._ID, + UserDictionary.Words.WORD, + UserDictionary.Words.LOCALE +}; +</pre> +<p> + もう一方のコントラクト クラスは、連絡先プロバイダのクラス {@link android.provider.ContactsContract} です。 + このクラスのリファレンスには、サンプルのコード スニペットが記載されています。サブクラスの 1 つである {@link android.provider.ContactsContract.Intents.Insert} は、インテントとインテント データの定数を含むコントラクト クラスです。 + + +</p> + + +<!-- MIME Type Reference --> +<h2 id="MIMETypeReference">MIME タイプ リファレンス</h2> +<p> + コンテンツ プロバイダは、標準の MIME メディア タイプかカスタムの MIME タイプ文字列、またはその両方を返すことができます。 +</p> +<p> + MIME タイプは次の形式となります +</p> +<pre> +<em>type</em>/<em>subtype</em> +</pre> +<p> + たとえば、よく利用される MIME タイプ <code>text/html</code> は、<code>text</code> タイプと <code>html</code> サブタイプを持ちます。 +プロバイダから URI に対してこのタイプが返される場合、その URI を使用するクエリは HTML タグを含むテキストを返すことになります。 + +</p> +<p> + 「ベンダー固有の」MIME タイプとも呼ばれるカスタムの MIME タイプ文字列には、より複雑な <em>type</em> と <em>subtype</em> の値が含まれます。 +複数行の場合、<em>type</em> 値は常に +</p> +<pre> +vnd.android.cursor.<strong>dir</strong> +</pre> +<p> + となり、1 つの行の場合は +</p> +<pre> +vnd.android.cursor.<strong>item</strong> +</pre> +<p> + となります。 +</p> +<p> + <em>subtype</em> はプロバイダ固有の値になります。通常、Android 組み込みプロバイダは単純な subtype を使用します。 +たとえば、連絡先アプリケーションが電話番号の行を作成すると、行には次のように MIME タイプが設定されます。 + +</p> +<pre> +vnd.android.cursor.item/phone_v2 +</pre> +<p> + subtype の値は単純に <code>phone_v2</code> となっていることがわかります。 +</p> +<p> + 他のプロバイダ デベロッパーは、プロバイダの認証局と表明に基づいて独自のパターンの subtype を作成できます。 +たとえば、列車の時刻表を含むプロバイダについて考えてみます。 + プロバイダの認証局は <code>com.example.trains</code> であり、表 Line1、Line2、Line3 を持ちます。 +表 Line1 のコンテンツ URI +</p> +<p> +<pre> +content://com.example.trains/Line1 +</pre> +<p> + に対しては、プロバイダは次の MIME タイプを返します +</p> +<pre> +vnd.android.cursor.<strong>dir</strong>/vnd.example.line1 +</pre> +<p> + 表 Line2 の行 5 のコンテンツ URI +</p> +<pre> +content://com.example.trains/Line2/5 +</pre> +<p> + に対しては、プロバイダは次の MIME タイプを返します +</p> +<pre> +vnd.android.cursor.<strong>item</strong>/vnd.example.line2 +</pre> +<p> + ほとんどのコンテンツ プロバイダが、使用する MIME タイプに対してコントラクト クラス定数を定義します。たとえば、連絡先プロバイダのコントラクト クラス {@link android.provider.ContactsContract.RawContacts} は、1 つの未加工連絡先行の MIME タイプに、定数 {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} を定義します。 + + + + +</p> +<p> + 1 つの行のコンテンツ URI については、<a href="#ContentURIs">コンテンツ URI</a> セクションをご覧ください。 + +</p> diff --git a/docs/html-intl/intl/ja/guide/topics/providers/content-provider-creating.jd b/docs/html-intl/intl/ja/guide/topics/providers/content-provider-creating.jd new file mode 100644 index 000000000000..af2181482d33 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/providers/content-provider-creating.jd @@ -0,0 +1,1214 @@ +page.title=コンテンツ プロバイダの作成 +@jd:body +<div id="qv-wrapper"> +<div id="qv"> + + +<h2>本書の内容</h2> +<ol> + <li> + <a href="#DataStorage">データ ストレージを設計する</a> + </li> + <li> + <a href="#ContentURI">コンテンツ URI を設計する</a> + </li> + <li> + <a href="#ContentProvider">ContentProvider クラスを実装する</a> + <ol> + <li> + <a href="#RequiredAccess">必須メソッド</a> + </li> + <li> + <a href="#Query">query() メソッドを実装する</a> + </li> + <li> + <a href="#Insert">insert() メソッドを実装する</a> + </li> + <li> + <a href="#Delete">delete() メソッドを実装する</a> + </li> + <li> + <a href="#Update">update() メソッドを実装する</a> + </li> + <li> + <a href="#OnCreate">onCreate() メソッドを実装する</a> + </li> + </ol> + </li> + <li> + <a href="#MIMETypes">コンテンツ プロバイダ MIME を実装する</a> + <ol> + <li> + <a href="#TableMIMETypes">テーブルの MIME タイプ</a> + </li> + <li> + <a href="#FileMIMETypes">ファイルの MIME タイプ</a> + </li> + </ol> + </li> + <li> + <a href="#ContractClass">コントラクト クラスを実装する</a> + </li> + <li> + <a href="#Permissions">コンテンツ プロバイダ パーミッションを実装する</a> + </li> + <li> + <a href="#ProviderElement"><provider> 要素</a> + </li> + <li> + <a href="#Intents">インテントとデータアクセス</a> + </li> +</ol> +<h2>キークラス</h2> + <ol> + <li> + {@link android.content.ContentProvider} + </li> + <li> + {@link android.database.Cursor} + </li> + <li> + {@link android.net.Uri} + </li> + </ol> +<h2>関連サンプル</h2> + <ol> + <li> + <a href="{@docRoot}resources/samples/NotePad/index.html"> + Note Pad のサンプル アプリケーション </a> + + </li> + </ol> +<h2>関連ドキュメント</h2> + <ol> + <li> + <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> + コンテンツ プロバイダの基本</a> + </li> + <li> + <a href="{@docRoot}guide/topics/providers/calendar-provider.html"> + カレンダー プロバイダ</a> + </li> + </ol> +</div> +</div> + + +<p> + コンテンツ プロバイダは、データの中央リポジトリへのアクセスを管理します。Android アプリケーションでは 1 つ以上のクラスとしてプロバイダを実装し、要素をマニフェスト ファイルで実装します。 + +いずれか 1 つのクラスがサブラス {@link android.content.ContentProvider} を実装します。これは、プロバイダと他のアプリケーションとの間のインターフェースになります。 + +コンテンツ プロバイダは他のアプリケーションへのデータの提供を意図したものですが、ユーザーがプロバイダに管理されるデータを照会、修正するアクティビティをアプリケーション内に設定することもできます。 + + +</p> +<p> + このトピックの残りの部分では、コンテンツ プロバイダと使用する API のリストをビルドするための基本的な手順を挙げていきます。 + +</p> + + +<!-- Before You Start Building --> +<h2 id="BeforeYouStart">ビルドを開始する前に</h2> +<p> + ビルドを開始する前に、次の操作を行います。 +</p> +<ol> + <li> + <strong>コンテンツ プロバイダが必要かどうかを決定します</strong>。次のような機能を 1 つ以上提供する場合に、コンテンツ プロバイダをビルドする必要があります。 + + <ul> + <li>他のアプリケーションに複雑なデータやファイルを提供する。</li> + <li>アプリから他のアプリへの複雑なデータのコピーをユーザーに許可する。</li> + <li>検索フレームワークを使用してカスタムの検索候補を提供する。</li> + </ul> + <p> + 完全に独自アプリケーション内だけで使用する場合は、SQLite データベースを使用するプロバイダは必要はありません。<em></em> + + </p> + </li> + <li> + 必要かどうかを決定していない場合は、プロバイダの詳細については「<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>」のトピックをご覧ください。 + + + </li> +</ol> +<p> + 次に、以下の手順に従ってプロバイダをビルドします。 +</p> +<ol> + <li> + データの未処理のストレージを設計します。コンテンツ プロバイダは次の 2 つの方法でデータを提供します。 + <dl> + <dt> + ファイルデータ + </dt> + <dd> + 通常、写真、オーディオ、ビデオなどのファイルの形式となるデータです。 +ファイルはアプリケーションのプライベート スペースに格納します。 +ファイルに対する別のアプリケーションからの要求に応じて、プロバイダからファイルへのハンドルが提供されます。 + + </dd> + <dt> + 「構造化」データ + </dt> + <dd> + 通常、データベース、配列、類似の構造の形式となるデータです。 + テーブルの行と列に互換性を持つ形式でデータが格納されます。行は、担当者や在庫にあるアイテムなどのエンティティを表します。 +列は、担当者の名前やアイテムの価格などの、エンティティの一部のデータを表します。 +一般的にこのタイプのデータは SQLite データベースに格納しますが、任意のタイプの永続ストレージを使用できます。 + +Android システムで使用できるストレージ タイプの詳細は、<a href="#DataStorage">データ ストレージを設計する</a>をご覧ください。 + + + </dd> + </dl> + </li> + <li> + {@link android.content.ContentProvider} クラスの具体的な実装とそれに必要なメソッドを定義します。 +このクラスは、データと Android システムのそれ以外の部分とのインターフェースとなります。 +このクラスの詳細は、<a href="#ContentProvider">ContentProvider クラスを実装する</a>セクションをご覧ください。 + + </li> + <li> + プロバイダの認証局の文字列、コンテンツ URI、列名を定義します。プロバイダのアプリケーションでインテントを処理する場合は、インテント アクション、エクストラ データ、フラグも定義します。 + +さらに、データにアクセスするアプリケーションに必要なパーミッションも定義します。 +これらの値はすべて定数として個別のコントラクト クラスに定義するようにします。そうしておくと、後で他のデベロッパーに対してこのクラスを公開できます。 +コンテンツ URI の詳細は、<a href="#ContentURI">コンテンツ URI を設計する</a>セクションをご覧ください。 + + + インテントの使用に関する詳細については、<a href="#Intents">インテントとデータアクセス</a>セクションをご覧ください。 + + </li> + <li> + サンプルデータや、プロバイダとクラウドベースのデータの間でデータを同期する {@link android.content.AbstractThreadedSyncAdapter} の実装などの、その他のオプション部分を追加します。 + + + </li> +</ol> + + +<!-- Designing Data Storage --> +<h2 id="DataStorage">データ ストレージを設計する</h2> +<p> + コンテンツ プロバイダは、構造化された形式で保存されているデータへのインターフェースです。インターフェースを作成する前に、データの格納方法を決定しておく必要があります。 +データは任意の形式で保存でき、必要に応じてデータの読み取りと書き込みを行うためのインターフェースを設計できます。 + +</p> +<p> + Android には、次のように、いくつかのデータ格納テクノロジーがあります。 +</p> +<ul> + <li> + Android システムには、Android の独自のプロバイダがテーブル指向のデータを格納するために使用する、SQLite データベース API があります。 +{@link android.database.sqlite.SQLiteOpenHelper} クラスを使用すると、データベースを作成できます。また、{@link android.database.sqlite.SQLiteDatabase} クラスは、データベースにアクセスするための基本クラスです。 + + + + <p> + リポジトリを実装するのに、データベースを使用する必要がありません。外部的には、プロバイダはリレーショナル データベースに似た一連のテーブルとして表示されますが、プロバイダの内部実装をそのような形式にする必要はありません。 + + + </p> + </li> + <li> + ファイルデータを格納するために、Android にはファイル指向のさまざまな API があります。 + ファイル ストレージの詳細は、「<a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>」トピックをご覧ください。 +音楽やビデオのようにメディア関連のデータを提供するプロバイダを設計する場合は、テーブルデータとファイルを組み合わせるプロバイダを作成できます。 + + + </li> + <li> + ネットワーク ベースのデータで作業する場合は、{@link java.net} と {@link android.net} のクラスを使用します。 +また、ネットワーク ベースをデータベースなどのローカル データストアに同期させ、データをテーブルやファイルとして提供することもできます。 + + <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">サンプル同期アダプタ</a>のサンプル アプリケーションでは、このタイプの同期のデモを紹介しています。 + + </li> +</ul> +<h3 id="DataDesign"> + データ設計上の考慮事項 +</h3> +<p> + 次に、プロバイダのデータ構造を設計する際のヒントを示します。 +</p> +<ul> + <li> + テーブルデータには、プロバイダが各行の一意の数値として保持する「プライマリキー」列が常に必要です。 +この値を使用すると、行を他のテーブルの関連する行にリンクできます(「外部キー」として使用)。 +この列には任意の名前を設定できますが、プロバイダ クエリの結果を {@link android.widget.ListView} にリンクさせるには、取得する列のいずれかの名前が <code>_ID</code> になっている必要があるため、{@link android.provider.BaseColumns#_ID BaseColumns._ID} を使用することをお勧めします。 + + + + + </li> + <li> + ビットマップ画像やサイズが非常に大きなその他のファイル指向のデータを提供する場合は、テーブルにデータを直接格納するのではなく、データをファイルに格納し、データを間接的に提供します。 + +その場合、データにアクセスするには、{@link android.content.ContentResolver} ファイル メソッドの使用が必要であることをプロバイダのユーザーに通知する必要があります。 + + </li> + <li> + サイズや構造が異なるデータを格納するには、バイナリ ラージ オブジェクト(BLOB)データタイプを使用します。 +たとえば、<a href="http://code.google.com/p/protobuf">Protocol Buffer</a> や <a href="http://www.json.org">JSON 構造</a>を格納するには、BLOB 列を使用します。 + + + <p> + さらに、BLOB を使用してスキーマに依存しないテーブルを実装できます。<em></em>このタイプのテーブルでは、プライマリキー列、MIME タイプ列、1 つ以上の汎用列を BLOB として定義します。 + +BLOB 列内のデータの内容は、MIME タイプ列の値によって示されます。 +これにより、同じテーブルにさまざまな行タイプを格納できます。 +連絡先プロバイダの「データ」テーブル {@link android.provider.ContactsContract.Data} は、スキーマに依存しないテーブルの例です。 + + + </p> + </li> +</ul> +<!-- Designing Content URIs --> +<h2 id="ContentURI">コンテンツ URI を設計する</h2> +<p> + <strong>コンテンツ URI</strong> は、プロバイダのデータを特定する URI です。コンテンツ URI には、プロバイダ全体の識別名(<strong>認証局</strong>)とテーブルやファイルをポイントする名前(<strong>パス</strong>)が含まれます。 + +オプションの ID 部分は、テーブル内の個々の行を指します。 +{@link android.content.ContentProvider} のそれぞれのデータアクセス メソッドは引数としてコンテンツ URI を使用します。これにより、アクセスするテーブル、行、ファイルを決定できます。 + + +</p> +<p> + コンテンツ URI の基本については、「<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">コンテンツ プロバイダの基本</a>」トピックをご覧ください。 + + +</p> +<h3>認証局を設計する</h3> +<p> + 通常、プロバイダは、Android 内部の名前として使用される認証局を 1 つ持ちます。他のプロバイダとの競合を避けるためには、(逆に)プロバイダの認証局の基礎としてインターネット ドメインの所有権を使用する必要があります。 + +この推奨事項は Android パッケージ名にもあてはまるため、プロバイダを含むパッケージの名前の拡張子として、プロバイダの認証局を定義できます。 + +たとえば、Android パッケージ名が <code>com.example.<appname></code> の場合、プロバイダに認証局 <code>com.example.<appname>.provider</code> を付与する必要があります。 + + +</p> +<h3>パス構造を設計する</h3> +<p> + デベロッパーは通常、個々のテーブルを指すパスを末尾に追加して認証局からコンテンツ URI を作成します。 +たとえば、<em>table1</em> と <em>table2</em> の 2 つのテーブルがある場合、前の例の認証局を組み合わせてコンテンツ URI <code>com.example.<appname>.provider/table1</code> と <code>com.example.<appname>.provider/table2</code> を作成します。 + + + +パスは 1 つのセグメントに限定されず、パスの各レベルにテーブルを作成する必要はありません。 + +</p> +<h3>コンテンツ URI ID を処理する</h3> +<p> + 慣例として、URI の末尾にある行の ID 値を持つコンテンツ URI を受け取ることで、プロバイダはテーブル内の 1 つの行へのアクセスを提供します。さらに、慣例として、プロバイダは ID 値をテーブルの <code>_ID</code> 列とマッチングし、一致する行に対して要求されたアクセスを実行します。 + + + +</p> +<p> + この慣例により、プロバイダにアクセスするアプリの一般的なパターンを簡単に設計できます。アプリはプロバイダにクエリを実行し、{@link android.widget.CursorAdapter} を使用して、取得した {@link android.database.Cursor} を {@link android.widget.ListView} に表示します。 + + + {@link android.widget.CursorAdapter} の定義には、{@link android.database.Cursor} のいずれかの列を <code>_ID</code> に設定する必要があります + +</p> +<p> + その後、ユーザーはデータの確認や修正のために、表示された行のいずれかを UI から選択します。 +アプリは {@link android.widget.ListView} を返す {@link android.database.Cursor} から対応する行を取得し、この行の <code>_ID</code> 値を取得し、その値をコンテンツ URI の末尾に追加して、プロバイダにアクセス要求を送ります。 + +その後、プロバイダは、ユーザーが選択した行にクエリや修正を実行します。 + +</p> +<h3>コンテンツ URI パターン</h3> +<p> + 受け取ったコンテンツ URI に対するアクションを簡単に選択できるように、プロバイダ API には {@link android.content.UriMatcher} という便利なクラスが用意されています。このクラスはコンテンツ URI 「パターン」を正数値にマッピングします。 + +この正数値を <code>switch</code> 文で使用することで、特定のパターンに一致する 1 つ以上のコンテンツ URI に目的のアクションを選択できます。 + +</p> +<p> + コンテンツ URI パターンは、次のワイルドカード文字を使用するコンテンツ URI に一致します。 +</p> + <ul> + <li> + <strong><code>*</code>:</strong> 任意の長さの任意の有効な文字で構成される文字列に一致します。 + </li> + <li> + <strong><code>#</code>:</strong> 任意の長さの任意の数字で構成される文字列に一致します。 + </li> + </ul> +<p> + コンテンツ URI 処理の設計とコーディングの例として、テーブルを指す次のコンテンツ URI を認識する認証局 <code>com.example.app.provider</code> を持つプロバイダを考えてみます。 + + +</p> +<ul> + <li> + <code>content://com.example.app.provider/table1</code>: <code>table1</code> という名前のテーブル。 + </li> + <li> + <code>content://com.example.app.provider/table2/dataset1</code>: <code>dataset1</code> という名前のテーブル。 + + </li> + <li> + <code>content://com.example.app.provider/table2/dataset2</code>: <code>dataset2</code> という名前のテーブル。 + + </li> + <li> + <code>content://com.example.app.provider/table3</code>: <code>table3</code> という名前のテーブル。 + </li> +</ul> +<p> + さらに、行 ID が末尾に追加されていると、プロバイダではこれらのコンテンツ URI が認識されます。たとえば、<code>table3</code> の <code>1</code> で特定される行は <code>content://com.example.app.provider/table3/1</code> になります。 + + +</p> +<p> + 次のようなコンテンツ URI パターンを使用できます。 +</p> +<dl> + <dt> + <code>content://com.example.app.provider/*</code> + </dt> + <dd> + プロバイダの任意のコンテンツ URI に一致します。 + </dd> + <dt> + <code>content://com.example.app.provider/table2/*</code>: + </dt> + <dd> + テーブル <code>dataset1</code> と <code>dataset2</code> のコンテンツ URI に一致しますが、<code>table1</code> や <code>table3</code> のコンテンツ URI には一致しません。 + + + </dd> + <dt> + <code>content://com.example.app.provider/table3/#</code>: <code>table3</code> の 1 つの行のコンテンツ URI に一致します。<code>6</code> で特定される行は <code>content://com.example.app.provider/table3/6</code> になります。 + + + + </dt> +</dl> +<p> + 次のコード スニペットでは、{@link android.content.UriMatcher} のメソッドが機能する仕組みを示します。 + このコードでは、テーブルにコンテンツ URI パターン <code>content://<authority>/<path></code> を使用し、1 つの行に <code>content://<authority>/<path>/<id></code> を使用することで、表全体の URI と 1 つの行の URI を異なる方法で処理します。 + + + +</p> +<p> + メソッド {@link android.content.UriMatcher#addURI(String, String, int) addURI()} は認証局とパスを正数値にマッピングします。 +メソッド {@link android.content.UriMatcher#match(Uri) + match()} は URI に正数値を返します。次のように、<code>switch</code> 文によって、クエリをテーブル全体に実行するか、1 つのレコードに実行するかが決まります。 + +</p> +<pre class="prettyprint"> +public class ExampleProvider extends ContentProvider { +... + // Creates a UriMatcher object. + private static final UriMatcher sUriMatcher; +... + /* + * The calls to addURI() go here, for all of the content URI patterns that the provider + * should recognize. For this snippet, only the calls for table 3 are shown. + */ +... + /* + * Sets the integer value for multiple rows in table 3 to 1. Notice that no wildcard is used + * in the path + */ + sUriMatcher.addURI("com.example.app.provider", "table3", 1); + + /* + * Sets the code for a single row to 2. In this case, the "#" wildcard is + * used. "content://com.example.app.provider/table3/3" matches, but + * "content://com.example.app.provider/table3 doesn't. + */ + sUriMatcher.addURI("com.example.app.provider", "table3/#", 2); +... + // Implements ContentProvider.query() + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, + String sortOrder) { +... + /* + * Choose the table to query and a sort order based on the code returned for the incoming + * URI. Here, too, only the statements for table 3 are shown. + */ + switch (sUriMatcher.match(uri)) { + + + // If the incoming URI was for all of table3 + case 1: + + if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC"; + break; + + // If the incoming URI was for a single row + case 2: + + /* + * Because this URI was for a single row, the _ID value part is + * present. Get the last path segment from the URI; this is the _ID value. + * Then, append the value to the WHERE clause for the query + */ + selection = selection + "_ID = " uri.getLastPathSegment(); + break; + + default: + ... + // If the URI is not recognized, you should do some error handling here. + } + // call the code to actually do the query + } +</pre> +<p> + 別の {@link android.content.ContentUris} には、コンテンツ URI の一部である <code>id</code> で作業するための便利なメソッドが備わっています。 +クラス {@link android.net.Uri} と {@link android.net.Uri.Builder} には、既存の {@link android.net.Uri} オブジェクトを解析して新しいオブジェクトをビルドするための便利なメソッドがあります。 + + +</p> + +<!-- Implementing the ContentProvider class --> +<h2 id="ContentProvider">ContentProvider クラスを実装する</h2> +<p> + {@link android.content.ContentProvider} インスタンスは、他のアプリケーションからの要求を処理することで、一連の構造化されたデータへのアクセスを管理します。 +どのような形式でアクセスする場合も、最終的には {@link android.content.ContentResolver} が呼び出されます。その後 {@link android.content.ContentProvider} の具象メソッドが呼び出され、アクセスを取得します。 + + +</p> +<h3 id="RequiredAccess">必須メソッド</h3> +<p> + 抽象クラス {@link android.content.ContentProvider} は 6 つの抽象メソッドを定義しますが、これらのメソッドは独自の具象サブクラスの一部として実装する必要があります。 +次のように、{@link android.content.ContentProvider#onCreate() onCreate()} を除くこれらのメソッドは、コンテンツ プロバイダへのアクセスを試みるクライアント アプリケーションによって呼び出されます。 + + +</p> +<dl> + <dt> + {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) + query()} + </dt> + <dd> + プロバイダからデータを取得します。引数を使って、クエリを実行するテーブル、返す行と列、結果の並び順を選択します。 + + データは {@link android.database.Cursor} オブジェクトとして返されます。 + </dd> + <dt> + {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} + </dt> + <dd> + プロバイダに新しい行を挿入します。引数を使って、挿入先のテーブルを選択し、使用する列の値を取得します。 +新たに挿入した行のコンテンツ URI が返されます。 + + </dd> + <dt> + {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[]) + update()} + </dt> + <dd> + プロバイダ内の既存の行を更新します。引数を使って、更新するテーブルと行を選び、更新された列の値を取得します。 +更新された行の数が返されます。 + </dd> + <dt> + {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} + </dt> + <dd> + プロバイダから行を削除します。引数を使って、削除するテーブルと行を選びます。 +削除された行の数が返されます。 + </dd> + <dt> + {@link android.content.ContentProvider#getType(Uri) getType()} + </dt> + <dd> + コンテンツ URI に対応する MIME タイプを返します。このメソッドの詳細は、<a href="#MIMETypes">コンテンツ プロバイダ MIME を実装する</a>セクションをご覧ください。 + + </dd> + <dt> + {@link android.content.ContentProvider#onCreate() onCreate()} + </dt> + <dd> + プロバイダを初期化します。プロバイダが作成されると、Android システムがこのメソッドを即座に呼び出します。 +{@link android.content.ContentResolver} オブジェクトがアクセスを試みるまでは、プロバイダは作成されません。 + + </dd> +</dl> +<p> + これらのメソッドが持つ署名は、同じ名前の {@link android.content.ContentResolver} メソッドの署名と同じになります。 + +</p> +<p> + これらのメソッドを実装する場合は、次の点を考慮する必要があります。 +</p> +<ul> + <li> + {@link android.content.ContentProvider#onCreate() onCreate()} を除くこれらのすべてのメソッドは、複数のスレッドを使用して同時に呼び出すことができるため、スレッドに対応した設定にする必要があります。 +複数のスレッドの詳細は、<a href="{@docRoot}guide/components/processes-and-threads.html">プロセスとスレッド</a>をご覧ください。 + + + + </li> + <li> + {@link android.content.ContentProvider#onCreate() + onCreate()} では冗長な操作は行わないようにします。本当に必要になるまでは、タスクの初期化は行わないようにします。 + 詳細は、<a href="#OnCreate">onCreate() メソッドを実装する</a>をご覧ください。 + + </li> + <li> + これのメソッドの実装は必須ですが、コードでは予測されたデータタイプを返す以外の操作は必要ありません。 +たとえば、他のアプリケーションが一部のテーブルにデータを挿入できないように設定するとします。 +その場合、{@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} への呼び出しを無視して 0 を返します。 + + + </li> +</ul> +<h3 id="Query">query() メソッドを実装する</h3> +<p> + {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) + ContentProvider.query()} メソッドは {@link android.database.Cursor} オブジェクトを返す必要があります。失敗した場合は、{@link java.lang.Exception} をスローします。 + +SQLite データベースをデータストレージとして使用する場合は、{@link android.database.sqlite.SQLiteDatabase} クラスのいずれかの <code>query()</code> メソッドが返す {@link android.database.Cursor} を返します。 + + + クエリがどの行にも一致しない場合は、{@link android.database.Cursor#getCount()} メソッドが 0 を返す {@link android.database.Cursor} インスタンスを返す必要があります。 + + クエリプロセス中にエラーが発生した場合にのみ <code>null</code> を返します。 +</p> +<p> + SQLite データベースをデータストレージとして使用しない場合は、{@link android.database.Cursor} クラスのいずれかの具象サブクラスを使用します。 +たとえば、{@link android.database.MatrixCursor} クラスは、各行が {@link java.lang.Object} の配列となるカーソルを実装します。 +このクラスでは、{@link android.database.MatrixCursor#addRow(Object[]) addRow()} を使って新しい行を追加します。 + +</p> +<p> + Android システムは、プロセスの境界をまたいで {@link java.lang.Exception} を送信できるように設定する必要があることにご注意ください。 +Android では、クエリエラーを処理するのに便利な、次の例外を送信できます。 + +</p> +<ul> + <li> + {@link java.lang.IllegalArgumentException}(プロバイダが無効なコンテンツ URI を受け取った場合にこの例外をスローするように選択できます) + + </li> + <li> + {@link java.lang.NullPointerException} + </li> +</ul> +<h3 id="Insert">insert() メソッドを実装する</h3> +<p> + {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} メソッドは、{@link android.content.ContentValues} 引数の値を使用して、適切なテーブルに新しい行を追加します。 + +列名が {@link android.content.ContentValues} 引数にない場合は、プロバイダ コードがデータベース スキーマのいずれかで、デフォルト値を設定できます。 + + +</p> +<p> + このメソッドは新しい行のコンテンツ URI を返します。作成するには、{@link android.content.ContentUris#withAppendedId(Uri, long) withAppendedId()} を使用して、新しい行の <code>_ID</code>(または他のプライマリキー)の値をテーブルのコンテンツ URI の末尾に追加します。 + + +</p> +<h3 id="Delete">delete() メソッドを実装する</h3> +<p> + {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} メソッドでは、データストレージから行を物理的に削除する必要はありません。 +プロバイダで同期アダプタを使用する場合は、行全体を削除するのではなく、削除された行に「削除」フラグを付けるようにします。 + +同期アダプタは削除された行を探して、プロバイダから削除される前に、サーバーから行を削除できます。 + +</p> +<h3 id="Update">update() メソッドを実装する</h3> +<p> + {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[]) + update()} メソッドは {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} が使用するのと同じ {@link android.content.ContentValues} 引数、{@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} と {@link android.content.ContentProvider#query(Uri, String[], String, String[], String) + ContentProvider.query()} が使用するのと同じ <code>selection</code> と <code>selectionArgs</code> 引数を使用します。 + + + +これにより、これらのメソッド間でコードを再利用できます。 +</p> +<h3 id="OnCreate">onCreate() メソッドを実装する</h3> +<p> + Android システムはプロバイダを起動する際に {@link android.content.ContentProvider#onCreate() + onCreate()} を呼び出します。このメソッドでは迅速に実行できる初期化タスクのみを実行するようにし、プロバイダが実際にデータの要求を受け取るまでは、データベースの作成とデータロードを保留します。 + +{@link android.content.ContentProvider#onCreate() onCreate()} で冗長なタスクを行う場合は、プロバイダの起動が遅くなります。 + +同様に、プロバイダから他のアプリケーションへの応答も遅くなります。 + +</p> +<p> + たとえば、SQLite データベースを使用すると、{@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} に {@link android.database.sqlite.SQLiteOpenHelper} オブジェクトを作成し、データベースを初めて開くときに SQL テーブルを作成できます。 + + +この操作を簡単にするために、{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase + getWritableDatabase()} を初めて呼び出すときには、{@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) + SQLiteOpenHelper.onCreate()} メソッドが自動的に呼び出されます。 + + +</p> +<p> + 次の 2 つのスニペットは、{@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} と {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) + SQLiteOpenHelper.onCreate()} との間のやり取りを表しています。 + +最初のスニペットは {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} の実装です。 + +</p> +<pre class="prettyprint"> +public class ExampleProvider extends ContentProvider + + /* + * Defines a handle to the database helper object. The MainDatabaseHelper class is defined + * in a following snippet. + */ + private MainDatabaseHelper mOpenHelper; + + // Defines the database name + private static final String DBNAME = "mydb"; + + // Holds the database object + private SQLiteDatabase db; + + public boolean onCreate() { + + /* + * Creates a new helper object. This method always returns quickly. + * Notice that the database itself isn't created or opened + * until SQLiteOpenHelper.getWritableDatabase is called + */ + mOpenHelper = new MainDatabaseHelper( + getContext(), // the application context + DBNAME, // the name of the database) + null, // uses the default SQLite cursor + 1 // the version number + ); + + return true; + } + + ... + + // Implements the provider's insert method + public Cursor insert(Uri uri, ContentValues values) { + // Insert code here to determine which table to open, handle error-checking, and so forth + + ... + + /* + * Gets a writeable database. This will trigger its creation if it doesn't already exist. + * + */ + db = mOpenHelper.getWritableDatabase(); + } +} +</pre> +<p> + 次のスニペットは {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase) + SQLiteOpenHelper.onCreate()} の実装であり、ヘルパークラスを含みます。 + +</p> +<pre class="prettyprint"> +... +// A string that defines the SQL statement for creating a table +private static final String SQL_CREATE_MAIN = "CREATE TABLE " + + "main " + // Table's name + "(" + // The columns in the table + " _ID INTEGER PRIMARY KEY, " + + " WORD TEXT" + " FREQUENCY INTEGER " + + " LOCALE TEXT )"; +... +/** + * Helper class that actually creates and manages the provider's underlying data repository. + */ +protected static final class MainDatabaseHelper extends SQLiteOpenHelper { + + /* + * Instantiates an open helper for the provider's SQLite data repository + * Do not do database creation and upgrade here. + */ + MainDatabaseHelper(Context context) { + super(context, DBNAME, null, 1); + } + + /* + * Creates the data repository. This is called when the provider attempts to open the + * repository and SQLite reports that it doesn't exist. + */ + public void onCreate(SQLiteDatabase db) { + + // Creates the main table + db.execSQL(SQL_CREATE_MAIN); + } +} +</pre> + + +<!-- Implementing ContentProvider MIME Types --> +<h2 id="MIMETypes">ContentProvider MIME タイプを実装する</h2> +<p> + {@link android.content.ContentProvider} クラスには、MIME タイプを返すための次の 2 つのクラスがあります。 +</p> +<dl> + <dt> + {@link android.content.ContentProvider#getType(Uri) getType()} + </dt> + <dd> + 任意のプロバイダに実装する必要がある必須メソッドの 1 つです。 + </dd> + <dt> + {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()} + </dt> + <dd> + ファイルを提供するプロバイダの場合に、実装が考えられるメソッドです。 + </dd> +</dl> +<h3 id="TableMIMETypes">テーブルの MIME タイプ</h3> +<p> + {@link android.content.ContentProvider#getType(Uri) getType()} メソッドは、MIME 形式で {@link java.lang.String} を返します。これは、コンテンツ URI 引数によって返されるデータのタイプを表します。 + +{@link android.net.Uri} 引数には特定の URI ではなくパターンを指定することもできます。この場合、パターンに一致するコンテンツ URI に関連付けられているデータのタイプを返します。 + + +</p> +<p> + テキスト、HTML、JPEG といった一般的なタイプのデータの場合、{@link android.content.ContentProvider#getType(Uri) getType()} では該当するデータの標準的な MIME タイプを返す必要があります。 + +利用できるこれらの標準的なタイプの詳細なリストは、「<a href="http://www.iana.org/assignments/media-types/index.htm">IANA MIME Media Types</a>」のウェブサイトをご覧ください。 + + +</p> +<p> + テーブル データの 1 つ以上の行を指すコンテンツ URI の場合、{@link android.content.ContentProvider#getType(Uri) getType()} は、Android のベンダー固有の MIME 形式で MIME タイプを返す必要があります。 + + +</p> +<ul> + <li> + タイプ部分: <code>vnd</code> + </li> + <li> + サブタイプ部分: + <ul> + <li> + URI パターンが 1 つの行の場合: <code>android.cursor.<strong>item</strong>/</code> + </li> + <li> + URI パターンが複数の行の場合: <code>android.cursor.<strong>dir</strong>/</code> + </li> + </ul> + </li> + <li> + プロバイダ固有の部分: <code>vnd.<name></code>.<code><type></code> + <p> + <code><name></code> と <code><type></code> を指定します。 + <code><name></code> の値はグローバルに一意の値とし、<code><type></code> の値は対応する URI パターンに一意のものとする必要があります。 + +<code><name></code> には、企業名や、アプリケーションの Android パッケージ名の一部を使うことをお勧めします。 +<code><type></code> には、URI に関連付けられているテーブルを特定する文字列を使うことをお勧めします。 + + + </p> + + </li> +</ul> +<p> + たとえば、プロバイダの認証局が <code>com.example.app.provider</code> の場合、テーブル名は <code>table1</code> となり、<code>table1</code> の複数行の MIME タイプは次のようになります。 + + +</p> +<pre> +vnd.android.cursor.<strong>dir</strong>/vnd.com.example.provider.table1 +</pre> +<p> + <code>table1</code> の 1 つの行の場合は、MIME タイプは次のようになります。 +</p> +<pre> +vnd.android.cursor.<strong>item</strong>/vnd.com.example.provider.table1 +</pre> +<h3 id="FileMIMETypes">ファイルの MIME タイプ</h3> +<p> + ファイルを提供するプロバイダの場合は、{@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()} を実装します。 + + このメソッドは、プロバイダが特定のコンテンツ URI に対して返すことができるファイルの MIME タイプの {@link java.lang.String} 配列を返します。クライアントで処理する MIME タイプのみを返すには、MIME タイプフィルタ引数によって、提供する MIME タイプをフィルタする必要があります。 + + +</p> +<p> + たとえば、写真画像を <code>.jpg</code>、<code>.png</code>、<code>.gif</code> 形式で提供するプロバイダについて考えてみます。 + + アプリケーションが {@link android.content.ContentResolver#getStreamTypes(Uri, String) + ContentResolver.getStreamTypes()} をフィルタ文字列 <code>image/*</code> (何らかの形式の「画像」)で呼び出す場合、{@link android.content.ContentProvider#getStreamTypes(Uri, String) + ContentProvider.getStreamTypes()} メソッドは次のような配列を返します。 + + +</p> +<pre> +{ "image/jpeg", "image/png", "image/gif"} +</pre> +<p> + アプリの対象が <code>.jpg</code> ファイルのみであり、アプリが {@link android.content.ContentResolver#getStreamTypes(Uri, String) + ContentResolver.getStreamTypes()} をフィルタ文字列 <code>*\/jpeg</code> で呼び出す場合、{@link android.content.ContentProvider#getStreamTypes(Uri, String) + ContentProvider.getStreamTypes()} は次の項目を返します。 + + +<pre> +{"image/jpeg"} +</pre> +<p> + プロバイダが、フィルタ文字列で要求した MIME タイプを提供していない場合、{@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()} は <code>null</code> を返します。 + + +</p> + + +<!-- Implementing a Contract Class --> +<h2 id="ContractClass">コントラクト クラスを実装する</h2> +<p> + コントラクト クラスは <code>public final</code> クラスであり、URI、列名、MIME タイプ、プロバイダに関連するその他のメタデータを含みます。 +このクラスは、URI や列名などの実際の値が変更された場合にも、プロバイダに正しくアクセスできることを保証することで、プロバイダとその他のアプリケーションとの間にコントラクトを構築します。 + + + +</p> +<p> + さらに、通常、コントラクト クラスではその定数にニーモニック名が設定されているため、デベロッパーが列名や URI に誤った値を使用しにくいようになっています。 +クラスであるため、Javadoc ドキュメントを含めることができます。 +Eclipse などの統合型開発環境では、コントラクト クラスから定数名が自動的に設定され、定数の Javadoc が表示されます。 + + +</p> +<p> + デベロッパーはアプリケーションからコントラクト クラスのクラスファイルにアクセスできませんが、提供する <code>.jar</code> ファイルからクラスファイルをアプリケーションに静的にコンパイルできます。 + +</p> +<p> + {@link android.provider.ContactsContract} クラスとそのネストされたクラスは、コントラクト クラスの例です。 + +</p> +<h2 id="Permissions">コンテンツ プロバイダ パーミッションを実装する</h2> +<p> + Android システムのあらゆる領域に対するパーミッションとクラスについては、「<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>」トピックをご覧ください。 + + また、トピック「<a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>」にも、ストレージのさまざまなタイプに有効なセキュリティとパーミッションについて記載されています。 + + 重要な点をまとめると次のようになります。 +</p> +<ul> + <li> + デフォルトでは、端末の内部ストレージに格納されるデータファイルは、アプリケーションとプロバイダでのみ使用できます。 + + </li> + <li> + 作成する {@link android.database.sqlite.SQLiteDatabase} データベースは、自分のアプリケーションとプロバイダにのみ公開されます。 + + </li> + <li> + デフォルトでは、外部ストレージに保存するデータファイルはパブリックとなり、誰もが読み取ることができます。<em></em><em></em> +他のアプリケーションは別の API 呼び出しを使用してファイルの読み取りと書き込みを実行できるため、コンテンツ プロバイダで外部ストレージにあるファイルへのアクセスは制限できません。 + + </li> + <li> + 端末の内部ストレージにあるファイルや SQLite データベースを開いたり作成したりするメソッド呼び出しは、他のすべてのアプリケーションに読み取りと書き込みの両方のアクセスを付与してしまう可能性があります。 +内部ファイルやデータベースをプロバイダのリポジトリとして使用する場合に、「誰でも読み取り可能」や「誰でも書き込み可能」なアクセスを付与してしまうと、マニフェストで設定したプロバイダのパーミッションでデータを保護できなくなってしまいます。 + + +内部ストレージのファイルとデータベースへのデフォルトのアクセスは「プライベート」になっているため、プロバイダのリポジトリの場合はこの設定を変更しないでください。 + + </li> +</ul> +<p> + コンテンツ プロバイダ パーミッションを使用してデータへのアクセスを制御する場合は、内部ファイル、SQLite データベース、「クラウド」(リモート サーバーなど)にデータを格納し、ファイルやデータベースを自分のアプリケーションにのみ公開するように設定します。 + + +</p> +<h3>パーミッションを実装する</h3> +<p> + デフォルトではプロバイダにはパーミッションが設定されていないため、基礎となるデータがプライベートに設定されている場合でも、すべてのアプリケーションは自分のプロバイダからの読み取りとプロバイダへの書き込みを実行できます。 +これを変更するには、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素の属性や子要素を使用して、マニフェスト ファイルでプロバイダのパーミッションを設定します。 + +プロバイダ全体に適用するパーミッションを設定することもできますし、特定のテーブル、特定のレコード、これら 3 つすべてに適用するパーミッションを設定することもできます。 + +</p> +<p> + マニフェスト ファイルで 1 つ以上の <code><a href="{@docRoot}guide/topics/manifest/permission-element.html"> + <permission></a></code> 要素を使用して、プロバイダのパーミッションを定義します。 +自分のプロバイダに独自のパーミッションを作成するには、<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#nm"> + android:name</a></code> 属性に Java スタイルのスコーピングを使用します + +たとえば、読み取りパーミッションの名前を <code>com.example.app.provider.permission.READ_PROVIDER</code> とします。 + + +</p> +<p> + 次のリストは、プロバイダ パーミッションの範囲を示しています。プロバイダ全体に適用するパーミッションから始まり、より詳細な範囲のものになっています。 + + より広い範囲を持つパーミッションよりも、範囲が限定されるパーミッションの方が優先されます。 +</p> +<dl> + <dt> + プロバイダ レベルで 1 つの読み取りと書き込みのパーミッション + </dt> + <dd> + 1 つのパーミッションでプロバイダ全体の読み取りと書き込みのアクセスの両方を制御します。<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> + android:permission</a></code> 属性で指定します。 + + + </dd> + <dt> + プロバイダ レベルで別々の読み取りと書き込みパーミッション + </dt> + <dd> + プロバイダ全体の読み取りパーミッションと書き込みパーミッションです。これらのパーミッションは <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn"> + android:readPermission</a></code> 属性と <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn"> + android:writePermission</a></code> 属性で指定します。 + + +これらは、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> + android:permission</a></code> で要求するパーミッションよりも優先されます。 + + </dd> + <dt> + パスレベルのパーミッション + </dt> + <dd> + プロバイダのコンテンツ URI の読み取り、書き込み、読み取り / 書き込みパーミッションです。<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html"> + <path-permission></a></code> 子要素を使用して、制御対象の各 URI を指定します。 + + +指定する各コンテンツ URI に対して、読み取り / 書き込みパーミッション、読み取りパーミッション、書き込みパーミッション、3 つすべてを指定できます。 +読み取りパーミッションと書き込みパーミッションは、読み取り / 書き込みパーミッションに優先します。 +また、パスレベルのパーミッションはプロバイダ レベルのパーミッションに優先します。 + + </dd> + <dt> + 一時的なパーミッション + </dt> + <dd> + アプリケーションへの一時的なアクセスを付与するパーミッション レベルです。アプリケーションに通常必要とするパーミッションが付与されていない場合でも付与できます。 +一時的なアクセス機能により、アプリケーションのマニフェストに必要なパーミッションの数を減らせます。 + +一時的なパーミッションを有効にすると、プロバイダへの「永続的な」パーミッションを必要とするアプリケーションのみが、継続的にすべてのデータにアクセスできます。 + + + <p> + プロバイダからの写真の添付ファイルを外部の画像ビューワ アプリケーションで表示する場合に、メール プロバイダとアプリに実装するパーミッションを考えてみます。 + +パーミッションを要求しなくても、画像ビューワに必要なアクセスを付与するには、写真のコンテンツ URI に一時的なパーミッションを設定します。 +ユーザーが写真を表示しようとしたときに、アプリから写真のコンテンツ URI とパーミッション フラグを含むインテントを画像ビューワに送信するようにメール アプリを設計します。 + +ビューワにプロバイダの通常の読み取りパーミッションが付与されていない場合でも、画像ビューワはメール プロバイダにクエリを実行して写真を取得します。 + + + </p> + <p> + 一時的なパーミッションを有効にするには、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> + android:grantUriPermissions</a></code> 属性を設定するか、1 つ以上の <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"> + <grant-uri-permission></a></code> 子要素を <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素に追加します。 + + + +一時的なパーミッションを使用する場合、プロバイダからのコンテンツ URI のサポートを削除したときは常に {@link android.content.Context#revokeUriPermission(Uri, int) + Context.revokeUriPermission()} を呼び出す必要があります。そうすると、コンテンツ URI が一時的なパーミッションに関連付けられます。 + + + </p> + <p> + 属性の値によって、プロバイダへのアクセスレベルが決まります。 + 属性を <code>true</code> に設定すると、システムによってプロバイダ全体への一時的なパーミッションが付与されます。このパーミッションは、プロバイダ レベルやパスレベルのパーミッションで必要になるその他のパーミッションよりも優先されます。 + + + </p> + <p> + このフラグを <code>false</code> に設定する場合は、<code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html"> + <grant-uri-permission></a></code> 子要素を <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素に追加する必要があります。 + +それぞれの子要素は、一時的なアクセスが付与される 1 つ以上のコンテンツ URI を指定します。 + + </p> + <p> + 一時的なアクセスをアプリケーションに委任するには、インテントに {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} フラグか {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} フラグ、またはその両方を含める必要があります。 + +これらは、{@link android.content.Intent#setFlags(int) setFlags()} メソッドで設定します。 + + </p> + <p> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> + android:grantUriPermissions</a></code> 属性がない場合は、<code>false</code> であると仮定されます。 + + </p> + </dd> +</dl> + + + +<!-- The Provider Element --> +<h2 id="ProviderElement"><provider> 要素</h2> +<p> + {@link android.app.Activity} コンポーネントや {@link android.app.Service} コンポーネントと同様に、<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素を使用して {@link android.content.ContentProvider} のサブクラスをアプリケーションのマニフェスト ファイルに定義する必要があります。 + + +Android システムは要素から次の情報を取得します。 + +<dl> + <dt> + 認証局(<a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">{@code + android:authorities}</a>) + + </dt> + <dd> + システム内のプロバイダ全体を特定する識別名です。この属性の詳細は、<a href="#ContentURI">コンテンツ URI を設計する</a>セクションをご覧ください。 + + + </dd> + <dt> + プロバイダ クラス名(<code> +<a href="{@docRoot}guide/topics/manifest/provider-element.html#nm">android:name</a> + </code>) + + </dt> + <dd> + {@link android.content.ContentProvider} を実装するクラスです。このクラスの詳細は、<a href="#ContentProvider">ContentProvider クラスを実装する</a>セクションをご覧ください。 + + + </dd> + <dt> + パーミッション + </dt> + <dd> + 他のアプリケーションがプロバイダのデータにアクセスするのに必要なパーミッションを指定する属性です。 + + <ul> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn"> + android:grantUriPermssions</a></code>: 一時的なパーミッションのフラグです。 + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn"> + android:permission</a></code>: 1 つのプロバイダ全体の読み取り / 書き込みパーミッションです。 + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn"> + android:readPermission</a></code>: プロバイダ全体の読み取りパーミッションです。 + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn"> + android:writePermission</a></code>: プロバイダ全体の書き込みパーミッションです。 + </li> + </ul> + <p> + パーミッションとそれに対応する属性の詳細は、<a href="#Permissions">コンテンツ プロバイダ パーミッションを実装する</a>セクションをご覧ください。 + + + </p> + </dd> + <dt> + 起動と制御の属性 + </dt> + <dd> + これらの属性は、Android システムの起動方法とそのタイミング、プロバイダのプロセスの特性、その他の実行時の設定を決定します。 + + <ul> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#enabled"> + android:enabled</a></code>: システムにプロバイダの起動を許可するフラグです。 + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#exported"> + android:exported</a></code>: 他のアプリケーションにこのプロバイダの使用を許可するフラグです。 + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#init"> + android:initOrder</a></code>: 同じプロセス内の他のプロバイダに対して、このプロバイダを起動する順番です。 + + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#multi"> + android:multiProcess</a></code>: システムに呼び出しクライアントと同じプロセスでのプロバイダの開始を許可するフラグです。 + + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#proc"> + android:process</a></code>: プロバイダを実行するプロセスの名前です。 + + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#sync"> + android:syncable</a></code>: プロバイダのデータをサーバー上のデータと同期することを示すフラグです。 + + </li> + </ul> + <p> + 属性に関する詳細は、開発ガイドの <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素に関するトピックに記載されています。 + + + </p> + </dd> + <dt> + 情報に関する属性 + </dt> + <dd> + プロバイダのオプションのアイコンとラベルです。 + <ul> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#icon"> + android:icon</a></code>: プロバイダのアイコンを含むドローアブル リソースです。 + [設定] > [アプリ] > [すべて] にあるアプリのリストのプロバイダラベルの横に表示されるアイコンです。<em></em><em></em><em></em> + + </li> + <li> + <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#label"> + android:label</a></code>: プロバイダ、データ、その両方を説明する、情報ラベルです。 +[設定] > [アプリ] > [すべて] にあるアプリのリストのプロバイダラベルの横に表示されるアイコンです。<em></em><em></em><em></em> + + </li> + </ul> + <p> + 属性に関する詳細は、開発ガイドの <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"> + <provider></a></code> 要素に関するトピックに記載されています。 + + </p> + </dd> +</dl> + +<!-- Intent Access --> +<h2 id="Intents">インテントとデータアクセス</h2> +<p> + {@link android.content.Intent} を使用すると、アプリケーションはコンテンツ プロバイダに間接的にアクセスできます。 + アプリケーションは、{@link android.content.ContentResolver} や {@link android.content.ContentProvider} のメソッドを呼び出しません。 +その代わりに、アクティビティを起動するインテントを送信します。これは通常、プロバイダ独自のアプリケーションの一部となっています。 +対象のアクティビティは UI のデータの取得と表示を担当します。インテントのアクションに応じて、対象のアクティビティにより、ユーザーにプロバイダのデータの修正を求めるメッセージが表示されることがあります。 + + + さらに、インテントには、対象のアクティビティが UI に表示する「エクストラ」データが含まれることがあります。ユーザーは使用前に、このデータを変更してプロバイダのデータを修正することもできます。 + + +</p> +<p> + +</p> +<p> + インテント アクセスを使用して、データの整合性を保証できます。プロバイダのデータの挿入、更新、削除は、厳格に定義されたビジネス ロジックによって規定されることがあります。 +この場合、他のアプリケーションにデータを直接修正できるように許可すると、無効なデータが発生することがあります。 + +デベロッパーがインテント アクセスを使用する場合は、すべての操作を完全に文書化します。 + コードを使用してデータを修正するよりも、独自のアプリケーションの UI を使用したインテント アクセスの方が優れている理由を説明します。 + +</p> +<p> + プロバイダのデータを修正するための受信インテントの処理は、その他のインテントの処理と同じです。 +インテントの使用についての詳細は、「<a href="{@docRoot}guide/components/intents-filters.html">インテントとインテント フィルタ</a>」をご覧ください。 + +</p> diff --git a/docs/html-intl/intl/ja/guide/topics/providers/content-providers.jd b/docs/html-intl/intl/ja/guide/topics/providers/content-providers.jd new file mode 100644 index 000000000000..918426ad1480 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/providers/content-providers.jd @@ -0,0 +1,108 @@ +page.title=コンテンツ プロバイダ +@jd:body +<div id="qv-wrapper"> +<div id="qv"> + + +<!-- In this document --> +<h2>トピック</h2> +<ol> + <li> + <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> コンテンツ プロバイダの基本</a> + + </li> + <li> + <a href="{@docRoot}guide/topics/providers/content-provider-creating.html"> コンテンツ プロバイダの作成</a> + + </li> + <li> + <a href="{@docRoot}guide/topics/providers/calendar-provider.html">カレンダー プロバイダ</a> + </li> + <li> + <a href="{@docRoot}guide/topics/providers/contacts-provider.html">連絡先プロバイダ</a> + </li> +</ol> + + <!-- Related Samples --> +<h2>関連サンプル</h2> + <ol> + <li> + <a href="{@docRoot}resources/samples/ContactManager/index.html"> Contact Manager</a> アプリケーション + + </li> + <li> + <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html"> + "Cursor (People)" + </a> + </li> + <li> + <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html"> + "Cursor (Phones)"</a> + </li> + <li> + <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html"> サンプル同期アダプタ</a> + + </li> + </ol> +</div> +</div> +<p> + コンテンツ プロバイダは、一連の構造化されたデータへのアクセスを管理します。データをカプセル化し、データ セキュリティの定義のためのメカニズムを提供します。 +コンテンツ プロバイダは、1 つのプロセス内のデータを別のプロセスで実行されているコードにつなげるための標準的なインターフェースです。 + +</p> +<p> + コンテンツ プロバイダのデータにアクセスする場合は、アプリケーションの {@link android.content.Context} の {@link android.content.ContentResolver} オブジェクトを使用し、クライアントとしてプロバイダとやり取りします。 + + + {@link android.content.ContentResolver} オブジェクトは、{@link android.content.ContentProvider} を実装するクラスのインスタンスである、プロバイダ オブジェクトとやり取りします。 +プロバイダ オブジェクトはクライアントからのデータ要求を受け取り、要求されたアクションを実行し、結果を返します。 + + +</p> +<p> + データを他のアプリケーションと共有しない場合は、独自のプロバイダを開発する必要はありません。 +ただし、独自のアプリケーションでカスタムの検索候補を提供する場合は、独自のプロバイダが必要になります。 +また、自分のアプリケーションから別のアプリケーションに複雑なデータやファイルをコピーして貼り付ける場合も、独自のプロバイダが必要になります。 + +</p> +<p> + Android 自身には、オーディオ、ビデオ、画像、個人的な連絡先情報などのデータを管理するコンテンツ プロバイダが用意されています。 +一部のプロバイダについては、<code><a href="{@docRoot}reference/android/provider/package-summary.html">android.provider</a> + </code> パッケージのリファレンスに一覧が記載されています。 + +いくつかの制限もありますが、これらのプロバイダにはすべての Android アプリケーションからアクセスできます。 + +</p><p> + コンテンツ プロバイダの詳細は、次のトピックをご覧ください。 +</p> +<dl> + <dt> + <strong><a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> コンテンツ プロバイダの基本</a></strong> + + </dt> + <dd> + データが表形式にまとめられている場合の、コンテンツ プロバイダでのデータへのアクセス方法。 + </dd> + <dt> + <strong><a href="{@docRoot}guide/topics/providers/content-provider-creating.html"> コンテンツ プロバイダの作成</a></strong> + + </dt> + <dd> + 独自のコンテンツ プロバイダの作成方法。 + </dd> + <dt> + <strong><a href="{@docRoot}guide/topics/providers/calendar-provider.html"> カレンダー プロバイダ</a></strong> + + </dt> + <dd> + Android プラットフォームの一部であるカレンダー プロバイダへのアクセス方法。 + </dd> + <dt> + <strong><a href="{@docRoot}guide/topics/providers/contacts-provider.html"> 連絡先プロバイダ</a></strong> + + </dt> + <dd> + Android プラットフォームの一部である連絡先プロバイダへのアクセス方法。 + </dd> +</dl> diff --git a/docs/html-intl/intl/ja/guide/topics/providers/document-provider.jd b/docs/html-intl/intl/ja/guide/topics/providers/document-provider.jd new file mode 100644 index 000000000000..b4342dcdd750 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/providers/document-provider.jd @@ -0,0 +1,916 @@ +page.title=ストレージ アクセス フレームワーク +@jd:body +<div id="qv-wrapper"> +<div id="qv"> + +<h2>本書の内容 + <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle"> + <span class="more">詳細を表示</span> + <span class="less" style="display:none">詳細を非表示</span></a></h2> +<ol id="toc44" class="hide-nested"> + <li> + <a href="#overview">概要</a> + </li> + <li> + <a href="#flow">コントロール フロー</a> + </li> + <li> + <a href="#client">クライアント アプリを作成する</a> + <ol> + <li><a href="#search">ドキュメントを検索する</a></li> + <li><a href="#process">プロセスの結果</a></li> + <li><a href="#metadata">ドキュメント メタデータを確認する</a></li> + <li><a href="#open">ドキュメントを開く</a></li> + <li><a href="#create">新しいドキュメントを作成する</a></li> + <li><a href="#delete">ドキュメントを削除する</a></li> + <li><a href="#edit">ドキュメントを編集する</a></li> + <li><a href="#permissions">パーミッションを固定する</a></li> + </ol> + </li> + <li><a href="#custom">カスタム ドキュメント プロバイダを作成する</a> + <ol> + <li><a href="#manifest">マニフェスト</a></li> + <li><a href="#contract">コントラクト</a></li> + <li><a href="#subclass">サブクラス DocumentsProvider</a></li> + <li><a href="#security">セキュリティ</a></li> + </ol> + </li> + +</ol> +<h2>キークラス</h2> +<ol> + <li>{@link android.provider.DocumentsProvider}</li> + <li>{@link android.provider.DocumentsContract}</li> +</ol> + +<h2>ビデオ</h2> + +<ol> + <li><a href="http://www.youtube.com/watch?v=zxHVeXbK1P4"> +DevBytes: Android 4.4 ストレージ アクセス フレームワーク: プロバイダ</a></li> + <li><a href="http://www.youtube.com/watch?v=UFj9AEz0DHQ"> +DevBytes: Android 4.4 ストレージ アクセス フレームワーク: クライアント</a></li> +</ol> + + +<h2>コードサンプル</h2> + +<ol> + <li><a href="{@docRoot}samples/StorageProvider/index.html"> +StorageProvider</a></li> + <li><a href="{@docRoot}samples/StorageClient/index.html"> +StorageClient</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ol> + <li> + <a href="{@docRoot}guide/topics/providers/content-provider-basics.html"> コンテンツ プロバイダの基本 </a> + + + </li> +</ol> + +</div> +</div> + + +<p>Android 4.4 (API レベル 19)は、ストレージ アクセス フレームワーク(SAF)を採用しています。SAF を利用することで、ユーザーは設定したドキュメント ストレージ プロバイダ全体から簡単にドキュメント、画像、その他のファイルを参照して開くことができます。 + +標準の使いやすい UI により、アプリやプロバイダを通じて一貫性のある方法でファイルを参照したり、最近使用したファイルにアクセスしたりできます。 +</p> + +<p>サービスをカプセル化する {@link android.provider.DocumentsProvider} を実装することで、クラウドやローカル ストレージ サービスをエコシステムに参加させることができます。 +プロバイダのドキュメントへのアクセスが必要なクライアントも、数行のコードだけで SAF と統合できます。 + +</p> + +<p>SAF には次の項目が含まれます。</p> + +<ul> +<li><strong>ドキュメント プロバイダ</strong>—ストレージ サービス(Google ドライブなど)が管理するファイルの表示を許可するコンテンツ プロバイダです。 +ドキュメント プロバイダは {@link android.provider.DocumentsProvider} クラスのサブクラスとして実装されます。document-provider スキーマは従来のファイル階層に基づくものですが、ドキュメント プロバイダが物理的にどのようにファイルを格納するかはその設定次第です。Android プラットフォームには、ダウンロード、画像、ビデオなどの組み込みのドキュメント プロバイダがいくつか用意されています。 + + + + +</li> + +<li><strong>クライアント アプリ</strong>—{@link android.content.Intent#ACTION_OPEN_DOCUMENT} または {@link android.content.Intent#ACTION_CREATE_DOCUMENT} インテントを呼び出し、ドキュメント プロバイダが返したファイルを受け取るカスタムアプリです。 + + +</li> + +<li><strong>ピッカー</strong>—クライアントアプリの検索条件を満たすすべてのドキュメント プロバイダのドキュメントにアクセスできるシステム UI です。 +</li> +</ul> + +<p>SAF は次のような機能も提供します。</p> +<ul> +<li>ユーザーは 1 つのアプリだけではなく、すべてのドキュメント プロバイダのコンテンツを参照できます。</li> +<li>アプリからドキュメント プロバイダが所有するドキュメントへの、長期間の固定アクセスを可能にします。 +このアクセスにより、ユーザーはプロバイダ上でのファイルの追加、編集、保存、削除が可能になります。 +</li> +<li>複数のユーザー アカウントと USB ストレージ プロバイダなどの一時的なルートをサポートします。一時的なルートはドライブを挿入した場合にのみ表示されます。 + </li> +</ul> + +<h2 id ="overview">概要</h2> + +<p>SAF は、{@link android.provider.DocumentsProvider} クラスのサブクラスであるコンテンツ プロバイダを中心に展開します。 +ドキュメント プロバイダでは、データは下図のように従来のファイル階層で構造化されます。<em></em> +</p> +<p><img src="{@docRoot}images/providers/storage_datamodel.png" alt="data model" /></p> +<p class="img-caption"><strong>図 1.</strong> ドキュメント プロバイダのデータモデル。ルートポイントが 1 つのドキュメントを指し、そこからツリー全体が広がります。 +</p> + +<p>注: </p> +<ul> + +<li>各ドキュメント プロバイダは、ドキュメントのツリーの検索の出発点である 1 つ以上の「ルート」を報告します。各ルートは一意の {@link android.provider.DocumentsContract.Root#COLUMN_ROOT_ID} を持ち、該当するルートの下のコンテンツを表すドキュメント(ディレクトリ)を指します。ルートはデザインによって動的に変化し、複数アカウント、一時的な USB ストレージ ドライブ、ユーザーのログインとログアウトなどのユースケースをサポートします。 + + + + + +</li> + +<li>各ルートの下のドキュメントは 1 つだけになります。そのドキュメントは、1 ~ <em>N</em> 個のドキュメントを指し、さらにそれぞれのドキュメントも 1 ~ <em>N</em> 個のドキュメントを指すことができます。 + </li> + +<li>各ストレージ バックエンドは、一意の {@link android.provider.DocumentsContract.Document#COLUMN_DOCUMENT_ID} を使って個々のファイルやディレクトリを参照して表示します。端末の再起動後も使用できる永続的な URI の付与に使用することから、ドキュメント ID は一意でなければならず、一度発行すると変更できません。 + + + +</li> + + +<li>ドキュメントには、開くことができるファイル(特定の MIME タイプを持つもの)か、追加のドキュメント({@link android.provider.DocumentsContract.Document#MIME_TYPE_DIR} MIME タイプを持つもの)を含むディレクトリのいずれかに設定できます。 + +</li> + +<li>各ドキュメントはさまざまな機能を持つことができ、{@link android.provider.DocumentsContract.Document#COLUMN_FLAGS COLUMN_FLAGS} を使って記述します。たとえば、{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_WRITE}、{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_DELETE}、{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_THUMBNAIL} といった機能です。同一の {@link android.provider.DocumentsContract.Document#COLUMN_DOCUMENT_ID} は複数のディレクトリに含めることができます。 + + + + + +</li> +</ul> + +<h2 id="flow">コントロール フロー</h2> +<p>前述のように、ドキュメント プロバイダのデータモデルは従来のファイル階層を基本とします。 +ただし、{@link android.provider.DocumentsProvider} API でアクセスできるのであれば、任意の方法でデータを物理的に格納できます。たとえば、データにタグベースのクラウド ストレージを使用できます。 + +</p> + +<p>図 2 の例は、写真アプリが格納されたデータに SAF を使ってアクセスする様子を表しています。 +</p> +<p><img src="{@docRoot}images/providers/storage_dataflow.png" alt="app" /></p> + +<p class="img-caption"><strong>図 2.</strong> ストレージ アクセス フレームワーク フロー</p> + +<p>注: </p> +<ul> + +<li>SAF では、プロバイダとクライアントは直接やり取りできません。 +クライアントが、ファイルを操作(ファイルの読み取り、編集、作成、削除)するためのパーミッションを要求します。 +</li> + +<li>アプリケーション(この例では写真アプリ)がインテント {@link android.content.Intent#ACTION_OPEN_DOCUMENT} または {@link android.content.Intent#ACTION_CREATE_DOCUMENT} を起動すると、やり取りが始まります。 +インテントには、基準を詳細に調整するためのフィルタが含まれる場合があります。—たとえば、「画像」の MIME タイプを持つ、開くことができるすべてのファイルを取得する、のように設定できます。 + +</li> + +<li>インテントが起動すると、システム ピッカーが登録済みの各プロバイダに移動し、一致するコンテンツのルートをユーザーに表示します。 +</li> + +<li>基礎となるドキュメント プロバイダの種類に関係なく、ドキュメントにアクセスするための標準的なインターフェースがピッカーから提供されます。 +図 2 には、Google Drive プロバイダ、USB プロバイダ、クラウド プロバイダの例を示しています。 +</li> +</ul> + +<p>図 3 は、Google Drive アカウントを選択したユーザーが画像を検索するピッカーを表しています。 +</p> + +<p><img src="{@docRoot}images/providers/storage_picker.png" width="340" alt="picker" style="border:2px solid #ddd" /></p> + +<p class="img-caption"><strong>図 3.</strong> ピッカー</p> + +<p>ユーザーが Google Drive を選択すると、図 4 のように画像が表示されます。 +この時点から、ユーザーはプロバイダとクライアント アプリがサポートするすべての操作方法を使って、画像を操作できるようになります。 + + +<p><img src="{@docRoot}images/providers/storage_photos.png" width="340" alt="picker" style="border:2px solid #ddd" /></p> + +<p class="img-caption"><strong>図 4.</strong>画像</p> + +<h2 id="client">クライアント アプリを作成する</h2> + +<p>Android 4.3 以前では、別のアプリからファイルを取得する場合、{@link android.content.Intent#ACTION_PICK} や {@link android.content.Intent#ACTION_GET_CONTENT} といったインテントを呼び出す必要があります。 + +その後ユーザーは、ファイルを選択するためのアプリを 1 つ選びます。選択されたアプリはユーザーが使用可能なファイルを参照して選択するためのユーザー インターフェースを提供する必要があります。 + + </p> + +<p>Android 4.4 以降であれば、{@link android.content.Intent#ACTION_OPEN_DOCUMENT} インテントを使用するという選択肢もあります。このインテントではシステム制御のピッカー UI が表示され、ユーザーはそこから他のアプリで利用可能なすべてのファイル参照できます。 + + +ユーザーは、この 1 つの UI から、サポートされるすべてのアプリのファイルを選択できます。 +</p> + +<p>{@link android.content.Intent#ACTION_OPEN_DOCUMENT} は、{@link android.content.Intent#ACTION_GET_CONTENT} との置き換えを意図したものではありません。どちらを使用するかは、アプリのニーズによって異なります。 + +</p> + +<ul> +<li>アプリでデータの読み取りとインポートのみを行う場合は、{@link android.content.Intent#ACTION_GET_CONTENT} を使用します。 +この方法を使用すると、アプリは、画像ファイルなどのデータのコピーをインポートします。 +</li> + +<li>アプリからドキュメント プロバイダが所有するドキュメントへの、長期間の固定アクセスを可能にするには、{@link android.content.Intent#ACTION_OPEN_DOCUMENT} を使用します。 + +ドキュメント プロバイダに格納されている画像をユーザーが編集するための、写真編集アプリなどの例が挙げられます。 + </li> + +</ul> + + +<p>ここでは、{@link android.content.Intent#ACTION_OPEN_DOCUMENT} と {@link android.content.Intent#ACTION_CREATE_DOCUMENT} インテントに基づいたクライアント アプリの作成方法について説明します。 + +</p> + + +<h3 id="search">ドキュメントを検索する</h3> + +<p> +次のスニペットでは {@link android.content.Intent#ACTION_OPEN_DOCUMENT} を使って、画像ファイルがあるドキュメント プロバイダを検索します。 + +</p> + +<pre>private static final int READ_REQUEST_CODE = 42; +... +/** + * Fires an intent to spin up the "file chooser" UI and select an image. + */ +public void performFileSearch() { + + // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file + // browser. + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + + // Filter to only show results that can be "opened", such as a + // file (as opposed to a list of contacts or timezones) + intent.addCategory(Intent.CATEGORY_OPENABLE); + + // Filter to show only images, using the image MIME data type. + // If one wanted to search for ogg vorbis files, the type would be "audio/ogg". + // To search for all documents available via installed storage providers, + // it would be "*/*". + intent.setType("image/*"); + + startActivityForResult(intent, READ_REQUEST_CODE); +}</pre> + +<p>注: </p> +<ul> +<li>アプリが {@link android.content.Intent#ACTION_OPEN_DOCUMENT} インテントを開始すると、ピッカーが起動し、条件に一致するすべてのドキュメント プロバイダが表示されます。 +</li> + +<li>カテゴリ {@link android.content.Intent#CATEGORY_OPENABLE} をインテントに追加すると、結果がフィルタリングされ、画像ファイルなどの開くことができるドキュメントのみが表示されます。 +</li> + +<li>{@code intent.setType("image/*")} 文は結果をさらにフィルタリングし、画像 MIME データタイプを持つドキュメントのみを表示します。 +</li> +</ul> + +<h3 id="results">プロセスの結果</h3> + +<p>ユーザーがピッカーでドキュメントを選択すると、{@link android.app.Activity#onActivityResult onActivityResult()} が呼び出されます。選択したドキュメントを指す URI は {@code resultData} パラメータに含まれます。 + + +{@link android.content.Intent#getData getData()} を使って URI を抽出します。URI を抽出したら、その URI を使ってユーザーが希望するドキュメントを取得できます。 +次に例を示します。 +</p> + +<pre>@Override +public void onActivityResult(int requestCode, int resultCode, + Intent resultData) { + + // The ACTION_OPEN_DOCUMENT intent was sent with the request code + // READ_REQUEST_CODE. If the request code seen here doesn't match, it's the + // response to some other intent, and the code below shouldn't run at all. + + if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) { + // The document selected by the user won't be returned in the intent. + // Instead, a URI to that document will be contained in the return intent + // provided to this method as a parameter. + // Pull that URI using resultData.getData(). + Uri uri = null; + if (resultData != null) { + uri = resultData.getData(); + Log.i(TAG, "Uri: " + uri.toString()); + showImage(uri); + } + } +} +</pre> + +<h3 id="metadata">ドキュメント メタデータを確認する</h3> + +<p>ドキュメントのURI を取得したら、そのメタデータにアクセスできます。次のスニペットは、URI で指定したドキュメントのメタデータを取得して、ログに記録します。 +</p> + +<pre>public void dumpImageMetaData(Uri uri) { + + // The query, since it only applies to a single document, will only return + // one row. There's no need to filter, sort, or select fields, since we want + // all fields for one document. + Cursor cursor = getActivity().getContentResolver() + .query(uri, null, null, null, null, null); + + try { + // moveToFirst() returns false if the cursor has 0 rows. Very handy for + // "if there's anything to look at, look at it" conditionals. + if (cursor != null && cursor.moveToFirst()) { + + // Note it's called "Display Name". This is + // provider-specific, and might not necessarily be the file name. + String displayName = cursor.getString( + cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); + Log.i(TAG, "Display Name: " + displayName); + + int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE); + // If the size is unknown, the value stored is null. But since an + // int can't be null in Java, the behavior is implementation-specific, + // which is just a fancy term for "unpredictable". So as + // a rule, check if it's null before assigning to an int. This will + // happen often: The storage API allows for remote files, whose + // size might not be locally known. + String size = null; + if (!cursor.isNull(sizeIndex)) { + // Technically the column stores an int, but cursor.getString() + // will do the conversion automatically. + size = cursor.getString(sizeIndex); + } else { + size = "Unknown"; + } + Log.i(TAG, "Size: " + size); + } + } finally { + cursor.close(); + } +} +</pre> + +<h3 id="open-client">ドキュメントを開く</h3> + +<p>ドキュメントのURI を取得したら、そのドキュメントを開いてさまざまな操作を行うことができます。 +</p> + +<h4>ビットマップ</h4> + +<p>{@link android.graphics.Bitmap} を開く方法の例を次に示します。</p> + +<pre>private Bitmap getBitmapFromUri(Uri uri) throws IOException { + ParcelFileDescriptor parcelFileDescriptor = + getContentResolver().openFileDescriptor(uri, "r"); + FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); + Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); + parcelFileDescriptor.close(); + return image; +} +</pre> + +<p>この操作を UI スレッドで実行しないでください。{@link android.os.AsyncTask} を使ってバックグラウンドで実行します。 +ビットマップを開いたら、{@link android.widget.ImageView} で表示できます。 + +</p> + +<h4>InputStream を取得する</h4> + +<p>URI から {@link java.io.InputStream} を取得する方法の例を次に示します。このスニペットでは、ファイルの行が文字列に読み込まれます。 +</p> + +<pre>private String readTextFromUri(Uri uri) throws IOException { + InputStream inputStream = getContentResolver().openInputStream(uri); + BufferedReader reader = new BufferedReader(new InputStreamReader( + inputStream)); + StringBuilder stringBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + stringBuilder.append(line); + } + fileInputStream.close(); + parcelFileDescriptor.close(); + return stringBuilder.toString(); +} +</pre> + +<h3 id="create">新しいドキュメントを作成する</h3> + +<p>{@link android.content.Intent#ACTION_CREATE_DOCUMENT} インテントを使用すると、アプリでドキュメント プロバイダに新しいドキュメントを作成できます。 + +ファイルを作成するには、インテントに MIME タイプとファイル名を渡し、一意の要求コードを使ってインテントを起動します。 +後は自分で設定します。</p> + + +<pre> +// Here are some examples of how you might call this method. +// The first parameter is the MIME type, and the second parameter is the name +// of the file you are creating: +// +// createFile("text/plain", "foobar.txt"); +// createFile("image/png", "mypicture.png"); + +// Unique request code. +private static final int WRITE_REQUEST_CODE = 43; +... +private void createFile(String mimeType, String fileName) { + Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); + + // Filter to only show results that can be "opened", such as + // a file (as opposed to a list of contacts or timezones). + intent.addCategory(Intent.CATEGORY_OPENABLE); + + // Create a file with the requested MIME type. + intent.setType(mimeType); + intent.putExtra(Intent.EXTRA_TITLE, fileName); + startActivityForResult(intent, WRITE_REQUEST_CODE); +} +</pre> + +<p>新しいドキュメントを作成したら、{@link android.app.Activity#onActivityResult onActivityResult()} で URI を取得して、ドキュメントに書き込み操作を実行できます。 + +</p> + +<h3 id="delete">ドキュメントを削除する</h3> + +<p>ドキュメントの URI と、{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_DELETE SUPPORTS_DELETE} を含むドキュメントの {@link android.provider.DocumentsContract.Document#COLUMN_FLAGS Document.COLUMN_FLAGS} を取得すると、ドキュメントを削除できます。 + + + +次に例を示します。</p> + +<pre> +DocumentsContract.deleteDocument(getContentResolver(), uri); +</pre> + +<h3 id="edit">ドキュメントを編集する</h3> + +<p>SAF を使用するとテキスト ドキュメントを直接編集できます。このスニペットは {@link android.content.Intent#ACTION_OPEN_DOCUMENT} インテントを起動し、カテゴリ {@link android.content.Intent#CATEGORY_OPENABLE} を使って、開くことができるドキュメントのみを表示します。 + + + +次のように、テキスト ファイルのみを表示するようにフィルタリングします。</p> + +<pre> +private static final int EDIT_REQUEST_CODE = 44; +/** + * Open a file for writing and append some text to it. + */ + private void editDocument() { + // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's + // file browser. + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + + // Filter to only show results that can be "opened", such as a + // file (as opposed to a list of contacts or timezones). + intent.addCategory(Intent.CATEGORY_OPENABLE); + + // Filter to show only text files. + intent.setType("text/plain"); + + startActivityForResult(intent, EDIT_REQUEST_CODE); +} +</pre> + +<p>次に、{@link android.app.Activity#onActivityResult onActivityResult()}(「<a href="#results">プロセスの結果</a>」をご覧ください)からコードを呼び出して、編集を行います。次のスニペットは {@link android.content.ContentResolver} から {@link java.io.FileOutputStream} を取得します。 + + +デフォルトでは、「書き込み」モードを使用します。必要最小限のアクセスのみを要求することをお勧めします。書き込みのみが必要な場合に読み込みと書き込みを要求しないでください。 + +</p> + +<pre>private void alterDocument(Uri uri) { + try { + ParcelFileDescriptor pfd = getActivity().getContentResolver(). + openFileDescriptor(uri, "w"); + FileOutputStream fileOutputStream = + new FileOutputStream(pfd.getFileDescriptor()); + fileOutputStream.write(("Overwritten by MyCloud at " + + System.currentTimeMillis() + "\n").getBytes()); + // Let the document provider know you're done by closing the stream. + fileOutputStream.close(); + pfd.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } +}</pre> + +<h3 id="permissions">パーミッションを固定する</h3> + +<p>アプリで読み込みや書き込み用にファイルを開くと、システムからアプリに対して、該当するファイルの URI パーミッションが付与されます。 +このパーミッションはユーザーが端末を再起動するまで有効です。ただし、画像アプリでユーザーが最近編集した 5 つの画像にアプリから直接アクセスできるようにするにはどうすればいいでしょう。ユーザーの端末が再起動されたら、ファイルを検索するためにユーザーをシステム ピッカーに戻す必要がありますが、これは明らかにいい方法とは言えません。 + + + +</p> + +<p>このような状況を避けるために、システムがアプリに付与するパーミッションを固定します。実際は、システムが提供する固定可能な URI パーミッションをアプリで「取得」します。 + +これにより、端末を再起動した場合でも、ユーザーはアプリからファイルに継続的にアクセスできます。 +</p> + + +<pre>final int takeFlags = intent.getFlags() + & (Intent.FLAG_GRANT_READ_URI_PERMISSION + | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); +// Check for the freshest data. +getContentResolver().takePersistableUriPermission(uri, takeFlags);</pre> + +<p>最後にもう 1 つ手順があります。アプリが最近アクセスした URI は、保存されていても既に無効になっている場合があります。—別のアプリによってドキュメントが削除されたり、修正されたりすることが考えられます。 + +そこで、最新のデータを確認するには、常に {@code getContentResolver().takePersistableUriPermission()} を呼び出す必要があります。 + +</p> + +<h2 id="custom">カスタム ドキュメント プロバイダを作成する</h2> + +<p> +ファイル用のストレージ サービスを提供するアプリ(クラウド保存サービスなど)を開発する場合、カスタム ドキュメント プロバイダを作成すれば、SAF を介してファイルを利用可能にできます。 + +ここではその方法について説明します。 +</p> + + +<h3 id="manifest">マニフェスト</h3> + +<p>カスタム ドキュメント プロバイダを実装するには、アプリケーションのマニフェストに次のものを追加します。 +</p> +<ul> + +<li>API レベル 19 以降のターゲット。</li> + +<li>カスタム ストレージ プロバイダを宣言する <code><provider></code> 要素。 + </li> + +<li>クラス名となる、プロバイダの名前。パッケージ名を含みます。例: <code>com.example.android.storageprovider.MyCloudProvider</code>。 +</li> + +<li>認証局の名前。これはパッケージ名(この例では <code>com.example.android.storageprovider</code>)とコンテンツ プロバイダのタイプを合わせたもの(<code>documents</code>)。 + +たとえば、{@code com.example.android.storageprovider.documents} のようになります。</li> + +<li><code>"true"</code> に設定された属性 <code>android:exported</code>。他のアプリで認識できるようにプロバイダをエクスポートする必要があります。 +</li> + +<li><code>"true"</code> に設定された属性 <code>android:grantUriPermissions</code>。 +この設定により、プロバイダのコンテンツにアクセスできるように、システムが他のアプリにアクセス権を付与します。 +特定のドキュメントへのアクセス権を固定する方法については、「<a href="#permissions">パーミッションを固定する</a>」をご覧ください。 +</li> + +<li>{@code MANAGE_DOCUMENTS} パーミッション。デフォルトでは、プロバイダはすべてのユーザーが利用可能です。 +このパーミッションを追加することで、プロバイダをシステムに制限できます。セキュリティ上この制限は重要です。 +</li> + +<li>リソース ファイルで定義したブール値に設定された {@code android:enabled} 属性。 +この属性は、Android 4.3 以前を実行する端末でプロバイダを無効にすることを目的としています。たとえば、{@code android:enabled="@bool/atLeastKitKat"} のようになります。 +マニフェストのこの属性に加え、次の操作を実行する必要があります。 + +<ul> +<li>{@code res/values/} にある {@code bool.xml} リソース ファイルに、次の行を追加します。 + <pre><bool name="atLeastKitKat">false</bool></pre></li> + +<li>{@code res/values-v19/} にある {@code bool.xml} リソース ファイルに、次の行を追加します。 + <pre><bool name="atLeastKitKat">true</bool></pre></li> +</ul></li> + +<li>{@code android.content.action.DOCUMENTS_PROVIDER} アクションを含むインテント フィルタ。システムがプロバイダを検索したときに、プロバイダがピッカーに表示されます。 + +</li> + +</ul> +<p>プロバイダを含むサンプル マニフェストの抜粋を次に示します。</p> + +<pre><manifest... > + ... + <uses-sdk + android:minSdkVersion="19" + android:targetSdkVersion="19" /> + .... + <provider + android:name="com.example.android.storageprovider.MyCloudProvider" + android:authorities="com.example.android.storageprovider.documents" + android:grantUriPermissions="true" + android:exported="true" + android:permission="android.permission.MANAGE_DOCUMENTS" + android:enabled="@bool/atLeastKitKat"> + <intent-filter> + <action android:name="android.content.action.DOCUMENTS_PROVIDER" /> + </intent-filter> + </provider> + </application> + +</manifest></pre> + +<h4 id="43">Android 4.3 以前を実行する端末をサポートする</h4> + +<p>{@link android.content.Intent#ACTION_OPEN_DOCUMENT} インテントは、Android 4.4 以降を実行する端末でのみ利用可能です。Android 4.3 以前を実行する端末に対応するためにアプリケーションで {@link android.content.Intent#ACTION_GET_CONTENT} をサポートするには、Android 4.4 以降を実行する端末のマニフェストで {@link android.content.Intent#ACTION_GET_CONTENT} インテント フィルタを無効にする必要があります。 + + + + + +ドキュメント プロバイダと {@link android.content.Intent#ACTION_GET_CONTENT} は互いに排他的な関係にあると考える必要があります。 + +両方を同時にサポートする場合、アプリはシステム ピッカー UI に 2 度表示され、格納されたデータへの 2 つの異なる方法を提供します。 + +これではユーザーも操作に迷ってしまいます。</p> + +<p>ここでは、Android バージョン 4.4 以降を実行する端末で {@link android.content.Intent#ACTION_GET_CONTENT} インテント フィルタを無効にする際に推奨される方法を紹介します。 + +</p> + +<ol> +<li>{@code res/values/} にある {@code bool.xml} リソース ファイルに、次の行を追加します。 + <pre><bool name="atMostJellyBeanMR2">true</bool></pre></li> + +<li>{@code res/values-v19/} にある {@code bool.xml} リソース ファイルに、次の行を追加します。 + <pre><bool name="atMostJellyBeanMR2">false</bool></pre></li> + +<li>4.4 (API レベル 19)以降のバージョンに対して {@link android.content.Intent#ACTION_GET_CONTENT} インテント フィルタを無効にするには、<a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">アクティビティ エイリアス</a>を追加します。 + + +次に例を示します。 + +<pre> +<!-- This activity alias is added so that GET_CONTENT intent-filter + can be disabled for builds on API level 19 and higher. --> +<activity-alias android:name="com.android.example.app.MyPicker" + android:targetActivity="com.android.example.app.MyActivity" + ... + android:enabled="@bool/atMostJellyBeanMR2"> + <intent-filter> + <action android:name="android.intent.action.GET_CONTENT" /> + <category android:name="android.intent.category.OPENABLE" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="image/*" /> + <data android:mimeType="video/*" /> + </intent-filter> +</activity-alias> +</pre> +</li> +</ol> +<h3 id="contract">コントラクト</h3> + +<p>通常、カスタム コンテンツ プロバイダを作成するときには、<a href="{@docRoot}guide/topics/providers/content-provider-creating.html#ContractClass">コンテンツ プロバイダ</a>のデベロッパー ガイドに記載があるように、コントラクト クラスを実装するタスクが必要になります。 + + +コントラクト クラスは {@code public final} クラスであり、URI、列名、MIME タイプ、プロバイダに関連するその他のメタデータを含みます。 + +コントラクト クラスは SAF によって提供されるため、独自に作成する必要はありません。 + +</p> + +<ul> + <li>{@link android.provider.DocumentsContract.Document}</li> + <li>{@link android.provider.DocumentsContract.Root}</li> +</ul> + +<p>たとえば、ドキュメント プロバイダでドキュメントやルートを照会したときには、カーソルに次のような列が返されることがあります。 +</p> + +<pre>private static final String[] DEFAULT_ROOT_PROJECTION = + new String[]{Root.COLUMN_ROOT_ID, Root.COLUMN_MIME_TYPES, + Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE, + Root.COLUMN_SUMMARY, Root.COLUMN_DOCUMENT_ID, + Root.COLUMN_AVAILABLE_BYTES,}; +private static final String[] DEFAULT_DOCUMENT_PROJECTION = new + String[]{Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE, + Document.COLUMN_DISPLAY_NAME, Document.COLUMN_LAST_MODIFIED, + Document.COLUMN_FLAGS, Document.COLUMN_SIZE,}; +</pre> + +<h3 id="subclass">サブクラス DocumentsProvider</h3> + +<p>カスタム ドキュメント プロバイダの作成の次の手順では、抽象クラス {@link android.provider.DocumentsProvider} をサブクラス化します。 +少なくとも、次のメソッドを実装する必要があります。 +</p> + +<ul> +<li>{@link android.provider.DocumentsProvider#queryRoots queryRoots()}</li> + +<li>{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()}</li> + +<li>{@link android.provider.DocumentsProvider#queryDocument queryDocument()}</li> + +<li>{@link android.provider.DocumentsProvider#openDocument openDocument()}</li> +</ul> + +<p>これらは実装する必要があるメソッドですが、これ以外にも多くのメソッドを実装できます。 +詳細については、{@link android.provider.DocumentsProvider} をご覧ください。 +</p> + +<h4 id="queryRoots">queryRoots を実装する</h4> + +<p>{@link android.provider.DocumentsProvider#queryRoots +queryRoots()} を実装すると、{@link android.provider.DocumentsContract.Root} で定義される列を使って、ドキュメント プロバイダのすべてのルート ディレクトリを指す {@link android.database.Cursor} が返されます。 + +</p> + +<p>次のスニペットの {@code projection} パラメータは、呼び出し側が取得する特定のフィールドを表します。 +スニペットは新しいカーソルを作成し、それに行を 1 つ追加します。—[ダウンロード] や [画像] と同じように、1 つのルートに対して最上位のディレクトリが 1 つになります。 + +ほとんどのプロバイダでルートは 1 つになります。複数のユーザー アカウントを使用するような場合は、1 つ以上のルートを設定できます。 +その場合、カーソルに 2 つ目の行を追加します。 +</p> + +<pre> +@Override +public Cursor queryRoots(String[] projection) throws FileNotFoundException { + + // Create a cursor with either the requested fields, or the default + // projection if "projection" is null. + final MatrixCursor result = + new MatrixCursor(resolveRootProjection(projection)); + + // If user is not logged in, return an empty root cursor. This removes our + // provider from the list entirely. + if (!isUserLoggedIn()) { + return result; + } + + // It's possible to have multiple roots (e.g. for multiple accounts in the + // same app) -- just add multiple cursor rows. + // Construct one row for a root called "MyCloud". + final MatrixCursor.RowBuilder row = result.newRow(); + row.add(Root.COLUMN_ROOT_ID, ROOT); + row.add(Root.COLUMN_SUMMARY, getContext().getString(R.string.root_summary)); + + // FLAG_SUPPORTS_CREATE means at least one directory under the root supports + // creating documents. FLAG_SUPPORTS_RECENTS means your application's most + // recently used documents will show up in the "Recents" category. + // FLAG_SUPPORTS_SEARCH allows users to search all documents the application + // shares. + row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | + Root.FLAG_SUPPORTS_RECENTS | + Root.FLAG_SUPPORTS_SEARCH); + + // COLUMN_TITLE is the root title (e.g. Gallery, Drive). + row.add(Root.COLUMN_TITLE, getContext().getString(R.string.title)); + + // This document id cannot change once it's shared. + row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(mBaseDir)); + + // The child MIME types are used to filter the roots and only present to the + // user roots that contain the desired type somewhere in their file hierarchy. + row.add(Root.COLUMN_MIME_TYPES, getChildMimeTypes(mBaseDir)); + row.add(Root.COLUMN_AVAILABLE_BYTES, mBaseDir.getFreeSpace()); + row.add(Root.COLUMN_ICON, R.drawable.ic_launcher); + + return result; +}</pre> + +<h4 id="queryChildDocuments">queryChildDocuments を実装する</h4> + +<p>{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()} を実装すると、{@link android.provider.DocumentsContract.Document} で定義される列を使って、指定したディレクトリ内のすべてのファイルを指す {@link android.database.Cursor} が返されます。 + + + +</p> + +<p>ピッカー UI でアプリケーション ルートを選択すると、このメソッドが呼び出されます。ルートの下のディレクトリの子ドキュメントを取得します。 +ルートだけでなく、ファイル階層内の任意のレベルで呼び出せます。 +このスニペットでは、要求した列を持つ新しいカーソルが作成され、親ディレクトリのすぐ下のそれぞれの子の情報がカーソルに追加されます。子は、画像、別のディレクトリなど—任意のファイルとなります。 + + +</p> + +<pre>@Override +public Cursor queryChildDocuments(String parentDocumentId, String[] projection, + String sortOrder) throws FileNotFoundException { + + final MatrixCursor result = new + MatrixCursor(resolveDocumentProjection(projection)); + final File parent = getFileForDocId(parentDocumentId); + for (File file : parent.listFiles()) { + // Adds the file's display name, MIME type, size, and so on. + includeFile(result, null, file); + } + return result; +} +</pre> + +<h4 id="queryDocument">queryDocument を実装する</h4> + +<p>{@link android.provider.DocumentsProvider#queryDocument queryDocument()} を実装すると、{@link android.provider.DocumentsContract.Document} で定義される列を使って、指定したファイルを指す {@link android.database.Cursor} が返されます。 + + + +</p> + +<p>{@link android.provider.DocumentsProvider#queryDocument queryDocument()} メソッドでは、特定のファイルの情報ではなく、{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()} に渡したのと同じ情報が返されます。 + + +</p> + + +<pre>@Override +public Cursor queryDocument(String documentId, String[] projection) throws + FileNotFoundException { + + // Create a cursor with the requested projection, or the default projection. + final MatrixCursor result = new + MatrixCursor(resolveDocumentProjection(projection)); + includeFile(result, documentId, null); + return result; +} +</pre> + +<h4 id="openDocument">openDocument を実装する</h4> + +<p>指定したファイルを表す {@link android.os.ParcelFileDescriptor} を返すには、{@link android.provider.DocumentsProvider#openDocument +openDocument()} を実装する必要があります。 +他のアプリは、返された {@link android.os.ParcelFileDescriptor} を使ってデータをストリーミングします。 +ユーザーがファイルを選択するとシステムがこのメソッドを呼び出し、クライアント アプリは {@link android.content.ContentResolver#openFileDescriptor openFileDescriptor()} を呼び出してファイルへのアクセスを要求します。次に例を示します。 + + +</p> + +<pre>@Override +public ParcelFileDescriptor openDocument(final String documentId, + final String mode, + CancellationSignal signal) throws + FileNotFoundException { + Log.v(TAG, "openDocument, mode: " + mode); + // It's OK to do network operations in this method to download the document, + // as long as you periodically check the CancellationSignal. If you have an + // extremely large file to transfer from the network, a better solution may + // be pipes or sockets (see ParcelFileDescriptor for helper methods). + + final File file = getFileForDocId(documentId); + + final boolean isWrite = (mode.indexOf('w') != -1); + if(isWrite) { + // Attach a close listener if the document is opened in write mode. + try { + Handler handler = new Handler(getContext().getMainLooper()); + return ParcelFileDescriptor.open(file, accessMode, handler, + new ParcelFileDescriptor.OnCloseListener() { + @Override + public void onClose(IOException e) { + + // Update the file with the cloud server. The client is done + // writing. + Log.i(TAG, "A file with id " + + documentId + " has been closed! + Time to " + + "update the server."); + } + + }); + } catch (IOException e) { + throw new FileNotFoundException("Failed to open document with id " + + documentId + " and mode " + mode); + } + } else { + return ParcelFileDescriptor.open(file, accessMode); + } +} +</pre> + +<h3 id="security">セキュリティ</h3> + +<p>たとえば、ドキュメント プロバイダがパスワードで保護されたクラウド ストレージ サービスであり、ファイル共有を開始する前にユーザーがログインしているかどうかを確認するとします。ユーザーがログインしていない場合、アプリはどのような動作を行う必要があるでしょうか。 + +このような場合、{@link android.provider.DocumentsProvider#queryRoots +queryRoots()} の実装のゼロルートを返すようにします。 +つまり、空のルートカーソルになります。</p> + +<pre> +public Cursor queryRoots(String[] projection) throws FileNotFoundException { +... + // If user is not logged in, return an empty root cursor. This removes our + // provider from the list entirely. + if (!isUserLoggedIn()) { + return result; +} +</pre> + +<p>その他に {@code getContentResolver().notifyChange()} を呼び出す手順もあります。{@link android.provider.DocumentsContract} については既に説明してあります。 +これを使ってこの URI を作成します。次のスニペットは、ユーザーのログイン ステータスが変わった場合に、ドキュメント プロバイダのルートを照会するようシステムに指示します。 + +ユーザーがログインしてない場合は、上述のように、{@link android.provider.DocumentsProvider#queryRoots queryRoots()} を呼び出すと空のカーソルが返されます。 + +こうすることで、ユーザーがプロバイダにログインしている場合にのみ、プロバイダのドキュメントを利用できます。 +</p> + +<pre>private void onLoginButtonClick() { + loginOrLogout(); + getContentResolver().notifyChange(DocumentsContract + .buildRootsUri(AUTHORITY), null); +} +</pre>
\ No newline at end of file diff --git a/docs/html-intl/intl/ja/guide/topics/resources/accessing-resources.jd b/docs/html-intl/intl/ja/guide/topics/resources/accessing-resources.jd new file mode 100644 index 000000000000..af8d005dac42 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/resources/accessing-resources.jd @@ -0,0 +1,337 @@ +page.title=リソースへのアクセス +parent.title=アプリケーション リソース +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>クイックビュー</h2> + <ul> + <li>リソースは、{@code R.java} の整数を使うコード({@code R.drawable.myimage} など)を使用して参照できます。 +</li> + <li>リソースは、特殊な XML 構文({@code +@drawable/myimage} など)を使用して参照できます。</li> + <li>さらに、{@link android.content.res.Resources} のメソッドを使用すると、アプリ リソースにアクセスできます。 +</li> + </ul> + + <h2>キークラス</h2> + <ol> + <li>{@link android.content.res.Resources}</li> + </ol> + + <h2>本書の内容</h2> + <ol> + <li><a href="#ResourcesFromCode">コードからリソースにアクセスする</a></li> + <li><a href="#ResourcesFromXml">XML からリソースにアクセスする</a> + <ol> + <li><a href="#ReferencesToThemeAttributes">スタイル属性を参照する</a></li> + </ol> + </li> + <li><a href="#PlatformResources">プラットフォーム リソースにアクセスする</a></li> + </ol> + + <h2>関連ドキュメント</h2> + <ol> + <li><a href="providing-resources.html">リソースの提供</a></li> + <li><a href="available-resources.html">Resource Types</a></li> + </ol> +</div> +</div> + + + + +<p>アプリケーションでリソースを提供すると(詳細は「<a href="providing-resources.html">リソースの提供</a>」)、リソース ID を参照することで適用できるようになります。リソース ID はすべてプロジェクトの {@code R} クラスで定義します。これは {@code aapt} ツールが自動的に生成します。 + +</p> + +<p>アプリケーションをコンパイルすると、{@code aapt} が {@code R} クラスを生成します。このクラスには、{@code +res/} ディレクトリに含まれるの全リソースのリソース ID が入ります。 +リソースのそれぞれのタイプに対して、{@code R} サブクラス(例: ドローアブル リソースの場合はすべて {@code R.drawable})があり、そのタイプのそれぞれのリソースには、静的整数(例: {@code R.drawable.icon})があります。 + +この整数がリソース ID であり、リソースを取得するのに使用できます。 +</p> + +<p>{@code R} クラスではリソース ID を指定されていますが、リソース ID を探す必要はありません。リソース ID は常に次のように構成されます。 +</p> +<ul> + <li><em>リソースタイプ</em>: それぞれのリソースは、{@code +string}、{@code drawable}、{@code layout} のようなタイプにグループ化されます。さまざまなタイプに関する詳細は、「<a href="available-resources.html">Resource Types</a>」をご覧ください。 + </li> + <li><em>リソース名</em>。これは、拡張子を除外したファイル名か、XML {@code android:name} 属性(リソースが文字列などの単純な値の場合)のいずれかになります。 + +</li> +</ul> + +<p>リソースにアクセスするには次の 2 つの方法があります。</p> +<ul> + <li><strong>コード内:</strong> {@code R} クラスのサブクラスから次のような静的整数を使用します。 + + <pre class="classic no-pretty-print">R.string.hello</pre> + <p>{@code string} はリソースタイプ、{@code hello} はリソース名です。多くの Android API が、リソース ID をこの形式で指定してリソースにアクセスします。 +<a href="#ResourcesFromCode">コードでリソースにアクセスする</a>をご覧ください。 +</p> + </li> + <li><strong>XML 内:</strong> {@code R} クラスで定義するリソース ID に対応する、次のような特殊な XML 構文を使用します。 + + <pre class="classic no-pretty-print">@string/hello</pre> + <p>{@code string} はリソースタイプ、{@code hello} はリソース名です。この構文は、リソースで提供する値が想定される、XML リソース内の任意の場所に使用できます。 +<a href="#ResourcesFromXml">XML からリソースにアクセスする</a>をご覧ください。</p> + </li> +</ul> + + + +<h2 id="ResourcesFromCode">コードでリソースにアクセスする </h2> + +<p>リソース ID をメソッド パラメータとして渡すことで、コード内でリソースを使用できます。たとえば、{@link android.widget.ImageView#setImageResource(int) setImageResource()} を使って、{@link android.widget.ImageView} が {@code res/drawable/myimage.png} を使用するように設定できます。 + +</p> +<pre> +ImageView imageView = (ImageView) findViewById(R.id.myimageview); +imageView.setImageResource(<strong>R.drawable.myimage</strong>); +</pre> + +<p>さらに、{@link +android.content.res.Resources} のメソッドを使用して、個々のリソースを取得することもできます。{@link android.content.Context#getResources()} を使用すると、インスタンスを取得できます。 +</p> + +<div class="sidebox-wrapper"> +<div class="sidebox"> +<h2>元のファイルへのアクセス</h2> + +<p>一般的な操作ではありませんが、元のファイルやディレクトリへのアクセスが必要になることがあります。その場合、{@code res/} からリソースを読み込むにはリソース ID が必要なため、{@code res/} にファイルを保存しても機能しません。その代わりに、{@code assets/} ディレクトリにリソースを保存します。 + + +</p> +<p>{@code assets/} ディレクトリに保存したファイルにはリソース ID が付与されないため、<em></em>{@code R} クラスや XML リソースからはそれらのファイルを参照できません。 +その代わりに、通常のファイル システムのように {@code assets/} ディレクトリ内のファイルを照会し、{@link android.content.res.AssetManager} を使用して未処理のデータを読み込みます。 + +</p> +<p>ただし、単に(ビデオやオーディオなどの)未処理データの読み込みのみが必要となる場合は、ファイルを {@code res/raw/} ディレクトリに保存し、{@link +android.content.res.Resources#openRawResource(int) openRawResource()} を使用してバイトのストリームを読み込みます。 +</p> + +</div> +</div> + + +<h3>構文</h3> + +<p>次の構文を使用して、コード内のリソースを参照します。</p> + +<pre class="classic no-pretty-print"> +[<em><package_name></em>.]R.<em><resource_type></em>.<em><resource_name></em> +</pre> + +<ul> + <li><em>{@code <package_name>}</em> は、リソースが配置されるパッケージの名前です(独自のパッケージからリソースを参照する場合は必要ありません)。 +</li> + <li><em>{@code <resource_type>}</em> は、リソースタイプの {@code R} サブクラスです。</li> + <li><em>{@code <resource_name>}</em> は、拡張子以外のリソース ファイル名か、XML 要素の {@code android:name} 属性値(単純な値の場合)のいずれかになります。 + +</li> +</ul> +<p>リソースタイプの詳細やそれらの査証方法については、「<a href="available-resources.html">Resource Types</a>」をご覧ください。 +</p> + + +<h3>使用例</h3> + +<p>多くのメソッドでリソース ID パラメータを使うことができ、{@link android.content.res.Resources} のメソッドを使用すればリソースを取得できます。 +{@link +android.content.res.Resources} のインスタンスは、{@link android.content.Context#getResources +Context.getResources()} により取得できます。</p> + + +<p>次は、コードのリソースにアクセスする例です。</p> + +<pre> +// Load a background for the current screen from a drawable resource +{@link android.app.Activity#getWindow()}.{@link +android.view.Window#setBackgroundDrawableResource(int) +setBackgroundDrawableResource}(<strong>R.drawable.my_background_image</strong>) ; + +// Set the Activity title by getting a string from the Resources object, because +// this method requires a CharSequence rather than a resource ID +{@link android.app.Activity#getWindow()}.{@link android.view.Window#setTitle(CharSequence) +setTitle}(getResources().{@link android.content.res.Resources#getText(int) +getText}(<strong>R.string.main_title</strong>)); + +// Load a custom layout for the current screen +{@link android.app.Activity#setContentView(int) +setContentView}(<strong>R.layout.main_screen</strong>); + +// Set a slide in animation by getting an Animation from the Resources object +mFlipper.{@link android.widget.ViewAnimator#setInAnimation(Animation) +setInAnimation}(AnimationUtils.loadAnimation(this, + <strong>R.anim.hyperspace_in</strong>)); + +// Set the text on a TextView object using a resource ID +TextView msgTextView = (TextView) findViewById(<strong>R.id.msg</strong>); +msgTextView.{@link android.widget.TextView#setText(int) +setText}(<strong>R.string.hello_message</strong>); +</pre> + + +<p class="caution"><strong>警告:</strong> {@code +R.java} ファイルを手動で修正しないでください。—プロジェクトがコンパイルされると、{@code aapt} ツールによって生成されます。 +変更した場合は、次回のコンパイルの際に上書きされます。</p> + + + +<h2 id="ResourcesFromXml">XML からリソースにアクセスする</h2> + +<p>一部の XML 属性や要素の値は、既存のリソースへの参照を使用して定義できます。 +通常は、ウィジェットに文字列や画像を提供するレイアウト ファイルを作成する場合に、この方法を使用します。 +</p> + +<p>たとえば、レイアウトに {@link android.widget.Button} を追加する場合は、次のように、ボタンテキストの<a href="string-resource.html">文字列リソース</a>を使用します。 +</p> + +<pre> +<Button + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="<strong>@string/submit</strong>" /> +</pre> + + +<h3>構文</h3> + +<p>次の構文を使用して、XML リソース内のリソースを参照します。</p> + +<pre class="classic no-pretty-print"> +@[<em><package_name></em>:]<em><resource_type></em>/<em><resource_name></em> +</pre> + +<ul> + <li>{@code <package_name>} は、リソースが配置されるパッケージの名前です(同一のパッケージからリソースを参照する場合は必要ありません) +</li> + <li>{@code <resource_type>} は、リソースタイプの {@code R} サブクラスです +</li> + <li>{@code <resource_name>} は、拡張子以外のリソース ファイル名か、XML 要素の {@code android:name} 属性値(単純な値の場合)のいずれかになります。 + +</li> +</ul> + +<p>リソースタイプの詳細やそれらの査証方法については、「<a href="available-resources.html">Resource Types</a>」をご覧ください。 +</p> + + +<h3>使用例</h3> + +<p>場合によっては、XML の値にリソースを使用する必要がありますが(ウィジェットにドローアブル画像を適用するような場合など)、単純な値を受け入れる XML の任意の場所にリソースを使用できます。 +たとえば、<a href="more-resources.html#Color">カラーリソース</a>と<a href="string-resource.html">文字列リソース</a>を持つ、次のようなリソースがあるとします。 +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="opaque_red">#f00</color> + <string name="hello">Hello!</string> +</resources> +</pre> + +<p>これらのリソースを次のようなレイアウト ファイルに使用して、テキストカラーとテキストの文字列を設定できます。 +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<EditText xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:textColor="<strong>@color/opaque_red</strong>" + android:text="<strong>@string/hello</strong>" /> +</pre> + +<p>この場合、リソースは独自のパッケージ内のものであることから、リソースの参照でパッケージ名を指定する必要はありません。 +システム リソースを参照するには、パッケージ名を含める必要があります。 +次に例を示します。</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<EditText xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:textColor="<strong>@android:color/secondary_text_dark</strong>" + android:text="@string/hello" /> +</pre> + +<p class="note"><strong>注:</strong> アプリケーションを他の言語にローカライズできるように、常に文字列リソースを使用するようにします。 +代替リソース(ローカライズされた文字列など)の作成方法についての詳細は、<a href="providing-resources.html#AlternativeResources">代替リソースを提供する</a>をご覧ください。 + + +アプリケーションを他の言語にローカライズするための詳細なガイドは、「<a href="localization.html">Localization</a>」をご覧ください。 +</p> + +<p>XML でリソースを使用すれば、エイリアスを作成することもできます。たとえば、別のドローアブル リソースのエイリアスとなる、次のようなドローアブル リソースを作成できます。 +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<bitmap xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/other_drawable" /> +</pre> + +<p>これは冗長のように思われますが、代替リソースを使用する場合に大変便利です。詳細は、<a href="providing-resources.html#AliasResources">エイリアス リソースを作成する</a>をご覧ください。 +</p> + + + +<h3 id="ReferencesToThemeAttributes">スタイル属性を参照する</h3> + +<p>スタイル属性リソースを使用すると、現在適用されているテーマの属性の値を参照できます。 +スタイル属性を参照すれば、ハードコードした値を指定しなくても、現在のテーマで与えられる標準的なバリエーションに合わせてスタイルを設定して、UI 要素の外観をカスタマイズできます。 + +本質的に、スタイル属性を参照するというのは、「現在のテーマのこの属性で定義されるスタイルを使用する」という意味になります。 +</p> + +<p>属性スタイルを参照する場合、名前構文は通常のリソース形式とほぼ同じですが、アットマーク({@code @})の代わりに疑問符({@code ?})を使用します。リソースタイプの部分は省略可能です。 + +例: </p> + +<pre class="classic"> +?[<em><package_name></em>:][<em><resource_type></em>/]<em><resource_name></em> +</pre> + +<p>たとえば、次の例では、属性を参照して、テキスト カラーをシステム テーマの「プライマリ」テキスト カラーに合わせて設定します。 +</p> + +<pre> +<EditText id="text" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:textColor="<strong>?android:textColorSecondary</strong>" + android:text="@string/hello_world" /> +</pre> + +<p>ここでは、{@code android:textColor} 属性が、現在のテーマのスタイル属性の名前を指定しています。 +Android は、{@code android:textColorSecondary} スタイル属性に適用された値を、このウィジェットの {@code android:textColor} の値として使用できるようになりました。 +このコンテキストで属性リソースが必要なことはシステム リソース ツールで認識されているため、タイプ(ここでは <code>?android:attr/textColorSecondary</code>)を明示的に指定する必要はありません — {@code attr} タイプを除外できます。 + + +</p> + + + + +<h2 id="PlatformResources">プラットフォーム リソースにアクセスする</h2> + +<p>Android には、スタイル、テーマ、レイアウトといった多数の標準的なリソースが用意されています。これらのリソースにアクセスするには、<code>android</code> パッケージ名でリソース参照を修飾します。 + +たとえば、Android には、{@link android.widget.ListAdapter} のリストアイテムに使用できるレイアウト リソースが用意されています。 +</p> + +<pre> +{@link android.app.ListActivity#setListAdapter(ListAdapter) +setListAdapter}(new {@link +android.widget.ArrayAdapter}<String>(this, <strong>android.R.layout.simple_list_item_1</strong>, myarray)); +</pre> + +<p>この例では、{@link android.R.layout#simple_list_item_1} は、プラットフォームによって {@link android.widget.ListView} のアイテム向けに定義されるレイアウト リソースです。 +リストアイテムに独自のレイアウトを作成する代わりに、このレイアウトを使用できます。 +詳細については、「<a href="{@docRoot}guide/topics/ui/layout/listview.html">List View</a>」のデベロッパー ガイドをご覧ください。 +</p> + diff --git a/docs/html-intl/intl/ja/guide/topics/resources/overview.jd b/docs/html-intl/intl/ja/guide/topics/resources/overview.jd new file mode 100644 index 000000000000..28ffa94970c0 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/resources/overview.jd @@ -0,0 +1,103 @@ +page.title=リソースの概要 +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>トピック</h2> + <ol> + <li><a href="providing-resources.html">リソースの提供</a></li> + <li><a href="accessing-resources.html">リソースへのアクセス</a></li> + <li><a href="runtime-changes.html">実行時の変更の処理</a></li> + <li><a href="localization.html">Localization</a></li> + </ol> + + <h2>リファレンス</h2> + <ol> + <li><a href="available-resources.html">Resource Types</a></li> + </ol> +</div> +</div> + + +<p>画像や文字列といったリソースは、常にアプリケーション コードの外部に置くようにすることで、独立して保持できるようになります。 +さらに、リソースを外部化することで、言語や画面サイズが異なるような特定の端末構成をサポートする代替リソースを提供できるようになります。異なる構成を持つ Android ベースの端末が増えていることから、この外部化がますます重要になってきています。 + + +異なる構成に互換性を持たせるには、リソースをタイプや構成ごとにグループ化するさまざまなサブディレクトリを使用して、プロジェクトの {@code res/} ディレクトリ内にリソースを整理する必要があります。 + + +</p> + +<div class="figure" style="width:429px"> +<img src="{@docRoot}images/resources/resource_devices_diagram1.png" height="167" alt="" /> +<p class="img-caption"> +<strong>図 1.</strong> デフォルト レイアウトを使用する 2 つの異なる端末(アプリによる代替レイアウトの提供なし)。 +</p> +</div> + +<div class="figure" style="width:429px"> +<img src="{@docRoot}images/resources/resource_devices_diagram2.png" height="167" alt="" /> +<p class="img-caption"> +<strong>図 2.</strong> 画面サイズが違うレイアウトを使用する 2 つの異なる端末 +</p> +</div> + +<p>すべてのリソースタイプに対して、アプリケーションの<em>デフォルト</em> レイアウトと複数の<em>代替</em>リソースを指定できます。 +</p> +<ul> + <li>デフォルト リソースは、端末構成に関係なく使われるものであり、現在の構成に一致する代替リソースがない場合に使用されます。 + +</li> + <li>代替リソースは、特定の構成で使うために作成したリソースです。 +リソースのグループを特定の構成に使用するよう指定するには、適切な構成修飾子をディレクトリ名の後ろに追加します。 +</li> +</ul> + +<p>たとえば、デフォルトの UI レイアウトが {@code res/layout/} ディレクトリに保存してある場合、{@code res/layout-land/} ディレクトリにレイアウトを保存しておくことで、横向きの画面を使用する際の別のレイアウトを指定できます。 + + +Android は、現在の端末の構成とリソースのディレクトリ名をマッチングさせ、適切なリソースを自動的に適用します。 +</p> + +<p>図 1 は、代替リソースがない場合に、システムが 2 つの異なる端末に同じレイアウトを適用する様子を表しています。 +図 2 は、大きい画面の代替レイアウト リソースを追加した場合の、レイアウトの適用の様子を表しています。 +</p> + +<p>次のドキュメントには、アプリケーション リソースの整理、代替リソースの指定、アプリケーションでのアクセスなどに関する情報が詳細に記載されています。 +</p> + +<dl> + <dt><strong><a href="providing-resources.html">リソースの提供</a></strong></dt> + <dd>アプリで提供可能なリソースの種類、保存場所、特定の端末構成用の代替リソースの作成方法。 +</dd> + <dt><strong><a href="accessing-resources.html">リソースへのアクセス</a></strong></dt> + <dd>アプリケーション コードまたは他の XML リソースからの参照による、提供済みリソースの使用方法。 +</dd> + <dt><strong><a href="runtime-changes.html">実行時の変更の処理</a></strong></dt> + <dd>アクティビティの実行中に生じた構成の変更の管理方法。</dd> + <dt><strong><a href="localization.html">Localization</a></strong></dt> + <dd>代替リソースを使用したアプリケーションのローカライズのためのボトムアップ ガイド。代替リソースの特定の使用方法を 1 つだけ解説していますが、複数のユーザーが利用する場合には非常に重要になります。 + +</dd> + <dt><strong><a href="available-resources.html">Resource Types</a></strong></dt> + <dd>提供可能な各種リソースタイプのリファレンス。XML 要素、属性、構文について説明しています。 +たとえば、このリファレンスには、アプリケーション メニュー、ドローアブル、アニメーションなどの作成方法が記載されています。 +</dd> +</dl> + +<!-- +<h2>Raw Assets</h2> + +<p>An alternative to saving files in {@code res/} is to save files in the {@code +assets/} directory. This should only be necessary if you need direct access to original files and +directories by name. Files saved in the {@code assets/} directory will not be given a resource +ID, so you can't reference them through the {@code R} class or from XML resources. Instead, you can +query data in the {@code assets/} directory like an ordinary file system, search through the +directory and +read raw data using {@link android.content.res.AssetManager}. For example, this can be more useful +when dealing with textures for a game. However, if you only need to read raw data from a file +(such as a video or audio file), then you should save files into the {@code res/raw/} directory and +then read a stream of bytes using {@link android.content.res.Resources#openRawResource(int)}. This +is uncommon, but if you need direct access to original files in {@code assets/}, refer to the {@link +android.content.res.AssetManager} documentation.</p> +--> diff --git a/docs/html-intl/intl/ja/guide/topics/resources/providing-resources.jd b/docs/html-intl/intl/ja/guide/topics/resources/providing-resources.jd new file mode 100644 index 000000000000..6729e8b6ee8a --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/resources/providing-resources.jd @@ -0,0 +1,1094 @@ +page.title=リソースの提供 +parent.title=アプリケーション リソース +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>クイックビュー</h2> + <ul> + <li>{@code res/} のそれぞれのサブディレクトリにはさまざまなタイプのリソースがある</li> + <li>代替リソースは設定固有のリソース ファイルを提供する</li> + <li>特定の端末設定に依存しないように、デフォルトのリソースを常に入れておく +</li> + </ul> + <h2>本書の内容</h2> + <ol> + <li><a href="#ResourceTypes">リソースタイプをグループ化する</a></li> + <li><a href="#AlternativeResources">代替リソースを提供する</a> + <ol> + <li><a href="#QualifierRules">修飾子の名前のルール</a></li> + <li><a href="#AliasResources">エイリアス リソースを作成する</a></li> + </ol> + </li> + <li><a href="#Compatibility">リソースとの最適な端末の互換性を提供する</a></li> + <li><a href="#BestMatch">Android が最適なリソースを見つける仕組み</a></li> + </ol> + + <h2>関連ドキュメント</h2> + <ol> + <li><a href="accessing-resources.html">リソースへのアクセス</a></li> + <li><a href="available-resources.html">Resource Types</a></li> + <li><a href="{@docRoot}guide/practices/screens_support.html">複数のスクリーンをサポートする</a> +</li> + </ol> +</div> +</div> + +<p>画像や文字列といったアプリケーション リソースは、常にコードの外部に置くようにすることで、独立して保持できるようになります。 +さらに、特別に名前を設定したリソース ディレクトリにグループ化することで、特定の端末設定に代替リソースを提供する必要があります。 +実行時には、現在の設定に基づいて、Android は適切なリソースを使用します。 +たとえば、画面サイズに応じて異なる UI レイアウトを提供したり、言語設定に応じて異なる文字列を提供したりできます。 + +</p> + +<p>アプリケーション リソースを外部化したら、プロジェクトの {@code R} クラスで生成されるリソース ID を使用してそれらのリソースにアクセスできます。 +アプリケーションでのリソースの使用方法については、「<a href="accessing-resources.html">リソースへのアクセス</a>」をご覧ください。 + +このドキュメントでは、Android プロジェクトでリソースをグループ化する方法と、特定の端末設定に代替リソースを提供する方法を説明します。 +</p> + + +<h2 id="ResourceTypes">リソースタイプをグループ化する</h2> + +<p>それぞれのタイプのリソースを、プロジェクトの {@code res/} ディレクトリの特定のサブディレクトリに配置する必要があります。 +次は、単純なプロジェクトのファイル階層の例です。</p> + +<pre class="classic no-pretty-print"> +MyProject/ + src/ <span style="color:black"> + MyActivity.java </span> + res/ + drawable/ <span style="color:black"> + graphic.png </span> + layout/ <span style="color:black"> + main.xml + info.xml</span> + mipmap/ <span style="color:black"> + icon.png </span> + values/ <span style="color:black"> + strings.xml </span> +</pre> + +<p>この例を見てわかるように、{@code res/} ディレクトリには、画像リソース、2 つのレイアウト リソース、ランチャー アイコンの {@code mipmap/} ディレクトリ、文字列リソース ファイルといった、すべてのリソース(サブディレクトリ内)が入ります。 + +リソース ディレクトリ名は重要です。表 1 に説明があります。 +</p> + +<p class="note"><strong>注:</strong> Mipmap フォルダの使用方法については、「<a href="{@docRoot}tools/projects/index.html#mipmap">Managing Projects Overview</a>」をご覧ください。 +</p> + +<p class="table-caption" id="table1"><strong>表 1.</strong> プロジェクト {@code res/} ディレクトリ内でサポートされているリソース ディレクトリ。 +</p> + +<table> + <tr> + <th scope="col">ディレクトリ</th> + <th scope="col">リソースタイプ</th> + </tr> + + <tr> + <td><code>animator/</code></td> + <td><a href="{@docRoot}guide/topics/graphics/prop-animation.html">プロパティ アニメーション</a>を定義する XML ファイル。 +</td> + </tr> + + <tr> + <td><code>anim/</code></td> + <td><a href="{@docRoot}guide/topics/graphics/view-animation.html#tween-animation">トゥイーン アニメーション</a>を定義する XML ファイル。 +(プロパティ アニメーションをこのディレクトリに保存することもできますが、2 つのタイプを区別するために、プロパティ アニメーションは {@code animator/} ディレクトリに保存することをお勧めします)。 + +</td> + </tr> + + <tr> + <td><code>color/</code></td> + <td>色の状態リストを定義する XML ファイル。「<a href="color-list-resource.html">Color State List Resource</a>」をご覧ください。 +</td> + </tr> + + <tr> + <td><code>drawable/</code></td> + + <td><p>ビットマップ ファイル({@code .png}、{@code .9.png}、{@code .jpg}、{@code .gif})または次のドローアブル リソース サブタイプにコンパイルされる XML ファイル: +</p> + <ul> + <li>ビットマップ ファイル</li> + <li>Nine-Patche(リサイズ可能なビットマップ)</li> + <li>状態リスト</li> + <li>形状</li> + <li>アニメーション ドローアブル</li> + <li>その他のドローアブル</li> + </ul> + <p>「<a href="drawable-resource.html">Drawable Resources</a>」をご覧ください。</p> + </td> + </tr> + + <tr> + <td><code>mipmap/</code></td> + <td>さまざまなランチャー アイコン密度のドローアブル ファイル。{@code mipmap/} フォルダによるランチャー アイコンの管理方法については、「<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>」をご覧ください。 + +</td> + </tr> + + <tr> + <td><code>layout/</code></td> + <td>ユーザー インターフェースのレイアウトを定義する XML ファイル。 + 「<a href="layout-resource.html">Layout Resource</a>」をご覧ください。</td> + </tr> + + <tr> + <td><code>menu/</code></td> + <td>オプション メニュー、コンテキスト メニュー、サブ メニューといった、アプリケーション メニューを定義する XML ファイル。 +「<a href="menu-resource.html">Menu Resource</a>」をご覧ください。</td> + </tr> + + <tr> + <td><code>raw/</code></td> + <td><p>未加工の形式で保存する任意のファイル。これらのリソースを未加工の {@link java.io.InputStream} で開くには、{@link android.content.res.Resources#openRawResource(int) +Resources.openRawResource()} をリソース ID({@code R.raw.ファイル名<em></em>})とともに呼び出します。 +</p> + <p>ただし、元のファイル名とファイル階層にアクセスする必要がある場合は、一部のリソースを {@code +assets/} ディレクトリ({@code res/raw/} の代わりに)に保存することを検討します。 +{@code assets/} のファイルにはリソース ID が付与されていないため、読み込むには {@link android.content.res.AssetManager} が必要です。 +</p></td> + </tr> + + <tr> + <td><code>values/</code></td> + <td><p>文字列、整数、色など、単純な値を含む XML ファイル。</p> + <p>その他の {@code res/} サブディレクトリの XML リソース ファイルは XML ファイル名に基づいて 1 つのリソースを定義しますが、{@code values/} ディレクトリのファイルは複数のリソースを表します。このディレクトリのファイルの場合、{@code <resources>} 要素のそれぞれの子が 1 つのリソースを定義します。 + + +たとえば、{@code <string>} 要素は {@code R.string} リソースを作成し、{@code <color>} 要素は {@code R.color} リソースを作成します。 + +</p> + <p>各リソースの定義には XML 要素を使用するため、ファイルには任意の名前を設定でき、1 つのファイル内にさまざまなリソースを配置できます。 +ただし、わかりやすくするために、一意のリソースタイプをそれぞれのファイルに配置することもできます。 +次は、このディレクトリで作成できるリソースのファイル名の変換例です。 +</p> + <ul> + <li>リソースの配列の場合 arrays.xml(<a href="more-resources.html#TypedArray">型付き配列</a>)。</li> + <li><a href="more-resources.html#Color">色の値</a>の場合 colors.xml </li> + <li><a href="more-resources.html#Dimension">寸法の値</a>の場合 dimens.xml。</li> + <li><a href="string-resource.html">文字列の値</a>の場合 strings.xml。 +</li> + <li><a href="style-resource.html">スタイル</a>の場合 styles.xml。</li> + </ul> + <p>「<a href="string-resource.html">String Resources</a>」、「<a href="style-resource.html">Style Resource</a>」、「<a href="more-resources.html">More Resource Types</a>」をご覧ください。 + +</p> + </td> + </tr> + + <tr> + <td><code>xml/</code></td> + <td>{@link +android.content.res.Resources#getXml(int) Resources.getXML()} を呼び出すことによって、実行時に読み込むことができる任意の XML ファイル。ここには、<a href="{@docRoot}guide/topics/search/searchable-config.html">検索可能な設定</a>など、各種の XML 設定ファイルが保存されます。 + +<!-- or preferences configuration. --></td> + </tr> +</table> + +<p class="caution"><strong>警告:</strong> リソース ファイルを {@code res/} ディレクトリに直接保存しないでください。—コンパイラー エラーの原因になります。 +</p> + +<p>リソースの特定のタイプの詳細は、「<a href="available-resources.html">Resource Types</a>」のドキュメントをご覧ください。</p> + +<p>表 1 で定義したサブディレクトリに保存するリソースは、「デフォルト」のリソースとなります。 +つまり、これらのリソースはアプリケーションのデフォルトのデザインとコンテンツを定義します。ただし、Android が搭載された端末では別のタイプのリソースが呼び出されることがあります。たとえば、端末の画面サイズが通常のものよりも大きな場合、追加の画面スペースを利用する別のレイアウト リソースを提供する必要があります。 + + +また、端末の言語設定が異なる場合、使用するユーザー インターフェースのテキストを翻訳する、別の文字列リソースを提供します。 + +さまざまな端末設定にこれらの異なるリソースを提供するには、デフォルトのリソースに加えて、代替リソースを提供する必要があります。 + +</p> + + +<h2 id="AlternativeResources">代替リソースを提供する</h2> + + +<div class="figure" style="width:429px"> +<img src="{@docRoot}images/resources/resource_devices_diagram2.png" height="167" alt="" /> +<p class="img-caption"> +<strong>図 1.</strong> 別のレイアウト リソースを使用する、2 つの異なる端末。</p> +</div> + +<p>ほぼすべてのアプリケーションが、特定の端末設定をサポートするための代替リソースを提供します。 +たとえば、画面密度が異なる場合は代替ドローアブル リソースを含め、言語が異ならう場合は代替文字列リソースを含めます。 +実行時には、Android が現在の端末設定を検出し、アプリケーションに合ったリソースを読み込みます。 + +</p> + +<p>一連のリソースに設定固有の代替リソースを指定するには:</p> +<ol> + <li>{@code +<em><resources_name></em>-<em><config_qualifier></em>} の形式で名前を付けた {@code res/} に新しいディレクトリを作成します。 + <ul> + <li><em>{@code <resources_name>}</em> は、対応するディレクトリ リソースのディレクトリ名です(表 1 で定義)。 +</li> + <li><em>{@code <qualifier>}</em> は、リソースを使用する個々の設定を指定する名前です(表 2 で定義)。 +</li> + </ul> + <p>1 つ以上の <em>{@code <qualifier>}</em> を末尾に追加できます。それぞれの修飾子はダッシュを使用して区切ります。 +</p> + <p class="caution"><strong>警告:</strong> 複数の修飾子を末尾に追加する場合は、表 2 に記載されているのと同じ順番で配置する必要があります。 +修飾子の順番に誤りがあると、リソースが無視されます。 +</p> + </li> + <li>それぞれの代替リソースをこの新しいディレクトリに保存します。リソース ファイルの名前は、デフォルトのリソース ファイルと同じものにする必要があります。 +</li> +</ol> + +<p>次に、デフォルト リソースと代替リソースの例を示します。</p> + +<pre class="classic no-pretty-print"> +res/ + drawable/ <span style="color:black"> + icon.png + background.png </span> + drawable-hdpi/ <span style="color:black"> + icon.png + background.png </span> +</pre> + +<p>{@code hdpi} 修飾子は、ディレクトリ内のリソースが高密度画面を持つ端末用であることを表します。 +これらのドローアブル ディレクトリの画像は特定の画面密度に合わせたサイズになっていますが、ファイル名は完全に同じになります。 + +このように、{@code icon.png} や {@code +background.png} 画像を参照するのに使用するリソース ID は常に同じになりますが、Android はリソース ディレクトリ名の修飾子により端末設定情報を比較して、各リソースの現在の端末に最適なバージョンを選択します。 + +</p> + +<p>Android では複数の設定修飾子をサポートしており、それぞれの修飾子をダッシュで区切ることで、1 つのディレクトリ名に複数の修飾子を追加できます。 +表 2 には、有効な設定修飾子が優先度順に記載されています。—参照ディレクトリに複数の修飾子を使用する場合、表に記載されている順番にディレクトリ名に追加する必要があります。 + + +</p> + + +<p class="table-caption" id="table2"><strong>表 2.</strong> 設定修飾子の名前。 +</p> +<table> + <tr> + <th>設定</th> + <th>修飾子の値</th> + <th>説明</th> + </tr> + <tr id="MccQualifier"> + <td>MCC と MNC</td> + <td>例: <br/> + <code>mcc310</code><br/> + <code><nobr>mcc310-mnc004</nobr></code><br/> + <code>mcc208-mnc00</code><br/> + など + </td> + <td> + <p>モバイル カントリーコード(MCC)です。端末の SIM カードにあるモバイル ネットワーク コード(MNC)が続くことがあります。 +たとえば、<code>mcc310</code> は米国の任意の携帯通信会社、<code>mcc310-mnc004</code> は米国の Verizon、<code>mcc208-mnc00</code> はフランスの Orange となります。 + +</p> + <p>端末が無線通信接続(GSM 電話)を使用する場合、MCC と MNC の値は SIM カードの値となります。 +</p> + <p>さらに、MCC のみを使用することもできます(たとえば、アプリケーションに国固有の法に関するリソースを含める場合)。 +言語のみに基づいて指定する場合は、代わりに<em>言語と地域</em>の修飾子(次のセクションで解説)を使用します。 +MCC と MNC 修飾子を使用する場合は、慎重に設定し、予測のとおりに機能することをテストします。 +</p> + <p>さらに、設定フィールド {@link +android.content.res.Configuration#mcc}、{@link +android.content.res.Configuration#mnc} もご覧ください。これらは、それぞれ、現在のモバイル カントリーコードとモバイル ネットワーク コードを表します。 +</p> + </td> + </tr> + <tr id="LocaleQualifier"> + <td>言語と地域</td> + <td>例: <br/> + <code>en</code><br/> + <code>fr</code><br/> + <code>en-rUS</code><br/> + <code>fr-rFR</code><br/> + <code>fr-rCA</code><br/> + など + </td> + <td><p>言語は 2 文字の <a href="http://www.loc.gov/standards/iso639-2/php/code_list.php">ISO 639-1</a> 言語コードで定義し、オプションで、2 文字の <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1-alpha-2</a> 地域コードを後ろに追加します(先頭に小文字の「{@code r}」が付きます)。 + + + + </p><p> + コードでは大文字と小文字が区別されません。<em></em>地域を区別するには、{@code r} 接頭辞を使用します。 + + 地域のみは指定できません。</p> + <p>ユーザーがシステム設定で言語を変更すると、アプリケーションの実行中にこの値が変更されます。 +実行時のアプリケーションに与える影響については、<a href="runtime-changes.html">実行時の変更の処理</a>をご覧ください。 +</p> + <p>アプリケーションを他の言語にローカライズするための詳細なガイドは、「<a href="localization.html">Localization</a>」をご覧ください。 +</p> + <p>さらに、{@link android.content.res.Configuration#locale} 設定フィールドもご覧ください。これは、現在のロケールを表します。 +</p> + </td> + </tr> + <tr id="LayoutDirectionQualifier"> + <td>レイアウトの方向</td> + <td><code>ldrtl</code><br/> + <code>ldltr</code><br/> + </td> + <td><p>アプリケーションのレイアウトの方向です。{@code ldrtl} は、「レイアウト方向は右から左」という意味になります。{@code ldltr} は、「レイアウト方向は左から右」という意味になります。この設定が暗黙的にデフォルト値となります。 + + </p> + <p>この設定は、レイアウト、ドローアブル、値など、任意のリソースに適用できます。 + </p> + <p>たとえば、アラビア語に何らかの特定なレイアウトを提供し、その他の「右から左」の言語(ペルシャ語やヘブライ語)に汎用的なレイアウトを提供する場合、次のように設定します。 + + </p> +<pre class="classic no-pretty-print"> +res/ + layout/ <span style="color:black"> + main.xml </span>(Default layout) + layout-ar/ <span style="color:black"> + main.xml </span>(Specific layout for Arabic) + layout-ldrtl/ <span style="color:black"> + main.xml </span>(Any "right-to-left" language, except + for Arabic, because the "ar" language qualifier + has a higher precedence.) +</pre> + <p class="note"><strong>注:</strong> アプリで右から左のレイアウト機能を有効にするには、<a href="{@docRoot}guide/topics/manifest/application-element.html#supportsrtl">{@code + supportsRtl}</a> を {@code "true"} に設定し、<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> を 17 以上に設定します。 +</p> + <p>API レベル 17 で追加。<em></em></p> + </td> + </tr> + <tr id="SmallestScreenWidthQualifier"> + <td>smallestWidth</td> + <td><code>sw<N>dp</code><br/><br/> + 例: <br/> + <code>sw320dp</code><br/> + <code>sw600dp</code><br/> + <code>sw720dp</code><br/> + など + </td> + <td> + <p>使用可能な画面領域の最小寸法で指定する、画面の基本サイズ。 +具体的には、端末の smallestWidth は画面に使用できる高さと幅の最小サイズとなります(画面の「使用できる最小幅」と考えることもできます)。 +画面の現在の方向に関係なく、この修飾子を使用することで、アプリケーションの UI に少なくとも {@code <N>} dps の幅を使用できます。 + +</p> + <p>たとえば、画面領域のレイアウトの最小寸法を常に 600 dp とする必要がある場合、この修飾子を使用してレイアウト リソース {@code +res/layout-sw600dp/} を作成できます。 +システムは、600dp の側が縦になるか横になるか関係なく、使用可能な画面の最小寸法が 600dp 以上の場合にのみこれらのリソースを使用します。 + +smallestWidth は端末の固定された画面サイズ特性です。<strong>画面の向きが変わっても、端末の smallestWidth は変更されません。</strong> +</p> + <p>端末の smallestWidth では画面の装飾とシステム UI が考慮されます。たとえば、端末の画面に smallestWidth の軸に沿ったスペースを考慮した固定 UI 要素がある場合、これらの画面ピクセルは UI に使用できないことから、システムは実際の画面サイズよりも小さな smallestWidth を宣言します。つまり、使用する値は、レイアウトが必要とする実際の最小寸法とする必要があります(通常は、この値は、画面の現在の向きに関係なく、レイアウトがサポートする「最小幅」となります)。<em></em> + + + + +</p> + <p>次に、一般的な画面サイズに使用する値を示します。</p> + <ul> + <li>320。次のような画面設定を持つ端末。 + <ul> + <li>240x320 ldpi(QVGA ハンドセット)</li> + <li>320x480 mdpi(ハンドセット)</li> + <li>480x800 hdpi(高密度ハンドセット)</li> + </ul> + </li> + <li>480。480x800 mdpi(タブレットやハンドセット)などの画面。</li> + <li>600。600x1024 mdpi(7 インチタブレット)などの画面。</li> + <li>720。720x1280 mdpi(10 インチタブレット)などの画面。</li> + </ul> + <p>アプリケーションで smallestWidth 修飾子の値が異なる複数のリソース ディレクトリを提供する場合、システムは端末の smallestWidth に最も近い(かつ超過しない)ものを使用します。 + + </p> + <p>API レベル 13 で追加。<em></em></p> + <p>さらに、<a href="{@docRoot}guide/topics/manifest/supports-screens-element.html#requiresSmallest">{@code +android:requiresSmallestWidthDp}</a> 属性もご覧ください。これは、アプリケーションが互換性を持つ最小の smallestWidth と、端末の smallestWidth 値を保持する {@link +android.content.res.Configuration#smallestScreenWidthDp} 設定フィールドを宣言します。 + +</p> + <p>さまざまな画面の設計とこの修飾子の使用方法についての詳細は、「<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>」のデベロッパー ガイドをご覧ください。 + +</p> + </td> + </tr> + <tr id="ScreenWidthQualifier"> + <td>使用可能な幅</td> + <td><code>w<N>dp</code><br/><br/> + 例: <br/> + <code>w720dp</code><br/> + <code>w1024dp</code><br/> + など + </td> + <td> + <p>リソースを使用する、使用可能な最小の画面幅を {@code dp} 単位で指定します。—<code><N></code> の値で定義します。 +画面の向きの縦と横を変更すると、現在の実際の幅に合わせて、この設定値が変更されます。 + +</p> + <p>アプリケーションでこの設定が異なる複数のリソース ディレクトリを提供する場合、システムは端末の現在の画面の幅に最も近い(かつ超過しない)ものを使用します。 + +この値は画面の装飾を考慮します。つまり、端末のディスプレイの左や右に何らかの固定 UI 要素がある場合、これらの UI 要素を考慮し、アプリケーションの使用可能なスペースを減らして、実際の画面サイズよりも小さな幅を使用します。 + + + +</p> + <p>API レベル 13 で追加。<em></em></p> + <p>さらに、{@link android.content.res.Configuration#screenWidthDp} 設定フィールドもご覧ください。これは現在の画面の幅を保持します。 +</p> + <p>さまざまな画面の設計とこの修飾子の使用方法についての詳細は、「<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>」のデベロッパー ガイドをご覧ください。 + +</p> + </td> + </tr> + <tr id="ScreenHeightQualifier"> + <td>使用可能な高さ</td> + <td><code>h<N>dp</code><br/><br/> + 例: <br/> + <code>h720dp</code><br/> + <code>h1024dp</code><br/> + など + </td> + <td> + <p>リソースを使用する、使用可能な最小の画面幅を「dp」単位で指定します。—<code><N></code> の値で定義します。 +画面の向きの縦と横を変更すると、現在の実際の高さに合わせて、この設定値が変更されます。 + +</p> + <p>アプリケーションでこの設定が異なる複数のリソース ディレクトリを提供する場合、システムは端末の現在の画面の高さに最も近い(かつ超過しない)ものを使用します。 + +この値は画面の装飾を考慮します。つまり、端末のディスプレイの上や下に何らかの固定 UI 要素がある場合、これらの UI 要素を考慮し、アプリケーションの使用可能なスペースを減らして、実際の画面サイズよりも小さな高さを使用します。 + + + +固定されていない画面の装飾(全画面にした場合に非表示になる携帯電話のステータスバーなど)や、タイトルバーやアクションバーなどのウィンドウの装飾は、ここでは考慮されません。そのため、アプリケーションでは指定したスペースよりもやや小さなサイズに対処できるように準備をし置く必要があります。<em></em> + + + + + <p>API レベル 13 で追加。<em></em></p> + <p>さらに、{@link android.content.res.Configuration#screenHeightDp} 設定フィールドもご覧ください。これは現在の画面の幅を保持します。 +</p> + <p>さまざまな画面の設計とこの修飾子の使用方法についての詳細は、「<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>」のデベロッパー ガイドをご覧ください。 + +</p> + </td> + </tr> + <tr id="ScreenSizeQualifier"> + <td>画面サイズ</td> + <td> + <code>small</code><br/> + <code>normal</code><br/> + <code>large</code><br/> + <code>xlarge</code> + </td> + <td> + <ul class="nolist"> + <li>{@code small}: 低密度 QVGA 画面と同等のサイズを持つ画面です。 +小さい画面の最小レイアウト サイズは約 320x426 dp 単位です。 +たとえば、QVGA 低密度や VGA 高密度です。 +</li> + <li>{@code normal}: 中密度 HVGA 画面と同等のサイズを持つ画面です。 +通常の画面の最小レイアウト サイズは約 320x470 dp 単位です。 +たとえば、WQVGA 低密度、HVGA 中密度、WVGA 高密度といった画面になります。 + +</li> + <li>{@code large}: 中密度 VGA 画面と同等のサイズを持つ画面です。 + + 大きな画面の最小レイアウト サイズは約 480x640 dp 単位です。 + たとえば、VGA や WVGA の中密度といった画面です。</li> + <li>{@code xlarge}: 従来の中密度 HVGA 画面よりもはるかに大きなサイズの画面です。 +特大の画面の最小レイアウト サイズは約 720x960 dp 単位です。 +ほとんどの場合、特大の画面を持つ端末はポケットに入れて持ち運ぶことができないほど大きく、タブレット スタイルの端末になります。 + +API レベル 9 で追加。<em></em></li> + </ul> + <p class="note"><strong>注:</strong> サイズ識別子を持つ場合でも、リソースがそのサイズの画面以外には対応しないということではありません。<em></em> +現在の端末に最適な識別子を持つ代替リソースを提供していない場合でも、システムによって<a href="#BestMatch">最適な</a>リソースが使用されることがあります。 + +</p> + <p class="caution"><strong>警告:</strong> すべてのリソースが現在の画面よりも大きなサイズ識別子を使用している場合、システムはそれらのリソースを使用せず、アプリケーションが実行時にクラッシュしてしまいます(たとえば、すべてのリソースに {@code +xlarge} 識別子のタグが付いているが、端末は通常サイズの画面である場合)。<em></em><strong></strong> + +</p> + <p>API レベル 4 で追加。<em></em></p> + + <p>詳細については、「<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>」をご覧ください。 +</p> + <p>さらに、{@link android.content.res.Configuration#screenLayout} 設定フィールドもご覧ください。これは、画面のサイズが小、中、大のいずれかであるかを表します。 + +</p> + </td> + </tr> + <tr id="ScreenAspectQualifier"> + <td>画面アスペクト</td> + <td> + <code>long</code><br/> + <code>notlong</code> + </td> + <td> + <ul class="nolist"> + <li>{@code long}: WQVGA、WVGA、FWVGA のような長い画面</li> + <li>{@code notlong}: QVGA、HVGA、VGA のように長くない画面</li> + </ul> + <p>API レベル 4 で追加。<em></em></p> + <p>これは純粋に画面のアスペクト比を基準とします(「長い」画面は幅広の画面になります)。これは画面の向きには関係ありません。 +</p> + <p>さらに、{@link android.content.res.Configuration#screenLayout} 設定フィールドもご覧ください。これは、画面のサイズが長いかどうかを表します。 +</p> + </td> + </tr> + <tr id="OrientationQualifier"> + <td>画面の向き</td> + <td> + <code>port</code><br/> + <code>land</code> <!-- <br/> + <code>square</code> --> + </td> + <td> + <ul class="nolist"> + <li>{@code port}: 端末は縦向き(垂直)になっています</li> + <li>{@code land}: 端末は横向き(水平)になっています</li> + <!-- Square mode is currently not used. --> + </ul> + <p>ユーザーが画面を回転すると、アプリケーションの実行中にこの値が変更されます。 +実行時のアプリケーションに与える影響については、「<a href="runtime-changes.html">実行時の変更の処理</a>」をご覧ください。 +</p> + <p>さらに、{@link android.content.res.Configuration#orientation} 設定フィールドもご覧ください。これは、現在の端末の画面の向きを表します。 +</p> + </td> + </tr> + <tr id="UiModeQualifier"> + <td>UI モード</td> + <td> + <code>car</code><br/> + <code>desk</code><br/> + <code>television</code><br/> + <code>appliance</code> + <code>watch</code> + </td> + <td> + <ul class="nolist"> + <li>{@code car}: 端末は車載ドックで表示されています</li> + <li>{@code desk}: 端末はデスクドックで表示されています</li> + <li>{@code television}: 端末はテレビで表示されており、「10 フィート」離れた位置からの操作が可能です。UI はユーザーから離れた場所にある大きな画面に表示され、主に十字キーやポインタ以外のやり取りで操作します。 + + +</li> + <li>{@code appliance}: 端末をアプライアンスとして使用します。ディスプレイはありません +</li> + <li>{@code watch}: 端末にはディスプレイがあり、手首に装着して使用します</li> + </ul> + <p>API レベル 8 で追加。television は API 13 で追加。watch は API 20 で追加。<em></em></p> + <p>端末をホルダーに装着したり、取り外したりしたときのアプリの反応については、「<a href="{@docRoot}training/monitoring-device-state/docking-monitoring.html">Determining and Monitoring the Docking State and Type</a>」をご覧ください。 + +</p> + <p>ユーザーが端末をドックに装着すると、アプリケーションの実行中にこの値が変更されます。 +{@link +android.app.UiModeManager} を使用すると、これらのモードの一部を有効または無効にできます。実行時のアプリケーションに与える影響については、「<a href="runtime-changes.html">実行時の変更の処理</a>」をご覧ください。 +</p> + </td> + </tr> + <tr id="NightQualifier"> + <td>ナイトモード</td> + <td> + <code>night</code><br/> + <code>notnight</code> + </td> + <td> + <ul class="nolist"> + <li>{@code night}: 夜間</li> + <li>{@code notnight}: 昼間</li> + </ul> + <p>API レベル 8 で追加。<em></em></p> + <p>ナイトモードを自動モード(デフォルト)のままにしておくと、時間を基準にしてモードが変更された場合に、アプリケーションの実行中にこの値が変更されます。 +{@link android.app.UiModeManager} を使用すると、このモードを有効または無効にできます。 +実行時のアプリケーションに与える影響については、「<a href="runtime-changes.html">実行時の変更の処理</a>」をご覧ください。 +</p> + </td> + </tr> + <tr id="DensityQualifier"> + <td>画面ピクセル密度(dpi)</td> + <td> + <code>ldpi</code><br/> + <code>mdpi</code><br/> + <code>hdpi</code><br/> + <code>xhdpi</code><br/> + <code>xxhdpi</code><br/> + <code>xxxhdpi</code><br/> + <code>nodpi</code><br/> + <code>tvdpi</code> + </td> + <td> + <ul class="nolist"> + <li>{@code ldpi}: 低密度の画面。約 120dpi です。</li> + <li>{@code mdpi}: 中密度(従来の HVGA)の画面。約 160dpi です。 +</li> + <li>{@code hdpi}: 高密度の画面。約 240dpi です。</li> + <li>{@code xhdpi}: 超高密度の画面。約 320dpi です。API レベル 8 で追加。<em></em> +</li> + <li>{@code xxhdpi}: 超超高密度の画面。約 480dpi です。API レベル 16 で追加。<em></em> +</li> + <li>{@code xxxhdpi}: 超超高密度が使用(ランチャー アイコンのみ。「Supporting Multiple Screens」の<a href="{@docRoot}guide/practices/screens_support.html#xxxhdpi-note">注</a>をご覧ください)。約 640dpi です。<em></em> + +API レベル 18 で追加。<em></em> +</li> + <li>{@code nodpi}: 端末の密度に合わせてサイズを変更しないビットマップ リソースに使用します。 +</li> + <li>{@code tvdpi}: 密度が mdpi と hdpi の間の画面。約 213dpi です。これは「プライマリ」の密度グループとしては認識されません。 +ほとんどの場合、テレビ向けのものであり、大部分のアプリは必要としません。—通常、アプリの場合は mdpi と hdpi リソースを提供すれば十分であり、システムが必要に応じてサイズを変更します。 + +この識別子は API レベル 13 で導入されました。</li> + </ul> + <p>6 つのプライマリ密度のサイズの比率は 3:4:6:8:12:16 です(tvdpi 密度を除く)。 +そのため、ldpi では 9x9 のビットマップ、mdpi では 12x12 のビットマップ、hdpi では 18x18 のビットマップ、xhdpi では 24x24 のビットマップとなります。 +</p> + <p>画像リソースがテレビや他の特定の端末で正常に表示されず、tvdpi リソースを試す場合、拡張係数は 1.33*mdpi になります。 +たとえば、画面向けの 100px x 100px 画像は、tvdpi 向けにすると 133px x 133px となります。 +</p> + <p class="note"><strong>注:</strong> 密度識別子を持つ場合でも、リソースがその密度の画面以外には対応しないということではありません。<em></em> +現在の端末に最適な識別子を持つ代替リソースを提供していない場合でも、システムによって<a href="#BestMatch">最適な</a>リソースが使用されることがあります。 + +</p> + <p>異なる画面密度を処理する方法や、Android が現在の密度に合わせてビットマップのサイズを変更する方法については、「<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>」をご覧ください。 + +</p> + </td> + </tr> + <tr id="TouchscreenQualifier"> + <td>タッチスクリーン タイプ</td> + <td> + <code>notouch</code><br/> + <code>finger</code> + </td> + <td> + <ul class="nolist"> + <li>{@code notouch}: 端末にはタッチスクリーンが搭載されていません。</li> + <li>{@code finger}: 端末には、ユーザーの指先による指示操作で使用するためのタッチスクリーンが搭載されています。 +</li> + </ul> + <p>{@link android.content.res.Configuration#touchscreen} 設定フィールドもご覧ください。これは、端末上のタッチスクリーンのタイプを表します。 +</p> + </td> + </tr> + <tr id="KeyboardAvailQualifier"> + <td>キーボードの使用可能状況</td> + <td> + <code>keysexposed</code><br/> + <code>keyshidden</code><br/> + <code>keyssoft</code> + </td> + <td> + <ul class="nolist"> + <li>{@code keysexposed}: 端末ではキーボードを使用できます。端末でソフトウェア キーボードが有効な(と想定される)場合、端末にハードウェア キーボードが接続されておらず、ハードウェア キーボードがユーザーに提示されていない場合でも、この値が使用されることがあります。<em></em> + +ソフトウェア キーボードが提供されていない、または無効になっている場合は、ハードウェア キーボードが認識された場合にのみ使用されます。 + +</li> + <li>{@code keyshidden}: 端末には使用可能なハードウェア キーボードがありますが非表示になっています。また、端末ではソフトウェア キーボードが有効になっていません。<em></em><em></em> +</li> + <li>{@code keyssoft}: 表示されているかどうかに関係なく、端末ではソフトウェア キーボードが有効になっています。 +</li> + </ul> + <p><code>keysexposed</code> リソースを提供するが、<code>keyssoft</code> リソースを提供しない場合、システムのソフトウェア キーボードが有効になっている場合は、キーボードが表示されているかに関係なく、システムは <code>keysexposed</code> リソースを使用します。 + +</p> + <p>ユーザーがハードウェア キーボードを開くと、アプリケーションの実行中にこの値が変更されます。 +実行時のアプリケーションに与える影響については、「<a href="runtime-changes.html">実行時の変更の処理</a>」をご覧ください。 +</p> + <p>さらに、設定フィールド {@link +android.content.res.Configuration#hardKeyboardHidden} と {@link +android.content.res.Configuration#keyboardHidden} もご覧ください。これは、ハードウェア キーボードの可視性、任意のキーボード(ソフトウェアを含む)の可視性、それぞれの可視性を表します。 +</p> + </td> + </tr> + <tr id="ImeQualifier"> + <td>主なテキストの入力方法</td> + <td> + <code>nokeys</code><br/> + <code>qwerty</code><br/> + <code>12key</code> + </td> + <td> + <ul class="nolist"> + <li>{@code nokeys}: 端末にはテキスト入力用のハードウェア キーはありません。</li> + <li>{@code qwerty}: ユーザーに表示されているかどうかに関係なく、端末にはハードウェア クワーティ キーボードが搭載されています。 + +</li> + <li>{@code 12key}: ユーザーに表示されているかどうかに関係なく、端末にはハードウェア 12key キーボードが搭載されています。 +</li> + </ul> + <p>さらに、{@link android.content.res.Configuration#keyboard} 設定フィールドもご覧ください。これは、使用可能な主なテキストの入力方法を表します。 +</p> + </td> + </tr> + <tr id="NavAvailQualifier"> + <td>ナビゲーション キーの使用可能状況</td> + <td> + <code>navexposed</code><br/> + <code>navhidden</code> + </td> + <td> + <ul class="nolist"> + <li>{@code navexposed}: ユーザーはナビゲーション キーを使用できます。</li> + <li>{@code navhidden}: ナビゲーション キーは使用できません(閉じられた lid の背後になっている場合など)。 +</li> + </ul> + <p>ユーザーがナビゲーション キーを表示させると、アプリケーションの実行中にこの値が変更されます。 +実行時のアプリケーションに与える影響については、「<a href="runtime-changes.html">実行時の変更の処理</a>」をご覧ください。 +</p> + <p>さらに、{@link android.content.res.Configuration#navigationHidden} 設定フィールドもご覧ください。これは、ナビゲーション キーが非表示になっているかどうかを表します。 +</p> + </td> + </tr> + <tr id="NavigationQualifier"> + <td>タップ以外の主なナビゲーション方法</td> + <td> + <code>nonav</code><br/> + <code>dpad</code><br/> + <code>trackball</code><br/> + <code>wheel</code> + </td> + <td> + <ul class="nolist"> + <li>{@code nonav}: 端末には、タッチスクリーン以外のナビゲーション機能がありません。 +</li> + <li>{@code dpad}: 端末にはナビゲーション用の方向キー(十字キー)があります。</li> + <li>{@code trackball}: 端末にはナビゲーション用のトラックボールがあります。</li> + <li>{@code wheel}: 端末にはナビゲーション用の方向ホイールがあります(特殊)。</li> + </ul> + <p>{@link android.content.res.Configuration#navigation} 設定フィールドもご覧ください。これは、利用可能なナビゲーション方法のタイプを表します。 +</p> + </td> + </tr> +<!-- DEPRECATED + <tr> + <td>Screen dimensions</td> + <td>Examples:<br/> + <code>320x240</code><br/> + <code>640x480</code><br/> + etc. + </td> + <td> + <p>The larger dimension must be specified first. <strong>This configuration is deprecated +and should not be used</strong>. Instead use "screen size," "wider/taller screens," and "screen +orientation" described above.</p> + </td> + </tr> +--> + <tr id="VersionQualifier"> + <td>プラットフォーム バージョン(API レベル)</td> + <td>例: <br/> + <code>v3</code><br/> + <code>v4</code><br/> + <code>v7</code><br/> + など</td> + <td> + <p>端末がサポートする API レベル。たとえば、<code>v1</code> は API レベル 1(Android 1.0 以降の端末)、<code>v4</code> は API レベル 4(Android 1.6 以降の端末)となります。 + +これらの値の詳細については、「<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">Android API levels</a>」のドキュメントをご覧ください。 +</p> + </td> + </tr> +</table> + + +<p class="note"><strong>注:</strong> Android 1.0 以降、いくつかの設定識別子が追加されているため、すべてのバージョンの Android がすべての識別子をサポートしているわけではありません。 +新しい識別子を使用すると、旧式の端末がその識別子を無視できるように、プラットフォーム バージョンの識別子が暗黙的に追加されます。 +たとえば、available-width の識別子は API レベル 13 で新たに追加されたため、<code>w600dp</code> 識別子を使用すると、自動的に <code>v13</code> 識別子が追加されます。 + +問題を回避するために、常に一連のデフォルト リソースを含めるようにします(識別子のない一連のリソース)。<em></em> +詳細は、<a href="#Compatibility">リソースとの最適な端末の互換性を提供する</a>セクションをご覧ください。 + +</p> + + + +<h3 id="QualifierRules">修飾子の名前のルール</h3> + +<p>ここでは、設定修飾子の名前の使用方法に関するルールを説明します。</p> + +<ul> + <li>リソースの 1 つのセットに複数の修飾子を指定できます。その場合は、ダッシュで区切ります。たとえば、<code>drawable-en-rUS-land</code> は画面が横向きの米国英語の端末に適用されます。 + +</li> + <li>識別子は<a href="#table2">表 2</a> の順番で使用します。次に例を示します。 + + <ul> + <li>誤: <code>drawable-hdpi-port/</code></li> + <li>正: <code>drawable-port-hdpi/</code></li> + </ul> + </li> + <li>代替リソースのディレクトリはネストできません。<code>res/drawable/drawable-en/</code> などは使用できません。 +</li> + <li>値は大文字と小文字を区別します。大文字と小文字を区別するファイル システムの問題を回避するために、処理前にリソース コンパイラーがディレクトリ名を小文字に変換します。 + +読みやすくする場合にのみ、名前に大文字を使用します。</li> + <li>それぞれの修飾子タイプに使用できる値は 1 つだけです。たとえば、スペインとフランスの両方に同じドローアブル ファイルを使用する場合も、ディレクトリ名を <code>drawable-rES-rFR/</code> とすることはできません。<em></em> + +その代わりに、該当するファイルを含む <code>drawable-rES/</code> と <code>drawable-rFR/</code> という名前の 2 つのリソース ディレクトリが必要になります。ただし、実際のところ、両方の場所で同じファイルを重複させる必要はありません。 + +代わりに、リソースのエイリアスを作成できます。 +後述の<a href="#AliasResources">エイリアス リソースを作成する</a>をご覧ください。 +</li> +</ul> + +<p>これらの修飾子を名前に持つディレクトリに代替リソースを保存すると、現在の端末設定に基づいて、Android がアプリケーションにリソースを自動的に適用します。 + +リソースが要求されるたびに、Android は要求されたリソース ファイルを持つ代替リソース ディレクトリを探し、<a href="#BestMatch">最適なリソースを見つけます</a>(後述)。 + +特定の端末設定に合う代替リソースがない場合、Android は対応するデフォルト リソース(設定識別子を含まない特定のリソースタイプ用の一連のリソース)を使用します。 + + +</p> + + + +<h3 id="AliasResources">エイリアス リソースを作成する</h3> + +<p>複数の端末で使用するリソースがある場合(ただし、デフォルト リソースとして提供しない場合)、同じリソースを複数の代替リソース ディレクトリに配置する必要はありません。 + +その代わりに、(場合によっては)デフォルト リソースのディレクトリに保存したリソースのエイリアスとして機能する代替リソースを作成できます。 + +</p> + +<p class="note"><strong>注:</strong> すべてのリソースに、別のリソースへのエイリアスを作成できるメカニズムが備わっているわけではありません。 +特に、アニメーション、メニュー、未加工、{@code xml/} で指定されていないその他のリソースにはこの機能を使用できません。 +</p> + +<p>たとえば、アプリケーション アイコン {@code icon.png} について、ロケールごとに一意のバージョンが必要になるという状況を考えてみます。 +ただし、英語カナダとフランス語カナダの 2 つのロケールでは同じバージョンを使用する必要があります。 +英語カナダとフランス語カナダの両方のリソース ディレクトリに同じ画像をコピーする必要は実際にはありません。 + +代わりに、両方に使用する画像を {@code icon_ca.png} という名前({@code icon.png} 以外の名前)で保存し、デフォルトの {@code res/drawable/} ディレクトリに配置します。 + +次に {@code <bitmap>} 要素を使用して {@code icon_ca.png} リソースを参照する {@code icon.xml} ファイルを {@code +res/drawable-en-rCA/} と {@code res/drawable-fr-rCA/} に作成します。 +これにより、PNG ファイルを 1 つだけ作成し、それを指す小さな XML ファイルを 2 つ作成するだけで済みます +(次に、XML ファイルの例を示します)。</p> + + +<h4>ドローアブル</h4> + +<p>既存のドローアブルのエイリアスを作成するには、{@code <bitmap>} 要素を使用します。次に例を示します。 +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<bitmap xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/icon_ca" /> +</pre> + +<p>このファイルを {@code icon.xml} として({@code res/drawable-en-rCA/} などの代替リソース ディレクトリに)保存すると、{@code R.drawable.icon} として参照可能なリソースにコンパイルされますが、実際のところ、これは({@code res/drawable/} に保存されている){@code +R.drawable.icon_ca} リソースのエイリアスです。 + +</p> + + +<h4>レイアウト</h4> + +<p>既存のレイアウトのエイリアスを作成するには、{@code <merge>} にラップされる {@code <include>} 要素を使用します。 +次に例を示します。</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<merge> + <include layout="@layout/main_ltr"/> +</merge> +</pre> + +<p>このファイルを {@code main.xml} として保存すると、{@code R.layout.main} として参照可能なリソースにコンパイルされますが、実際のところ、これは {@code R.layout.main_ltr} リソースのエイリアスです。 + +</p> + + +<h4>文字列とその他の単純な値</h4> + +<p>既存の文字列のエイリアスを作成するには、単に、目的の文字列のリソース ID を新しい文字列の値として使用します。 +次に例を示します。</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="hello">Hello</string> + <string name="hi">@string/hello</string> +</resources> +</pre> + +<p>{@code R.string.hi} リソースは {@code R.string.hello} のエイリアスになりました。</p> + +<p> <a href="{@docRoot}guide/topics/resources/more-resources.html">その他の単純な値</a>も同様に機能します。 +次に色の例を示します。</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="yellow">#f00</color> + <color name="highlight">@color/red</color> +</resources> +</pre> + + + + +<h2 id="Compatibility">リソースとの最適な端末の互換性を提供する</h2> + +<p>アプリケーションで複数の端末設定をサポートするには、アプリケーションが使用するそれぞれのタイプのリソースに常にデフォルト リソースを提供することが重要です。 +</p> + +<p>たとえば、アプリケーションが複数の言語をサポートする場合は、<a href="#LocaleQualifier">言語と地域の修飾子</a>を<em>持たない</em> {@code +values/} ディレクトリ(文字列の保存先)を常に用意します。すべての文字列ファイルをすべて言語と地域の修飾子を持つディレクトリに配置してしまうと、自分の文字列がサポートしていない言語に設定された端末でアプリケーションを実行すると、アプリケーションがクラッシュしてしまいます。 + +ただし、デフォルトの {@code values/} リソースを提供しておけば、アプリケーションは適切に実行されます(ユーザーがその言語を理解できない場合でも。—クラッシュは避けられます)。 + +</p> + +<p>同様に、画面の向きに基づいた異なるレイアウト リソースを提供する場合も、いずれかの方向をデフォルトに設定する必要があります。 +たとえば、横向きの {@code +layout-land/} と縦向きの {@code layout-port/} にレイアウト リソースを提供する代わりに、横向きの {@code layout/} と縦向きの {@code layout-port/} のようなリソースをデフォルトとして保存しておきます。 +</p> + +<p>予測しなかった設定でアプリケーションが実行されるだけでなく、新しいバージョンの Android では古いバージョンではサポートされない設定修飾子が追加されることもあるため、デフォルト リソースの提供が重要になります。 + +新しいリソース修飾子を使用するが、古いバージョンの Android とのコードの互換性を保持する場合、古いバージョンの Android でアプリケーションを実行するときにデフォルト リソースが提供されていないと、古いバージョンの Android では新しい修飾子の付いたリソースを使用できないために、アプリケーションがクラッシュします。 + + +たとえば、<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code +minSdkVersion}</a> が 4 に設定されている場合に、<a href="#NightQualifier">ナイトモード</a>(API レベル 8 で追加された {@code night} または {@code notnight})を使用してすべてのドローアブル リソースの修飾子を設定すると、API レベル 4 端末はドローアブル リソースにアクセスできず、クラッシュします。 +この場合、{@code notnight} をデフォルト リソースにする場合、その修飾子を除外することになるため、ドローアブル リソースは {@code drawable/} または {@code drawable-night/} のいずれかになります。 + +</p> + +<p>そこで、端末の最適な互換性を提供するには、アプリケーションを適切に実行するのに必要なリソースに常にデフォルト リソースを提供するようにします。 +次に、設定修飾子を使用して、特定の端末設定向けの代替リソースを作成します。 +</p> + +<p>このルールには次の例外があります。アプリケーションの <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> が 4 以上の場合、<a href="#DensityQualifier">画像密度</a>修飾子で代替のドローアブル リソースを提供するときには、デフォルトのドローアブル リソースを提供する必要はありません。<em></em> + +デフォルトのドローアブル リソースがない場合でも、Android は代替の画面密度のなかで最適なものを見つけて、必要に応じてビットマップのサイズを変更できます。 + +ただし、すべてのタイプに最適な操作性を提供するには、密度の 3 つのタイプすべてに代替ドローアブルを提供する必要があります。 +</p> + + + +<h2 id="BestMatch">Android が最適なリソースを見つける仕組み</h2> + +<p>代替を提供するリソースを要求すると、現在の端末設定に応じて Android が実行時に使用する代替リソースを選択します。 +Android が代替リソースを選択する方法説明するために、次のドローアブル ディレクトリを想定します。それぞれに同じ画像の異なるバージョンが入っています。 + +</p> + +<pre class="classic no-pretty-print"> +drawable/ +drawable-en/ +drawable-fr-rCA/ +drawable-en-port/ +drawable-en-notouch-12key/ +drawable-port-ldpi/ +drawable-port-notouch-12key/ +</pre> + +<p>さらに、次のような端末設定を想定します。</p> + +<p style="margin-left:1em;"> +ロケール = <code>en-GB</code> <br/> +画面の向き = <code>port</code> <br/> +画面ピクセル密度 = <code>hdpi</code> <br/> +タッチスクリーン タイプ = <code>notouch</code> <br/> +主なテキストの入力方法 = <code>12key</code> +</p> + +<p>端末設定を使用可能な代替リソースに比較して、Android は {@code drawable-en-port} からドローアブルを選択します。 +</p> + +<p>システムは、次のロジックを使用して、使用するリソースを決定します。 +</p> + + +<div class="figure" style="width:371px"> +<img src="{@docRoot}images/resources/res-selection-flowchart.png" alt="" height="471" /> +<p class="img-caption"><strong>図 2.</strong> Android が最適なリソースを見つける仕組みを示したフローチャート。 +</p> +</div> + + +<ol> + <li>端末設定に矛盾するリソース ファイルを排除します。 + <p><code>en-GB</code> ロケールに矛盾するため、<code>drawable-fr-rCA/</code> ディレクトリが排除されます。 +</p> +<pre class="classic no-pretty-print"> +drawable/ +drawable-en/ +<strike>drawable-fr-rCA/</strike> +drawable-en-port/ +drawable-en-notouch-12key/ +drawable-port-ldpi/ +drawable-port-notouch-12key/ +</pre> +<p class="note"><strong>例外:</strong> 画面ピクセル密度は、矛盾により排除されない修飾子の 1 つです。 +それぞれの画面密度はその時点で最適であると判断されたものであるため、端末の画面密度が hdpi の場合でも、<code>drawable-port-ldpi/</code> は排除されません。 + +詳細は、「<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>」のドキュメントをご覧ください。 +</p></li> + + <li>リスト(<a href="#table2">表 2</a>)にある(次に)優先される修飾子を選択します(MCC から順に下がっていきます)。 + </li> + <li>この修飾子を含むリソース ディレクトリがあるかどうかを確認します。 </li> + <ul> + <li>ない場合は、ステップ 2 に戻り、次の修飾子を調べます(この例では、言語識別子になるまですべて「いいえ」になります)。 +</li> + <li>「はい」の場合は、ステップ 4 に進みます。</li> + </ul> + </li> + + <li>この修飾子を持たないリソース ディレクトリを排除します。この例では、システムによって言語修飾子を含まないすべてのディレクトリが排除されます。 +</li> +<pre class="classic no-pretty-print"> +<strike>drawable/</strike> +drawable-en/ +drawable-en-port/ +drawable-en-notouch-12key/ +<strike>drawable-port-ldpi/</strike> +<strike>drawable-port-notouch-12key/</strike> +</pre> +<p class="note"><strong>例外:</strong> 対象となる修飾子が画面ピクセル密度の場合、Android は端末の画像密度に最も近いオプションを選択します。一般的に、Android では小さな元画像を拡大するよりも、大きな元画像を縮小する方法が使用されます。 + + +「<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>」をご覧ください。 +</p> + </li> + + <li>残るディレクトリが 1 つになるまで、元に戻ってステップ 2、3、4 を繰り返します。このレイでは、次にマッチングするのが画面の向きの修飾子です。そのため、画面の向きを指定しないリソースは排除されます。 + + +<pre class="classic no-pretty-print"> +<strike>drawable-en/</strike> +drawable-en-port/ +<strike>drawable-en-notouch-12key/</strike> +</pre> +<p>{@code drawable-en-port} ディレクトリが残ります。</p> + </li> +</ol> + +<p>この手順は要求した各リソースに対して実行されますが、システムはさらにいくつかの最適化を行います。 +たとえば、端末の設定が判明すると、マッチングしない代替リソースが排除されたりします。 +たとえば、設定言語が英語(「en」)の場合、言語修飾子が英語以外に設定されているリソース ディレクトリはチェック対象のリソースのプールに入ることはありません(言語修飾子のないリソース ディレクトリはそのままプールに入ります)。<em></em> + + +</p> + +<p>画面サイズ修飾子に基づいてリソースを選択する場合、最適なリソースがない場合、システムは現在の画面よりも小さな画面向けのリソースを使用します(たとえば、必要に応じて大きなサイズの画面が通常サイズの画面のリソースを使用します)。 + +ただし、使用できるリソースが現在の画面よりも大きなサイズのものしかない場合は、システムはそれらのリソースを<strong>使用せず</strong>、端末設定にあるその他のリソースがないときは、アプリケーションがクラッシュします(たとえば、すべてのリソースに {@code xlarge} 識別子のタグが付いているが、端末は通常サイズの画面である場合)<em></em> + + + +</p> + +<p class="note"><strong>注:</strong> (<a href="#table2">表 2</a> の)上位にある修飾子の方が、端末に正確に一致する修飾子の数よりも重要になります。<em></em> +たとえば、上のステップ 4 では、<code>drawable-en</code> には一致するパラメータが 1 つしかありませんが(言語)、リストの最後の選択肢には、端末に正確に一致する修飾子が 3 つあります(画面の向き、タッチスクリーン タイプ、入力方法)。 + + +ただし、言語はこれらの他の修飾子よりも優先されるため、<code>drawable-port-notouch-12key</code> は排除されます。 +</p> + +<p>アプリケーションでのリソースの使用方法については、「<a href="accessing-resources.html">リソースへのアクセス</a>」をご覧ください。</p> diff --git a/docs/html-intl/intl/ja/guide/topics/resources/runtime-changes.jd b/docs/html-intl/intl/ja/guide/topics/resources/runtime-changes.jd new file mode 100644 index 000000000000..9bce95aee115 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/resources/runtime-changes.jd @@ -0,0 +1,281 @@ +page.title=実行時の変更の処理 +page.tags=アクティビティ,ライフサイクル +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + + <h2>本書の内容</h2> + <ol> + <li><a href="#RetainingAnObject">構成の変更中にオブジェクトを保持する</a></li> + <li><a href="#HandlingTheChange">構成の変更を自分で処理する</a> + </ol> + + <h2>関連ドキュメント</h2> + <ol> + <li><a href="providing-resources.html">リソースの提供</a></li> + <li><a href="accessing-resources.html">リソースへのアクセス</a></li> + <li><a href="http://android-developers.blogspot.com/2009/02/faster-screen-orientation-change.html">Faster + Screen Orientation Change</a></li> + </ol> +</div> +</div> + +<p>端末の構成の中には、実行時に変化するものがあります(画面の向き、キーボードの可用性、言語など)。 +そのような変更が発生すると、Android は実行中の {@link android.app.Activity} を再起動します({@link android.app.Activity#onDestroy()} が呼び出され、その後に{@link +android.app.Activity#onCreate(Bundle) onCreate()} が呼び出されます)。 + +再起動の動作は、新しい端末構成に一致する代替リソースを使用してアプリケーションを自動的にリロードすることで、アプリケーションを新しい構成に適応させることを目的としています。 + +</p> + +<p>再起動を適切に処理するには、アクティビティが通常の<a href="{@docRoot}guide/components/activities.html#Lifecycle">アクティビティのライフサイクル</a>を通じて事前の状態を格納することが重要です。その場合、アプリケーションの状態に関するデータを保存できるように、Android はアクティビティを破棄する前に {@link android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} を呼び出します。 + + + +その後、{@link android.app.Activity#onCreate(Bundle) onCreate()} か {@link +android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()} の際に状態を格納できます。 +</p> + +<p>アプリケーション自体がそのままの状態で再起動することをテストするには、アプリケーションでさまざまなタスクを実行中に、構成の変更(画面の向きの変更など)を呼び出す必要があります。 + +構成の変更を処理したり、ユーザーが電話を着信し、アプリケーション プロセスが破棄されるほど時間が経過してからアプリケーションに戻ったりするような場合には、ユーザーデータや状態を失うことなくいつでもアプリケーションを再起動できるようにする必要があります。 + + +アクティビティの状態を格納する方法については、「<a href="{@docRoot}guide/components/activities.html#Lifecycle">アクティビティのライフサイクル</a>」をご覧ください。</p> + +<p>ただし、場合によっては、アプリケーションを再起動すると、大量のデータの復元にコストがかかり、操作性が悪くなることがあります。 +そのような場合、次の 2 つの方法で処理できます。 +</p> + +<ol type="a"> + <li><a href="#RetainingAnObject">構成の変更中にオブジェクトを保持する</a> + <p>構成の変更時にアクティビティを再起動できますが、ステートフル オブジェクトがアクティビティの新しいインスタンスに移動します。 +</p> + + </li> + <li><a href="#HandlingTheChange">構成の変更を自分で処理する</a> + <p>特定の構成変更の際に、システムがアクティビティを再起動しないようにしますが、必要に応じてアクティビティをアップデートできるように、構成が変更された場合には、コールバックを受け取ります。 + +</p> + </li> +</ol> + + +<h2 id="RetainingAnObject">構成の変更中にオブジェクトを保持する</h2> + +<p>アクティビティの再起動で大量のデータの復元、ネットワーク接続の再構築、他の負荷のかかる操作の実行が必要になる場合、構成変更のために完全な再起動を実行すると、操作性が悪くなってしまうことがあります。 + +さらに、システムの {@link +android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} コールバックによって保存される {@link android.os.Bundle} を使用して、アクティビティの状態を完全に復元できない場合もあります。—大きなオブジェクト(ビットマップなど)を扱うためのものではなく、内部のデータをシリアル化してから逆シリアル化を行うため、多くのメモリを消費することになり、構成の変更に時間がかかってしまいます。 + + +そのような場合、構成の変更によるアクティビティの再起動の際に、{@link +android.app.Fragment} を保持することで、再初期化の負担を軽減できます。 +このフラグメントには、保持しておきたいステートフル オブジェクトへの参照を含めることができます。 +</p> + +<p>構成変更により Android システムがアクティビティをシャットダウンするとき、保持するためのマークを設定しておくと、アクティビティのフラグメントが破棄されません。 +ステートフル オブジェクトを保持するために、アクティビティにこのようなフラグメントを追加しておくことができます。 +</p> + +<p>実行時の構成変更の際に、フラグメントにステートフル オブジェクトを保持するには:</p> + +<ol> + <li>{@link android.app.Fragment} クラスを拡張し、ステートフル オブジェクトへの参照を宣言します。 +</li> + <li>フラグメントを作成するときに、{@link android.app.Fragment#setRetainInstance(boolean)} を呼び出します。 + </li> + <li>フラグメントをアクティビティに追加します。</li> + <li>アクティビティの再起動時にフラグメントを取得するには、{@link android.app.FragmentManager} を使用します。 +</li> +</ol> + +<p>次は、フラグメントの定義の例です。</p> + +<pre> +public class RetainedFragment extends Fragment { + + // data object we want to retain + private MyDataObject data; + + // this method is only called once for this fragment + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // retain this fragment + setRetainInstance(true); + } + + public void setData(MyDataObject data) { + this.data = data; + } + + public MyDataObject getData() { + return data; + } +} +</pre> + +<p class="caution"><strong>警告:</strong> オブジェクトの格納が可能な間は、{@link +android.graphics.drawable.Drawable}、{@link android.widget.Adapter}、{@link android.view.View}、さらには {@link android.content.Context} に関連付けられているその他のオブジェクトのように、{@link android.app.Activity} に結び付いたオブジェクトを渡さないようにしてください。 + +オブジェクトを渡すと、元のアクティビティ インスタンスのビューやリソースがすべて漏えいしてしまいます +(リソースが漏えいすると、アプリケーションはリソースを保持しているがガーベジコレクションを実行できず、大量のメモリが失われてしまうことがあります)。 + +</p> + +<p>次に、{@link android.app.FragmentManager} を使用して、フラグメントをアクティビティに追加します。実行時に構成を変更する際にアクティビティを再び起動すると、フラグメントからデータ オブジェクトを取得できます。 + +次は、アクティビティの定義の例です。</p> + +<pre> +public class MyActivity extends Activity { + + private RetainedFragment dataFragment; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + // find the retained fragment on activity restarts + FragmentManager fm = getFragmentManager(); + dataFragment = (DataFragment) fm.findFragmentByTag(“data”); + + // create the fragment and data the first time + if (dataFragment == null) { + // add the fragment + dataFragment = new DataFragment(); + fm.beginTransaction().add(dataFragment, “data”).commit(); + // load the data from the web + dataFragment.setData(loadMyData()); + } + + // the data is available in dataFragment.getData() + ... + } + + @Override + public void onDestroy() { + super.onDestroy(); + // store the data in the fragment + dataFragment.setData(collectMyLoadedData()); + } +} +</pre> + +<p>この例では、{@link android.app.Activity#onCreate(Bundle) onCreate()} がフラグメントを追加するか、フラグメントへの参照を復元します。さらに、{@link android.app.Activity#onCreate(Bundle) onCreate()} がステートフル オブジェクトをフラグメント インスタンスの内部に格納し、{@link android.app.Activity#onDestroy() onDestroy()} が保持しているフラグメント インスタンス内部のステートフル オブジェクトを更新します。 + + + +</p> + + + + + +<h2 id="HandlingTheChange">構成の変更を自分で処理する</h2> + +<p>アプリケーションに特定の構成の変更の際にリソースを更新する必要がなく、パフォーマンスの制限によりアクティビティの再起動を回避する必要がある場合は、構成の変更をアクティビティ自身が処理することを宣言します。そうすることで、システムによってアクティビティが再起動されなくなります。 +<em></em> + +</p> + +<p class="note"><strong>注:</strong> 構成の変更を自分で処理すると、変更がシステムによって自動的に適用されることがないため、代替リソースの使用が非常に難しくなります。 + +この手法は、構成の変更による再起動を回避する際の最後の手段として検討する手法です。ほとんどの場合、アプリケーションでの使用は推奨されません。 +</p> + +<p>アクティビティで構成の変更を処理することを宣言するには、マニフェスト ファイルの該当する <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 要素を編集し、処理する構成を表す値とともに <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code +android:configChanges}</a> 属性を配置します。 + +使用可能な値は、<a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code +android:configChanges}</a> 属性のドキュメントに一覧が記載されています(一般的には、画面の向きを変更した場合の再起動を回避するには {@code "orientation"} の値を、キーボードの可用性を変更した場合の再起動を回避するには {@code "keyboardHidden"} の値を使用します)。 + +パイプ記号の {@code |} 文字を使用して区切ることで、属性内に複数の構成値を宣言できます。 +</p> + +<p>たとえば、次のマニフェスト コードでは、画面の向きとキーボードの可用性の変更の両方を処理するアクティビティを宣言しています。 +</p> + +<pre> +<activity android:name=".MyActivity" + android:configChanges="orientation|keyboardHidden" + android:label="@string/app_name"> +</pre> + +<p>これで、これらのいずれかの構成が変更された場合でも、{@code MyActivity} が再起動することはなくなりました。代わりに、{@code MyActivity} が {@link +android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} への呼び出しを取得します。 +このメソッドには、新しい端末構成を指定する {@link android.content.res.Configuration} オブジェクトが渡されます。 + +{@link android.content.res.Configuration} のフィールドを読み込むことで新しい構成を判断し、インターフェースに使用するリソースを更新して適切に変更できます。 + +このメソッドが呼び出されると、アクティビティの {@link android.content.res.Resources} オブジェクトが更新され、新しい構成に基づいたリソースを返します。それにより、システムがアクティビティを再起動しなくても、UI の要素を簡単にリセットできます。 + + +</p> + +<p class="caution"><strong>警告:</strong> Android 3.2(API レベル 13)以降では、端末の画面の向きを縦から横に切り替えると、<strong>「画面サイズ」も変更されます</strong>。 + +そのため、API レベル 13 以降で開発を行う場合(<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> 属性と <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> 属性により宣言)、画面の向きによる実行時の再起動を回避するには、{@code "screenSize"} 値と一緒に {@code +"orientation"} 値を使用する必要があります。 + +つまり、{@code +android:configChanges="orientation|screenSize"} を宣言する必要があります。ただし、アプリケーションのターゲットが API レベル 12 以前の場合は、常にアクティビティ自身がこの構成の変更を処理します(Android 3.2 以降の端末で実行している場合でも、この構成の変更によりアクティビティが再起動されることはありません)。 + +</p> + +<p>たとえば、次の {@link +android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} の実装により現在の端末の画面の向きがチェックされます。 +</p> + +<pre> +@Override +public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + // Checks the orientation of the screen + if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { + Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); + } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ + Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); + } +} +</pre> + +<p>{@link android.content.res.Configuration} オブジェクトは、変更された構成を除く、現在のすべての構成を表します。 +ほとんどの場合、構成の変更内容を正確に把握する必要はなく、代替の構成を提供するすべてのリソースを処理中の構成に割り当て直します。 + +たとえば、現在は {@link +android.content.res.Resources} オブジェクトが更新されたため、任意の {@link android.widget.ImageView} を {@link android.widget.ImageView#setImageResource(int) +setImageResource()} でリセットでき、新しい構成には最適なリソースが使用されます(「<a href="providing-resources.html#AlternateResources">リソースの提供</a>」をご覧ください)。 + +</p> + +<p>{@link +android.content.res.Configuration} フィールドの値は、{@link android.content.res.Configuration} クラスの特定の定数に一致する整数であることにご注意ください。 +それぞれのフィールドで使用する定数に関するドキュメントについては、{@link +android.content.res.Configuration} リファレンスの該当するフィールドをご覧ください。 +</p> + +<p class="note"><strong>メモ:</strong> 構成の変更をアクティビティで処理することを宣言すると、代替を提供するすべての要素をリセットする操作が必要になります。 +画面の向きの変更を処理するアクティビティを宣言しており、縦向きと横向きで切り替わる画像がある場合、{@link +android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} の際にそれぞれの要素に各リソースを割り当て直す必要があります。 + +</p> + +<p>これらの構成の変更に基づいてアプリケーションを更新する必要がない場合は、代わりに <em></em>{@link +android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} を実装できません。 +このような場合、構成の変更前に使用していたすべてのリソースがそのまま使用され、アクティビティの再起動を回避した状態となります。 + +ただし、アプリケーションはいつでもシャットダウンして以前のままの状態で再起動できる状態にしておく必要があるため、通常のアクティビティのライフサイクルでは、状態を保持しない手段としてこの手法を使用しないようにします。 + +それは、アプリケーションの再起動を回避できない他の構成の変更があるだけでなく、ユーザーがアプリケーションを離れ、ユーザーがアプリケーションに戻る前に破棄されてしまうようなイベントを処理する必要があるためです。 + + +</p> + +<p>アクティビティで処理できる構成の変更についての詳細は、<a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code +android:configChanges}</a> のドキュメントと{@link android.content.res.Configuration} クラスをご覧ください。 +</p> diff --git a/docs/html-intl/intl/ja/guide/topics/ui/controls.jd b/docs/html-intl/intl/ja/guide/topics/ui/controls.jd new file mode 100644 index 000000000000..0bc2063764bb --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/ui/controls.jd @@ -0,0 +1,90 @@ +page.title=入力コントロール +parent.title=ユーザー インターフェース +parent.link=index.html +@jd:body + +<div class="figure" style="margin:0"> + <img src="{@docRoot}images/ui/ui-controls.png" alt="" style="margin:0" /> +</div> + +<p>入力コントロールは、アプリのユーザー インターフェースのインタラクティブなコンポーネントです。Android では、ボタン、テキスト フィールド、シークバー、チェックボックス、ズームボタン、トグルボタンなど UI で使用できるさまざまなコントロールが提供されています。 + +</p> + +<p>UI に入力コントロールを追加することは、<a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML レイアウト</a>に XML 要素を追加するのと同じくらい簡単です。テキスト フィールドとボタンを含むレイアウトの例を次に示します。 +</p> + +<pre style="clear:right"> +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="horizontal"> + <EditText android:id="@+id/edit_message" + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:hint="@string/edit_message" /> + <Button android:id="@+id/button_send" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/button_send" + android:onClick="sendMessage" /> +</LinearLayout> +</pre> + +<p>各入力コントロールでは、特定の一連の入力イベントがサポートされているため、ユーザーがテキストを入力したり、ボタンをタップしたりするときなどに、イベントを処理できます。 +</p> + + +<h2 id="CommonControls">コモン コントロール</h2> +<p>アプリで使用できるコモン コントロールには、次のようなものがあります。それぞれの使い方の詳細については、各リンクをご覧ください。 +</p> + +<p class="note"><strong>注:</strong> Android では、ここにリストされている以外にもいくつかコントロールが提供されています。 +他のコントロールについては、{@link android.widget} パッケージをご確認ください。アプリで、特定の種類の入力コントロールを必要とする場合、独自の <a href="{@docRoot}guide/topics/ui/custom-components.html">カスタム コンポーネント</a> をビルドできます。 +</p> + +<table> + <tr> + <th scope="col">コントロール タイプ</th> + <th scope="col">説明</th> + <th scope="col">関連クラス</th> + </tr> + <tr> + <td><a href="controls/button.html">ボタン</a></td> + <td>ユーザーがアクションを実行するために、押したり、クリックしたりできるプッシュボタン。</td> + <td>{@link android.widget.Button Button} </td> + </tr> + <tr> + <td><a href="controls/text.html">テキスト フィールド</a></td> + <td>編集できるテキスト フィールド。<code>AutoCompleteTextView</code> ウィジェットを使って、オートコンプリート候補を表示するテキスト入力ウィジェットを作成できます。</td> + <td>{@link android.widget.EditText EditText}、{@link android.widget.AutoCompleteTextView}</td> + </tr> + <tr> + <td><a href="controls/checkbox.html">チェックボックス</a></td> + <td>ユーザーが切り替えることができる、オン、オフスイッチ。相互に排他的ではない選択可能なオプションのグループをユーザーに表示するときは、チェックボックスを使ってください。</td> + <td>{@link android.widget.CheckBox CheckBox} </td> + </tr> + <tr> + <td><a href="controls/radiobutton.html">ラジオボタン</a></td> + <td>グループで選択できるオプションは 1 つのみであることを除き、チェックボックスと同様です。</td> + <td>{@link android.widget.RadioGroup RadioGroup} + <br>{@link android.widget.RadioButton RadioButton} </td> + </tr> + <tr> + <td><a href="controls/togglebutton.html" style="white-space:nowrap">トグルボタン</a></td> + <td>ライト インジケーター付きの、オン、オフボタン。</td> + <td>{@link android.widget.ToggleButton ToggleButton} </td> + </tr> + <tr> + <td><a href="controls/spinner.html">スピナー</a></td> + <td>ユーザーが一連の値から 1 つを選択できるドロップダウン リスト。</td> + <td>{@link android.widget.Spinner Spinner} </td> + </tr> + <tr> + <td><a href="controls/pickers.html">ピッカー</a></td> + <td>上下のボタンを使うか、スワイプして、1 つの値を選択するためのダイアログ。日付(月、日、年)の値を入力するには <code>DatePicker</code>code> ウィジェットを使い、時刻(時間、分、午前または午後)の値を入力するには <code>TimePicker</code> ウィジェットを使います。これにより、ユーザーのロケールが自動的に書式設定されます。</td> + <td>{@link android.widget.DatePicker}、{@link android.widget.TimePicker}</td> + </tr> +</table> diff --git a/docs/html-intl/intl/ja/guide/topics/ui/declaring-layout.jd b/docs/html-intl/intl/ja/guide/topics/ui/declaring-layout.jd new file mode 100644 index 000000000000..b0e9c03111fe --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/ui/declaring-layout.jd @@ -0,0 +1,492 @@ +page.title=レイアウト +page.tags=view,viewgroup +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>本書の内容</h2> +<ol> + <li><a href="#write">XML の記述</a></li> + <li><a href="#load">XML リソースの読み込み</a></li> + <li><a href="#attributes">属性</a> + <ol> + <li><a href="#id">ID</a></li> + <li><a href="#layout-params">レイアウト パラメータ</a></li> + </ol> + </li> + <li><a href="#Position">レイアウトの位置</a></li> + <li><a href="#SizePaddingMargins">サイズ、パディング、マージン</a></li> + <li><a href="#CommonLayouts">共通レイアウト</a></li> + <li><a href="#AdapterViews">アダプタを使ったレイアウトをビルドする</a> + <ol> + <li><a href="#FillingTheLayout">データを使ったアダプタビューを書き込む</a></li> + <li><a href="#HandlingUserSelections">クリック イベントを処理する</a></li> + </ol> + </li> +</ol> + + <h2>キークラス</h2> + <ol> + <li>{@link android.view.View}</li> + <li>{@link android.view.ViewGroup}</li> + <li>{@link android.view.ViewGroup.LayoutParams}</li> + </ol> + + <h2>関連ドキュメント</h2> + <ol> + <li><a href="{@docRoot}training/basics/firstapp/building-ui.html">簡単なユーザー インターフェースをビルドする</a> +</li> </div> +</div> + +<p>レイアウトでは、<a href="{@docRoot}guide/components/activities.html">アクティビティ</a>や<a href="{@docRoot}guide/topics/appwidgets/index.html">アプリ ウィジェット</a>の UI のような、ユーザー インターフェースの視覚的構造が定義されます。次の 2 つの方法でレイアウトを宣言できます。 +</p> +<ul> +<li><strong>XML で UI 要素を宣言する</strong>。Android では、ウィジェットやレイアウトなどの View クラスとサブクラスに対応する単純な XML ボキャブラリが提供されます。 +</li> +<li><strong>実行時にレイアウト要素のインスタンスを作成する</strong>。アプリケーションで View と ViewGroup オブジェクトを作成できます。また、プログラムを使ってプロパティを操作することもできます。 + </li> +</ul> + +<p>Android フレームワークでは、アプリケーション UI の宣言と管理に、これらのいずれかのメソッドまたは両方のメソッドを柔軟に使うことができます。たとえば、レイアウトに表示されるスクリーン要素やそのプロパティを含む、アプリケーションのデフォルト レイアウトを XML で宣言できます。スクリーン オブジェクトの状態を変更するコードをアプリケーション内で追加できます(実行時の XML での宣言を含む)。 </p> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <ul> + <li><a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin for Eclipse</a> では、XML ファイルを開いて [<strong>レイアウト</strong>] タブを選択すると、XML のレイアウト プレビューが提供されます。 + +</li> + <li>レイアウトのデバッグに、<a href="{@docRoot}tools/debugging/debugging-ui.html#hierarchyViewer">Hierarchy Viewer</a> ツールを使うこともできます。このツールでは、レイアウト プロパティ値の表示、パディングやマージンのインジケーターを使ったワイヤーフレームの描画、エミュレータや端末でデバッグする間のレンダリングされた全画面表示が提供されます。 + + + +</li> + <li><a href="{@docRoot}tools/debugging/debugging-ui.html#layoutopt">layoutopt</a> ツールを使うと、効率性の低下やその他の問題について、レイアウトや階層を素早く解析できます。 +</li> +</div> +</div> + +<p>XML で UI を宣言する利点は、動作を制御するコードとアプリケーションの表示をうまく切り離すことができる点です。UI の記述は、アプリケーション コード外にあるため、ソースコードの変更や再コンパイルをすることなく、記述を修正したり改良したりできます。たとえば、異なる画面の向き、端末の画面サイズ、言語に対して XML レイアウトを作成できます。XML でレイアウトを宣言すると、UI の構造を簡単に視覚化できるため、問題のデバッグも簡単です。そのため、本書では XML でレイアウトを宣言する方法を中心に説明しています。実行時に View オブジェクトのインスタンスを作成することに関心がある場合は、{@link android.view.ViewGroup} と {@link android.view.View} クラス参照をご覧ください。 + +</p> + +<p>通常、UI 要素を宣言する XML ボキャブラリは、クラスとメソッドの構造と命名に厳密に従っており、要素名はクラス名に、属性名はメソッドに対応しています。実際、ほとんどの場合、直接的に対応しているため、クラスメソッドに対応する XML 属性を推測したり、与えられた XML 要素に対応するクラスを推測したりできます。ただし、すべてのボキャブラリが同一とは限りません。場合によっては、命名が若干異なります。たとえば、EditText 要素には、<code>EditText.setText()</code> に対応する <code>text</code> 属性があります。 + + </p> + +<p class="note"><strong>ヒント:</strong> 異なるレイアウト タイプの詳細については、<a href="{@docRoot}guide/topics/ui/layout-objects.html">共通レイアウト オブジェクト</a>をご覧ください。 +また、<a href="{@docRoot}resources/tutorials/views/index.html">Hello Views</a> のチュートリアル ガイドには、さまざまなレイアウトのビルドに関するチュートリアルがあります。 +</p> + +<h2 id="write">XML の記述</h2> + +<p>Android の XML ボキャブラリを使って、HTML でウェブページを作成するのと同じ方法で(ネストした一連の要素を使って)、UI レイアウトとそれに含まれる画面要素を素早く設計できます。 </p> + +<p>各レイアウト ファイルには、必ず 1 つのルート要素が含まれていて、そのルート要素は View または ViewGroup オブジェクトでなくてはなりません。ルート要素を定義すれば、追加のレイアウト オブジェクトやウィジェットを子の要素として追加して、レイアウトを定義するビュー階層を少しずつビルドできます。{@link android.widget.TextView} と {@link android.widget.Button} を保持するために、縦方向の {@link android.widget.LinearLayout} を使用する XML レイアウトの例を次に示します。 +</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Hello, I am a TextView" /> + <Button android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Hello, I am a Button" /> +</LinearLayout> +</pre> + +<p>XML でレイアウトを宣言した後、そのファイルを Android プロジェクトの <code>res/layout/</code> ディレクトリ内で <code>.xml</code> 拡張子を付けて保存して、正しくコンパイルされるようにします。 + </p> + +<p>レイアウト XML ファイルの構文の詳細については、「<a href="{@docRoot}guide/topics/resources/layout-resource.html">Layout Resources</a>」のドキュメントをご覧ください。</p> + +<h2 id="load">XML リソースの読み込み</h2> + +<p>アプリケーションをコンパイルすると、各 XML レイアウト ファイルは {@link android.view.View} リソースにコンパイルされます。 +{@link android.app.Activity#onCreate(android.os.Bundle) Activity.onCreate()} コールバックの実装で、アプリケーション コードからレイアウト リソースを読み込んでください。これを行うには、<code>{@link android.app.Activity#setContentView(int) setContentView()}</code> を呼び出し、<code>R.layout.<em>layout_file_name</em></code> の形式でレイアウト リソースへの参照を渡します。たとえば、XML レイアウトが <code>main_layout.xml</code> として保存される場合、次のようにしてアクティビティに読み込みます。 + + + + + +</p> +<pre> +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main_layout); +} +</pre> + +<p>アクティビティの <code>onCreate()</code> コールバック メソッドは、アクティビティが起動されるときに、Android フレームワークによって呼び出されます(ライフサイクルに関する説明については、「<a href="{@docRoot}guide/components/activities.html#Lifecycle">アクティビティ</a>」のドキュメントをご覧ください)。 + + +</p> + + +<h2 id="attributes">属性</h2> + +<p>すべての View と ViewGroup オブジェクトでは、独自のさまざまな XML 属性がサポートされています。一部の属性は、View オブジェクト特有のものですが(たとえば TextView では <code>textSize</code> 属性がサポートされています)、これらの属性はこのクラスを拡張可能な View オブジェクトによっても継承されます。一部は、ルート View クラスから継承されるため、すべての View オブジェクトに共通します(<code>id</code> 属性のような)。 + + + +その他の属性は「レイアウト パラメータ」として考慮され、オブジェクトの親である ViewGroup オブジェクトとして定義された、View オブジェクトの特定のレイアウト方向を記述する属性となります。 + +</p> + +<h3 id="id">ID</h3> + +<p>ツリー内で View を一意に識別するために、すべての View オブジェクトには、それに関連付けられた整数の ID があることがあります。アプリケーションがコンパイルされると、この ID は整数として参照されますが、一般的にその ID は <code>id</code> 属性で文字列としてレイアウト XML ファイルに割り当てられます。これは、すべての View オブジェクトに共通の XML 属性で({@link android.view.View} クラスで定義)、非常に頻繁に使用されます。XML タグ内の ID の構文を次に示します。 + + + + +</p> +<pre>android:id="@+id/my_button"</pre> + +<p>文字列の先頭にあるアットマーク(@)は、その XML パーサーが ID の残りの文字列をパースして展開し、それを ID リソースとして識別する必要があることを示します。 +プラス記号(+)は、それが新しいリソース名で、作成してリソースに追加する(<code>R.java</code> ファイル内で)必要があることを意味しています。 +Android フレームワークによって提供されるその他のさまざまな ID リソースがあります。 +Android リソース ID を参照するときは、プラス記号を使う必要はありませんが、次のように <code>android</code> パッケージ名前空間を追加する必要があります。 +</p> +<pre>android:id="@android:id/empty"</pre> +<p><code>android</code> パッケージ名前空間付きの場合、ローカルのリソースクラスからではなく <code>android.R</code> リソースクラスから ID を参照するようになります。 +</p> + +<p>ビューを作成してアプリケーションからそれを参照するには、次のような共通のパターンがあります。</p> +<ol> + <li>レイアウト ファイルでビューとウィジェットを定義して、一意の ID を割り当てる。 +<pre> +<Button android:id="@+id/my_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/my_button_text"/> +</pre> + </li> + <li>次に、View オブジェクトのインスタンスを作成し、それを次のようにレイアウトから取得する(通常は、<code>{@link android.app.Activity#onCreate(Bundle) onCreate()}</code> メソッド内で)。 + +<pre> +Button myButton = (Button) findViewById(R.id.my_button); +</pre> + </li> +</ol> +<p>View オブジェクトの ID を定義することは、{@link android.widget.RelativeLayout} を作成するときに重要になります。相対レイアウトでは、兄弟ビューは一意の ID で参照される別の兄弟ビューに相対するレイアウトを定義できます。 + +</p> +<p>ツリー全体で ID が一意である必要はありませんが、探しているツリーの一部では、一意である必要があります。ほとんどの場合、それはツリー全体になりますが、可能な時に完全に一意になるようにすることが最善です。 + +</p> + + +<h3 id="layout-params">レイアウト パラメータ</h3> + +<p><code>layout_<em>something</em></code> という名前の XML レイアウト属性では、含まれている ViewGroup に適した View に対するレイアウト パラメータが定義されます。 +</p> + +<p>すべての ViewGroup クラスでは、{@link +android.view.ViewGroup.LayoutParams} を拡張するネストされたクラスが実装されます。このサブクラスには、各子ビューのサイズと位置を ViewGroup に合うように定義するプロパティ タイプが含まれています。 + +図 1 にあるように、親 ViewGroup によって、子 ViewGroup を含む、各子ビューのレイアウト パラメータが定義されます。 +</p> + +<img src="{@docRoot}images/layoutparams.png" alt="" /> +<p class="img-caption"><strong>図 1.</strong> 各ビューに関連付けられたレイアウトのパラメータを含むビュー階層の視覚化。 +</p> + +<p>すべての LayoutParams サブクラスには、設定値に独自の構文があります。 +それぞれの子の要素では、その親に適した LayoutParams が定義される必要がありますが、自分の子に対して異なる LayoutParams を定義することもできます。 + </p> + +<p>すべての ViewGroup には、幅と高さ(<code>layout_width</code> と <code>layout_height</code>)が含まれていて、各ビューでそれが定義されている必要があります。 +多くの LayoutParams には、省略可能なマージンと境界線も含まれています。 + <p> + +<p>必要になる頻度は少ない可能性はありますが、幅と高さを正確なサイズで指定することもできます。 +ほとんどの場合は、次の定数のいずれかを使って幅や高さを設定します。 + </p> + +<ul> + <li><var>wrap_content</var> では、ビューがそのコンテンツに必要な寸法に合わせられます。 +</li> + <li><var>match_parent</var> (API レベル 8 以前は <var>fill_parent</var> )では、ビューが親 ViewGroup で許容される最大サイズで表示されます。 +</li> +</ul> + +<p>通常、ピクセルなどの絶対単位でレイアウトの幅と高さを指定することは推奨されません。 + +密度非依存ピクセル単位(<var>dp</var>)、 <var>wrap_content</var>、 +<var>match_parent</var>などの相対測定を使う方が賢明です。そうすることで、さまざまな端末の画面サイズでアプリケーションが正しく表示されるようになります。使用可能な測定タイプは、「<a href="{@docRoot}guide/topics/resources/available-resources.html#dimension">使用可能なリソース</a>」のドキュメントで定義されています。 + + + +</p> + + +<h2 id="Position">レイアウトの位置</h2> + <p> + ビューの形状は、矩形です。ビューには、<em>左</em>と<em>上</em>の座標ペアで表される位置と、幅と高さで表される 2 次元があります。 + +位置と寸法の単位はピクセルです。 + + </p> + + <p> + {@link android.view.View#getLeft()} と {@link android.view.View#getTop()} メソッドを呼び出してビューの位置を取得できます。 +前者では、左またはビューを表す矩形の X 座標が返されます。 +後者では、上またはビューを表す矩形の Y 座標が返されます。 +これらのメソッドでは、両方とも親に相対するビューの位置が返されます。 +たとえば、<code>getLeft()</code> で 20 が返される場合、そのビューはその直属の親の左端から右に 20 ピクセルの位置にあることを意味します。 + + + </p> + + <p> + 他にも、{@link android.view.View#getRight()} や {@link android.view.View#getBottom()} といった不要な計算を回避するさまざまな便利なメソッドが提供されています。 + + これらのメソッドでは、ビューを表す矩形の右端と下端の座標が返されます。 +たとえば、{@link android.view.View#getRight()} を呼び出すことは、<code>getLeft() + getWidth()</code> の計算と同様です。 + + </p> + + +<h2 id="SizePaddingMargins">サイズ、パディング、マージン</h2> + <p> + ビューのサイズは、幅と高さで示します。実際に、ビューには幅と高さ 2 つの値がペアとして保持されています。 + + </p> + + <p> + 最初のペアは、<em>測定された幅</em>と<em>測定された高さ</em>と呼ばれます。 +これらの寸法で、その親内でのビューの大きさが定義されます。 +測定された寸法は、{@link android.view.View#getMeasuredWidth()} と {@link android.view.View#getMeasuredHeight()} を呼び出して取得できます。 + + + </p> + + <p> + 2 番目のペアは、単に<em>幅</em>と<em>高さ</em>と呼ばれたり、<em>描画する幅</em>と<em>描画する高さ</em>と呼ばれたりします。 +これらの寸法は、描画時とレイアウト後に、画面上のビューの実サイズを定義するものです。 + +これらの値は、測定された幅や高さと異なる値にすることもできますが、必須ではありません。 +幅と高さは、{@link android.view.View#getWidth()} と {@link android.view.View#getHeight()} を呼び出して取得できます。 + + </p> + + <p> + その寸法を測るために、ビューではパディングも考慮されます。パディングは、ビューの上下左右に対し、ピクセルで記述されます。 + + パディングを使って、特定のピクセル値でビュー コンテンツのオフセットを指定できます。 +たとえば、左側のパディングが 2 の場合は、左端から 2 ピクセル右にビューのコンテンツが寄せられます。 +パディングは {@link android.view.View#setPadding(int, int, int, int)} メソッドを使って設定でき、{@link android.view.View#getPaddingLeft()}、{@link android.view.View#getPaddingTop()}、{@link android.view.View#getPaddingRight()}、{@link android.view.View#getPaddingBottom()} を呼び出してクエリできます。 + + + + </p> + + <p> + ビューではパディングを定義できますが、マージンについてはサポートされていません。 +ただし、ViewGroup ではそのようなサポートが提供されています。詳細については、{@link android.view.ViewGroup} と {@link android.view.ViewGroup.MarginLayoutParams} をご覧ください。 + + + </p> + + <p>寸法の詳細については、<a href="{@docRoot}guide/topics/resources/more-resources.html#Dimension">寸法の値</a>をご覧ください。 + + </p> + + + + + + +<style type="text/css"> +div.layout { + float:left; + width:200px; + margin:0 0 20px 20px; +} +div.layout.first { + margin-left:0; + clear:left; +} +</style> + + + + +<h2 id="CommonLayouts">共通レイアウト</h2> + +<p>{@link android.view.ViewGroup} クラスの各サブクラスでは、ビュー内でネストするビューを表示する一意の方法が提供されます。 +Android プラットフォームにビルドされる共通のレイアウト タイプの一部を以下に示します。 +</p> + +<p class="note"><strong>注:</strong> 別のレイアウト内で 1 つ以上のレイアウトをネストして UI を設計できますが、レイアウトの階層はできる限り浅くしておくようにしてください。 + +ネストが浅いレイアウトの場合、レイアウトの描画がより速くなります。深いビュー階層より、ワイドなビュー階層の方がより良いと言えます。 +</p> + +<!-- +<h2 id="framelayout">FrameLayout</h2> +<p>{@link android.widget.FrameLayout FrameLayout} is the simplest type of layout +object. It's basically a blank space on your screen that you can +later fill with a single object — for example, a picture that you'll swap in and out. +All child elements of the FrameLayout are pinned to the top left corner of the screen; you cannot +specify a different location for a child view. Subsequent child views will simply be drawn over +previous ones, +partially or totally obscuring them (unless the newer object is transparent). +</p> +--> + + +<div class="layout first"> + <h4><a href="layout/linear.html">線形レイアウト</a></h4> + <a href="layout/linear.html"><img src="{@docRoot}images/ui/linearlayout-small.png" alt="" /></a> + <p>子を横方向または縦方向の 1 行にまとめるレイアウト。ウィンドウの長さが画面の長さを超える場合は、スクロールバーが作成されます。 +</p> +</div> + +<div class="layout"> + <h4><a href="layout/relative.html">相対レイアウト</a></h4> + <a href="layout/relative.html"><img src="{@docRoot}images/ui/relativelayout-small.png" alt="" /></a> + <p>たとえば子 A を子 B の左になど、それぞれの子オブジェクトの位置を相対して指定したり、親の上に揃えてなど、親に相対して指定したりできます。 +</p> +</div> + +<div class="layout"> + <h4><a href="{@docRoot}guide/webapps/webview.html">ウェブビュー</a></h4> + <a href="{@docRoot}guide/webapps/webview.html"><img src="{@docRoot}images/ui/webview-small.png" alt="" /></a> + <p>ウェブページを表示します。</p> +</div> + + + + +<h2 id="AdapterViews" style="clear:left">アダプタを使ったレイアウトをビルドする</h2> + +<p>レイアウトのコンテンツが動的または事前設定されていないとき、{@link android.widget.AdapterView} のサブクラスのレイアウトを使って、実行時にビューでレイアウトを設定できます。 +{@link android.widget.AdapterView} クラスのサブクラスでは、{@link android.widget.Adapter} を使ってそのレイアウトにデータがバインドされます。 + +{@link android.widget.Adapter} はデータソースと {@link android.widget.AdapterView} レイアウト間の仲介として動作します。{@link android.widget.Adapter} によって、配列やデータベース クエリのようなソースからデータが取得され、各エントリが {@link android.widget.AdapterView} レイアウトに追加できるビューに変換されます。 + + +</p> + +<p>アダプタでサポートされている共通レイアウトには次が含まれます。</p> + +<div class="layout first"> + <h4><a href="layout/listview.html">リストビュー</a></h4> + <a href="layout/listview.html"><img src="{@docRoot}images/ui/listview-small.png" alt="" /></a> + <p>スクロール可能な 1 列のリストが表示されます。</p> +</div> + +<div class="layout"> + <h4><a href="layout/gridview.html">グリッドビュー</a></h4> + <a href="layout/gridview.html"><img src="{@docRoot}images/ui/gridview-small.png" alt="" /></a> + <p>スクロール可能な列と行のグリッドが表示されます。</p> +</div> + + + +<h3 id="FillingTheLayout" style="clear:left">データを使ったアダプタビューを書き込む</h3> + +<p>{@link android.widget.AdapterView} インスタンスを {@link android.widget.Adapter} にバインドして、{@link android.widget.ListView} や {@link android.widget.GridView} などの {@link android.widget.AdapterView} を入力できます。外部ソースのデータが取得され、各データエントリを表す {@link +android.view.View} が作成されます。 + +</p> + +<p>Android ではさまざまな種類のデータの取得と {@link android.widget.AdapterView} のビューのビルドに役立つ {@link android.widget.Adapter} のサブクラスがいくつか提供されます。 +最も一般的なアダプタは次の 2 つです。 +</p> + +<dl> + <dt>{@link android.widget.ArrayAdapter}</dt> + <dd>データソースが配列の場合に、このアダプタを使います。デフォルトでは、{@link +android.widget.ArrayAdapter} によって各アイテムで {@link +java.lang.Object#toString()} が呼び出され、そのコンテンツが {@link +android.widget.TextView} に配置されることで、各配列アイテムのビューが作成されます。 + <p>たとえば、{@link +android.widget.ListView} に表示する文字列の配列がある場合、コンストラクタを使って新しい {@link android.widget.ArrayAdapter} を初期化して、各文字列と文字列配列のレイアウトを指定します。 +</p> +<pre> +ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, + android.R.layout.simple_list_item_1, myStringArray); +</pre> +<p>このコンストラクタの引数を次に示します。</p> +<ul> + <li>アプリの {@link android.content.Context}</li> + <li>配列の各文字列に対して {@link android.widget.TextView} を含むレイアウト</li> + <li>文字列配列</li> +</ul> +<p>次に、{@link android.widget.ListView} で {@link android.widget.ListView#setAdapter setAdapter()} を呼び出します。 +</p> +<pre> +ListView listView = (ListView) findViewById(R.id.listview); +listView.setAdapter(adapter); +</pre> + + <p>各アイテムの概観をカスタマイズするには、自分の配列内のオブジェクトに {@link +java.lang.Object#toString()} メソッドをオーバーライドします。または、たとえば各配列アイテムに {@link android.widget.ImageView} が必要な場合など、{@link android.widget.TextView} 以外の各アイテムの表示を作成するには、{@link +android.widget.ArrayAdapter} クラスを拡張し、{@link android.widget.ArrayAdapter#getView +getView()} をオーバーライドして、各アイテムに必要なビュータイプが返されるようにします。 + +</p> + +</dd> + + <dt>{@link android.widget.SimpleCursorAdapter}</dt> + <dd>{@link android.database.Cursor} から取得されたデータの場合は、このアダプタを使います。{@link android.widget.SimpleCursorAdapter} を使う場合は、{@link android.database.Cursor} で各行に使うレイアウトを指定して、{@link android.database.Cursor} のどの列をレイアウトのビューに挿入するのかを指定してください。 + + +たとえば、人の名前と電話番号のリストを作成する場合は、それぞれの人の行と、その名前と番号の列を含む {@link +android.database.Cursor} を返すクエリを実行します。 + +次に、それぞれの結果に対して {@link +android.database.Cursor} のどの列をレイアウトに含めるかを指定する文字列配列と、各列が配置されるべき対応するビューを指定する整数配列を作成します。 +</p> +<pre> +String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, + ContactsContract.CommonDataKinds.Phone.NUMBER}; +int[] toViews = {R.id.display_name, R.id.phone_number}; +</pre> +<p>{@link android.widget.SimpleCursorAdapter} のインスタンスを作成するとき、各結果に使うレイアウト、結果を含む {@link android.database.Cursor}、次の 2 つの配列を渡します。 +</p> +<pre> +SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, + R.layout.person_name_and_number, cursor, fromColumns, toViews, 0); +ListView listView = getListView(); +listView.setAdapter(adapter); +</pre> +<p>次に、{@link android.widget.SimpleCursorAdapter} によって、対応する {@code toViews} ビューに各 {@code +fromColumns} アイテムを挿入して提供されたレイアウトを使って {@link android.database.Cursor} で各行のビューが作成されます。 +</p>.</dd> +</dl> + + +<p>アプリケーションのライフサイクル中に、アダプタによって読み取られる基礎となるデータを変更する場合は、{@link android.widget.ArrayAdapter#notifyDataSetChanged()} を呼び出してください。 +これによって、データが変更されたアタッチされたビューが通知され、それ自体を更新する必要があることが通知されます。 +</p> + + + +<h3 id="HandlingUserSelections">クリック イベントを処理する</h3> + +<p>{@link android.widget.AdapterView.OnItemClickListener} インターフェースを実装して {@link android.widget.AdapterView} の各アイテムでのクリック イベントに応答できます。 +次に例を示します。</p> + +<pre> +// Create a message handling object as an anonymous class. +private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() { + public void onItemClick(AdapterView parent, View v, int position, long id) { + // Do something in response to the click + } +}; + +listView.setOnItemClickListener(mMessageClickedHandler); +</pre> + + + diff --git a/docs/html-intl/intl/ja/guide/topics/ui/dialogs.jd b/docs/html-intl/intl/ja/guide/topics/ui/dialogs.jd new file mode 100644 index 000000000000..358fc304f60a --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/ui/dialogs.jd @@ -0,0 +1,798 @@ +page.title=ダイアログ +page.tags=alertdialog,dialogfragment + +@jd:body + + + +<div id="qv-wrapper"> + <div id="qv"> + <h2>本書の内容</h2> +<ol> + <li><a href="#DialogFragment">Dialog Fragment を作成する</a></li> + <li><a href="#AlertDialog">アラート ダイアログをビルドする</a> + <ol> + <li><a href="#AddingButtons">ボタンを追加する</a></li> + <li><a href="#AddingAList">リストを追加する</a></li> + <li><a href="#CustomLayout">カスタム レイアウトを作成する</a></li> + </ol> + </li> + <li><a href="#PassingEvents">ダイアログのホストにイベントを渡す</a></li> + <li><a href="#ShowingADialog">ダイアログを表示する</a></li> + <li><a href="#FullscreenDialog">全画面でまたは埋め込まれたフラグメントとしてダイアログを表示する</a> + <ol> + <li><a href="#ActivityAsDialog">大画面でアクティビティをダイアログとして表示する</a></li> + </ol> + </li> + <li><a href="#DismissingADialog">ダイアログを閉じる</a></li> +</ol> + + <h2>キークラス</h2> + <ol> + <li>{@link android.app.DialogFragment}</li> + <li>{@link android.app.AlertDialog}</li> + </ol> + + <h2>関連ドキュメント</h2> + <ol> + <li><a href="{@docRoot}design/building-blocks/dialogs.html">ダイアログ デザインのガイド</a></li> + <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">ピッカー</a>(日付ダイアログと時刻ダイアログ)</li> + </ol> + </div> +</div> + +<p>ダイアログは、ユーザーによる意思決定や追加情報の入力用に表示される小さなウィンドウです。 +ダイアログは全画面に表示されることはなく、通常はユーザーが処理を続ける前にアクションを起こす必要があるモーダル イベントに使用されます。 +</p> + +<div class="note design"> +<p><strong>ダイアログ デザイン</strong></p> + <p>ダイアログをデザインする方法について(言語に対する推奨を含む)は、<a href="{@docRoot}design/building-blocks/dialogs.html">ダイアログ</a> デザインのガイドをお読みください。 +</p> +</div> + +<img src="{@docRoot}images/ui/dialogs.png" /> + +<p>{@link android.app.Dialog} クラスは、ダイアログの基本クラスですが、{@link android.app.Dialog} ディレクトリのインスタンスを作成することは避けてください。代わりに、次のいずれかのサブクラスを使用します。 + +</p> +<dl> + <dt>{@link android.app.AlertDialog}</dt> + <dd>タイトル、最大 3 つのボタン、選択可能なアイテムやカスタム レイアウトのリストを表示できるダイアログ。 +</dd> + <dt>{@link android.app.DatePickerDialog} または {@link android.app.TimePickerDialog}</dt> + <dd>ユーザーが日付または時刻を選択できるようにあらかじめ定義された UI を含むダイアログ。</dd> +</dl> + +<div class="sidebox"> +<h2>ProgressDialog を使用しない</h2> +<p>Android には、進捗バーを含むダイアログを表示する {@link android.app.ProgressDialog} という別のダイアログ クラスがあります。 +ただし、読み込み中または不確定な進捗状況を表示する必要がある場合は、<a href="{@docRoot}design/building-blocks/progress.html">Progress & Activity</a> のデザイン ガイドラインに従って、レイアウトで {@link android.widget.ProgressBar} を使用してください。 + + +</p> +</div> + +<p>これらのクラスでは、ダイアログのスタイルと構造が定義されますが、ダイアログのコンテナとして {@link android.support.v4.app.DialogFragment} を使用してください。{@link android.support.v4.app.DialogFragment} クラスでは、{@link android.app.Dialog} オブジェクトでメソッドを呼び出す代わりに、ダイアログの作成と表示の管理に必要なすべてのコントロールが提供されます。 + + + +</p> + +<p>{@link android.support.v4.app.DialogFragment} を使ってダイアログを管理すると、ライフサイクル イベント([<em>戻る</em>] ボタンを押したときや画面を回転したときなど)が正しく処理されます。 + +{@link +android.support.v4.app.DialogFragment} クラスを使用すると、従来の {@link +android.support.v4.app.Fragment} のように、大きな UI で埋め込み可能なコンポーネントとしてダイアログの UI を再利用することもできます(ダイアログ UI を大小の画面で異なって表示させる場合など)。 + +</p> + +<p>このガイドの次のセクションでは、{@link android.app.AlertDialog} オブジェクトと組み合わせて {@link +android.support.v4.app.DialogFragment} を使用する方法について説明します。 +日付や時刻ピッカーを作成する場合は、「<a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>」のガイドをご覧ください。 +</p> + +<p class="note"><strong>注:</strong> {@link android.app.DialogFragment} クラスは 元々 Android 3.0(API レベル 11)で追加されたため、このドキュメントでは<a href="{@docRoot}tools/support-library/index.html">サポート ライブラリ</a>と一緒に提供される {@link +android.support.v4.app.DialogFragment} クラスの使用方法について説明します。 + +アプリにこのライブラリを追加すると、Android 1.6 以降を実行する端末で、{@link android.support.v4.app.DialogFragment} とその他のさまざまな API を使うことができます。 + +アプリの最小バージョンで API レベル 11 以降がサポートされている場合、{@link +android.app.DialogFragment} のフレームワーク バージョンを使用できますが、このドキュメントのリンクはサポート ライブラリ API 向けであることにご注意ください。 + +サポート ライブラリを使用するときは、<code>android.app.DialogFragment</code> <em>ではなく</em>、<code>android.support.v4.app.DialogFragment</code> クラス をインポートしてください。 + +</p> + + +<h2 id="DialogFragment">Dialog Fragment を作成する</h2> + +<p>{@link android.support.v4.app.DialogFragment} を拡張して {@link android.support.v4.app.DialogFragment#onCreateDialog +onCreateDialog()} コールバック メソッドで {@link android.app.AlertDialog} を作成することで、さまざまなダイアログ デザイン(カスタム レイアウトや<a href="{@docRoot}design/building-blocks/dialogs.html">ダイアログ</a>のデザインガイドで説明されているものを含む)を実現できます。 + + + +</p> + +<p>{@link android.support.v4.app.DialogFragment} で管理される基本的な {@link android.app.AlertDialog} を次に示します。 +</p> + +<pre> +public class FireMissilesDialogFragment extends DialogFragment { + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Use the Builder class for convenient dialog construction + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setMessage(R.string.dialog_fire_missiles) + .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // FIRE ZE MISSILES! + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // User cancelled the dialog + } + }); + // Create the AlertDialog object and return it + return builder.create(); + } +} +</pre> + +<div class="figure" style="width:290px;margin:0 0 0 20px"> +<img src="{@docRoot}images/ui/dialog_buttons.png" alt="" /> +<p class="img-caption"><strong>図 1</strong> +メッセージと 2 つのアクション ボタンを含むダイアログ</p> +</div> + +<p>このクラスのインスタンスを作成してオブジェクトで {@link +android.support.v4.app.DialogFragment#show show()} を呼び出すと、図 1 のようなダイアログが表示されます。 +</p> + +<p>次のセクションでは、{@link android.app.AlertDialog.Builder} API を使ったダイアログの作成について詳細を説明します。 +</p> + +<p>ダイアログの複雑さに応じて、{@link android.support.v4.app.DialogFragment} ですべての基本的な<a href="{@docRoot}guide/components/fragments.html#Lifecycle">フラグメントのライフサイクル メソッド</a>を含む、他のさまざまなコールバック メソッドを実装できます。 + + + + + + + +<h2 id="AlertDialog">アラート ダイアログをビルドする</h2> + + +<p>{@link android.app.AlertDialog} クラスを使って、さまざまなダイアログ デザインをビルドできます。ほとんどの場合、必要なダイアログ クラスはこれだけです。図 2 のように、アラート ダイアログには 3 つの領域があります。 + +</p> + +<div class="figure" style="width:311px;margin-top:0"> +<img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0" /> +<p class="img-caption"><strong>図 2.</strong> ダイアログのレイアウト。</p> +</div> + +<ol> +<li><b>タイトル</b> + <p>この領域は省略可能で、コンテンツ エリアが詳細メッセージ、リスト、カスタム レイアウトで占有されている場合にのみ使う必要があります。 +単純なメッセージや質問(図 1 にあるダイアログなど)を記述する場合は、タイトルは必要ありません。 +</li> +<li><b>コンテンツ エリア</b> + <p>メッセージ、リスト、その他のカスタム レイアウトを表示できます。</p></li> +<li><b>アクション ボタン</b> + <p>1 つのダイアログ内に置くアクション ボタンは、3 つ以内にする必要があります。</p></li> +</ol> + +<p>{@link android.app.AlertDialog.Builder} クラスでは、カスタム レイアウトなど、これらの種類のコンテンツを含む {@link android.app.AlertDialog} を作成できます。 + +</p> + +<p>{@link android.app.AlertDialog} をビルドするには: </p> + +<pre> +<b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b> +AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + +<b>// 2. Chain together various setter methods to set the dialog characteristics</b> +builder.setMessage(R.string.dialog_message) + .setTitle(R.string.dialog_title); + +<b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b> +AlertDialog dialog = builder.create(); +</pre> + +<p>次のトピックでは、{@link android.app.AlertDialog.Builder} クラスを使ってさまざまなダイアログの属性を定義する方法を示します。 +</p> + + + + +<h3 id="AddingButtons">ボタンを追加する</h3> + +<p>図 2 のようなアクション ボタンを追加するには、{@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} と {@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()} メソッドを呼び出します。 + +</p> + +<pre style="clear:right"> +AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); +// Add the buttons +builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // User clicked OK button + } + }); +builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // User cancelled the dialog + } + }); +// Set other dialog properties +... + +// Create the AlertDialog +AlertDialog dialog = builder.create(); +</pre> + +<p><code>set...Button()</code> メソッドには、ボタンのタイトル(<a href="{@docRoot}guide/topics/resources/string-resource.html">文字列リソースで指定</a>)と、ユーザーがボタンを押したときに実行するアクションを定義する {@link android.content.DialogInterface.OnClickListener} が必要です。 + + +</p> + +<p>追加できるアクション ボタンは、次の 3 つです。</p> +<dl> + <dt>Positive</dt> + <dd>アクションを受け入れて続ける場合に使います(「OK」アクション)。</dd> + <dt>Negative</dt> + <dd>アクションをキャンセルする場合に使います。</dd> + <dt>Neutral</dt> + <dd>ユーザーがアクションを続けたくない可能性があり、キャンセルしたいとは限らない場合に使います。 +ポジティブ ボタンとネガティブ ボタンの間に表示されます。 +たとえば、「後で通知する」のようなアクションの場合です。</dd> +</dl> + +<p>各ボタンタイプのいずれか 1 つのみを {@link +android.app.AlertDialog} に追加できます。つまり、2 つ以上の「ポジティブ」ボタンを置くことはできません。</p> + + + +<div class="figure" style="width:290px;margin:0 0 0 40px"> +<img src="{@docRoot}images/ui/dialog_list.png" alt="" /> +<p class="img-caption"><strong>図 3</strong> +タイトルとリストを含むダイアログ</p> +</div> + +<h3 id="AddingAList">リストを追加する</h3> + +<p>{@link android.app.AlertDialog} API で使用できるリストは次の 3 種類です。</p> +<ul> +<li>従来の排他的選択リスト</li> +<li>固定の排他的選択リスト(ラジオボタン)</li> +<li>固定の複数選択リスト(チェックボックス)</li> +</ul> + +<p>図 3 のように、排他的選択リストを作成するには、{@link android.app.AlertDialog.Builder#setItems setItems()} メソッドを使います。 +</p> + +<pre style="clear:right"> +@Override +public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.pick_color) + .setItems(R.array.colors_array, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + // The 'which' argument contains the index position + // of the selected item + } + }); + return builder.create(); +} +</pre> + +<p>リストは、ダイアログのコンテンツ エリアに表示されるため、ダイアログにはメッセージとリストの両方は表示できません。{@link android.app.AlertDialog.Builder#setTitle setTitle()} でダイアログのタイトルを設定してください。 + +リストのアイテムを指定するには、{@link +android.app.AlertDialog.Builder#setItems setItems()} を呼び出して配列を渡します。{@link +android.app.AlertDialog.Builder#setAdapter setAdapter()} を使ってリストを指定することもできます。 + +こうすることで、{@link android.widget.ListAdapter} を使って、データベースからなど、ダイナミック データを含むリストを返すことができます。 +</p> + +<p>{@link android.widget.ListAdapter} を使ってリストを返すことを選択する場合は、必ず {@link android.support.v4.content.Loader} を使ってコンテンツが非同期で読み込まれるようにします。 + +この詳細については、「<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Building Layouts with an Adapter</a>」と「<a href="{@docRoot}guide/components/loaders.html">ローダ</a>」のガイドをご覧ください。 + + +</p> + +<p class="note"><strong>注:</strong> デフォルトでは、次の固定選択リストのいずれかを使っていない場合、リストアイテムをタップするとダイアログが閉じられます。 +</p> + +<div class="figure" style="width:290px;margin:-30px 0 0 40px"> +<img src="{@docRoot}images/ui/dialog_checkboxes.png" /> +<p class="img-caption"><strong>図 4.</strong>複数選択アイテムのリスト。 +</p> +</div> + + +<h4 id="Checkboxes">固定の複数選択または排他的選択リストを追加する</h4> + +<p>複数選択アイテム(チェックボックス)または排他的選択アイテム(ラジオボタン)のリストを追加するには、{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String, +DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} または {@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) +setSingleChoiceItems()} メソッドをそれぞれ使用します。 + + +</p> + +<p>{@link java.util.ArrayList} で選択されたアイテムを保存する、図 4 にあるような複数選択リストを作成する方法を次に示します。 + +</p> + +<pre style="clear:right"> +@Override +public Dialog onCreateDialog(Bundle savedInstanceState) { + mSelectedItems = new ArrayList(); // Where we track the selected items + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + // Set the dialog title + builder.setTitle(R.string.pick_toppings) + // Specify the list array, the items to be selected by default (null for none), + // and the listener through which to receive callbacks when items are selected + .setMultiChoiceItems(R.array.toppings, null, + new DialogInterface.OnMultiChoiceClickListener() { + @Override + public void onClick(DialogInterface dialog, int which, + boolean isChecked) { + if (isChecked) { + // If the user checked the item, add it to the selected items + mSelectedItems.add(which); + } else if (mSelectedItems.contains(which)) { + // Else, if the item is already in the array, remove it + mSelectedItems.remove(Integer.valueOf(which)); + } + } + }) + // Set the action buttons + .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + // User clicked OK, so save the mSelectedItems results somewhere + // or return them to the component that opened the dialog + ... + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + ... + } + }); + + return builder.create(); +} +</pre> + +<p>従来のリストとラジオボタンを含むリストでは、「排他的選択」アクションが提供されますが、ユーザーの選択を固定させたい場合は、{@link +android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) +setSingleChoiceItems()} を使用してください。つまり、ダイアログを後でもう一度開く場合は、ユーザーの現在の選択を表示し、ラジオボタンを含むリストを作成します。 + + +</p> + + + + + +<h3 id="CustomLayout">カスタム レイアウトを作成する</h3> + +<div class="figure" style="width:290px;margin:-30px 0 0 40px"> +<img src="{@docRoot}images/ui/dialog_custom.png" alt="" /> +<p class="img-caption"><strong>図 5.</strong> カスタム ダイアログのレイアウト。</p> +</div> + +<p>ダイアログでカスタム レイアウトが必要な場合は、レイアウトを作成し、{@link +android.app.AlertDialog.Builder} オブジェクトで {@link +android.app.AlertDialog.Builder#setView setView()} を呼び出して {@link android.app.AlertDialog} にそのレイアウトを追加します。 +</p> + +<p>デフォルトでは、カスタム レイアウトは、ダイアログ ウィンドウ全体に表示されますが、{@link android.app.AlertDialog.Builder} メソッドを使ってボタンとタイトルを追加できます。 +</p> + +<p>以下は、図 5 にあるダイアログのレイアウト ファイルです。</p> + +<p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p> +<pre> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + <ImageView + android:src="@drawable/header_logo" + android:layout_width="match_parent" + android:layout_height="64dp" + android:scaleType="center" + android:background="#FFFFBB33" + android:contentDescription="@string/app_name" /> + <EditText + android:id="@+id/username" + android:inputType="textEmailAddress" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:layout_marginLeft="4dp" + android:layout_marginRight="4dp" + android:layout_marginBottom="4dp" + android:hint="@string/username" /> + <EditText + android:id="@+id/password" + android:inputType="textPassword" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:layout_marginLeft="4dp" + android:layout_marginRight="4dp" + android:layout_marginBottom="16dp" + android:fontFamily="sans-serif" + android:hint="@string/password"/> +</LinearLayout> +</pre> + +<p class="note"><strong>ヒント:</strong> デフォルトでは、{@code "textPassword"} 入力タイプを使うために、{@link android.widget.EditText} 要素を設定すると、フォント ファミリーが monospace に設定されるため、フォント ファミリーを {@code "sans-serif"} に変えて、両方のテキスト フィールドで同じフォント スタイルが使用されるようにしてください。 + + +</p> + +<p>{@link android.support.v4.app.DialogFragment} でレイアウトをインフレートするには、{@link android.app.Activity#getLayoutInflater()} で {@link android.view.LayoutInflater} を取得して {@link android.view.LayoutInflater#inflate inflate()} を呼び出します。最初のパラメータは、レイアウト リソース ID で、2 番目のパラメータはレイアウトの親ビューです。その後、{@link android.app.AlertDialog#setView setView()} を呼び出してダイアログのレイアウトを配置できます。 + + + + + +</p> + +<pre> +@Override +public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + // Get the layout inflater + LayoutInflater inflater = getActivity().getLayoutInflater(); + + // Inflate and set the layout for the dialog + // Pass null as the parent view because its going in the dialog layout + builder.setView(inflater.inflate(R.layout.dialog_signin, null)) + // Add action buttons + .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + // sign in the user ... + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + LoginDialogFragment.this.getDialog().cancel(); + } + }); + return builder.create(); +} +</pre> + +<div class="note"> +<p><strong>ヒント:</strong> カスタム ダイアログが必要な場合は、{@link android.app.Dialog} API を使う代わりに、{@link android.app.Activity} をダイアログとして表示できます。 + +アクティビティを作り、<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a> マニフェスト要素でそのテーマを {@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog} に設定します。 + +</p> + +<pre> +<activity android:theme="@android:style/Theme.Holo.Dialog" > +</pre> +<p>これだけです。これで、アクティビティは全画面でなく、ダイアログ ウィンドウに表示されるようになります。</p> +</div> + + + +<h2 id="PassingEvents">ダイアログのホストにイベントを渡す</h2> + +<p>ユーザーがダイアログのアクション ボタンのいずれかをタップするか、そのリストからアイテムを選択すると、{@link android.support.v4.app.DialogFragment} によって必要なアクションが実行される場合がありますが、ダイアログを開くアクティビティやフラグメントにイベントを配信したい場合もよくあります。 + + +これを行うには、クリック イベントの各タイプのメソッドでインターフェースを定義します。次に、ダイアログからアクション イベントを受け取るホスト コンポーネントでインターフェースを実装します。 + +</p> + +<p>ホスト アクティビティにイベントを配信するインターフェースを定義する {@link android.support.v4.app.DialogFragment} を次に示します。 +</p> + +<pre> +public class NoticeDialogFragment extends DialogFragment { + + /* The activity that creates an instance of this dialog fragment must + * implement this interface in order to receive event callbacks. + * Each method passes the DialogFragment in case the host needs to query it. */ + public interface NoticeDialogListener { + public void onDialogPositiveClick(DialogFragment dialog); + public void onDialogNegativeClick(DialogFragment dialog); + } + + // Use this instance of the interface to deliver action events + NoticeDialogListener mListener; + + // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + // Verify that the host activity implements the callback interface + try { + // Instantiate the NoticeDialogListener so we can send events to the host + mListener = (NoticeDialogListener) activity; + } catch (ClassCastException e) { + // The activity doesn't implement the interface, throw exception + throw new ClassCastException(activity.toString() + + " must implement NoticeDialogListener"); + } + } + ... +} +</pre> + +<p>ダイアログをホスティングするアクティビティによって、ダイアログ フラグメントのコンストラクタを使ってダイアログのインスタンスが作成され、{@code NoticeDialogListener} インターフェースの実装によってダイアログのイベントが受信されます。 + +</p> + +<pre> +public class MainActivity extends FragmentActivity + implements NoticeDialogFragment.NoticeDialogListener{ + ... + + public void showNoticeDialog() { + // Create an instance of the dialog fragment and show it + DialogFragment dialog = new NoticeDialogFragment(); + dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); + } + + // The dialog fragment receives a reference to this Activity through the + // Fragment.onAttach() callback, which it uses to call the following methods + // defined by the NoticeDialogFragment.NoticeDialogListener interface + @Override + public void onDialogPositiveClick(DialogFragment dialog) { + // User touched the dialog's positive button + ... + } + + @Override + public void onDialogNegativeClick(DialogFragment dialog) { + // User touched the dialog's negative button + ... + } +} +</pre> + +<p>ホスト アクティビティによって、上記の {@link android.support.v4.app.Fragment#onAttach onAttach()} コールバック メソッドで適用される {@code NoticeDialogListener} が実装されるため、ダイアログ フラグメントではインターフェース コールバック メソッドを使ってアクティビティにクリック イベントを配信できます。 + + +</p> + +<pre> +public class NoticeDialogFragment extends DialogFragment { + ... + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Build the dialog and set up the button click handlers + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setMessage(R.string.dialog_fire_missiles) + .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // Send the positive button event back to the host activity + mListener.onDialogPositiveClick(NoticeDialogFragment.this); + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // Send the negative button event back to the host activity + mListener.onDialogNegativeClick(NoticeDialogFragment.this); + } + }); + return builder.create(); + } +} +</pre> + + + +<h2 id="ShowingADialog">ダイアログを表示する</h2> + +<p>ダイアログを表示する場合、{@link +android.support.v4.app.DialogFragment} のインスタンスを作成して {@link android.support.v4.app.DialogFragment#show +show()} を呼び出し、{@link android.support.v4.app.FragmentManager} とダイアログ フラグメントのタグ名を渡します。 +</p> + +<p>{@link android.support.v4.app.FragmentActivity} から {@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} を、または {@link +android.support.v4.app.Fragment} から {@link +android.support.v4.app.Fragment#getFragmentManager()} を呼び出して {@link android.support.v4.app.FragmentManager} を取得できます。 + +次に例を示します。</p> + +<pre> +public void confirmFireMissiles() { + DialogFragment newFragment = new FireMissilesDialogFragment(); + newFragment.show(getSupportFragmentManager(), "missiles"); +} +</pre> + +<p>2 番目の引数 {@code "missiles"} は、固有のタグ名で、システムはこれを使って必要な時にフラグメントの状態を保存して復元します。 +そのタグを使って、{@link android.support.v4.app.FragmentManager#findFragmentByTag +findFragmentByTag()} を呼び出してフラグメントを操作することもできます。 +</p> + + + + +<h2 id="FullscreenDialog">全画面でまたは埋め込まれたフラグメントとしてダイアログを表示する</h2> + +<p>場合によっては、UI の一部をダイアログとして表示させ、それ以外の場合には、たとえば端末の画面の大小に応じて、全画面や埋め込まれたフラグメントとして表示させるよう UI を設計できます。 + +{@link android.support.v4.app.DialogFragment} クラスは、埋め込み可能な {@link +android.support.v4.app.Fragment} として動作できるため、この柔軟性を実現できます。 +</p> + +<p>ただし、この場合は、{@link android.app.AlertDialog.Builder AlertDialog.Builder} やその他の {@link android.app.Dialog} オブジェクトを使ってダイアログをビルドできません。 +{@link android.support.v4.app.DialogFragment} を埋め込み可能にする場合、レイアウトでダイアログの UI を定義し、{@link android.support.v4.app.DialogFragment#onCreateView +onCreateView()} コールバックでレイアウトを読み込んでください。 + + +</p> + +<p>ダイアログまたは埋め込み可能なフラグメントのいずれかとして(<code>purchase_items.xml</code> という名前のレイアウトを使って)表示できる {@link android.support.v4.app.DialogFragment} の例を次に示します。 +</p> + +<pre> +public class CustomDialogFragment extends DialogFragment { + /** The system calls this to get the DialogFragment's layout, regardless + of whether it's being displayed as a dialog or an embedded fragment. */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout to use as dialog or embedded fragment + return inflater.inflate(R.layout.purchase_items, container, false); + } + + /** The system calls this only when creating the layout in a dialog. */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // The only reason you might override this method when using onCreateView() is + // to modify any dialog characteristics. For example, the dialog includes a + // title by default, but your custom layout might not need it. So here you can + // remove the dialog title, but you must call the superclass to get the Dialog. + Dialog dialog = super.onCreateDialog(savedInstanceState); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + return dialog; + } +} +</pre> + +<p>画面サイズに基づいて、フラグメントをダイアログとしてまたは全画面の UI として表示するかどうかを決めるコードの一例も示します。 +</p> + +<pre> +public void showDialog() { + FragmentManager fragmentManager = getSupportFragmentManager(); + CustomDialogFragment newFragment = new CustomDialogFragment(); + + if (mIsLargeLayout) { + // The device is using a large layout, so show the fragment as a dialog + newFragment.show(fragmentManager, "dialog"); + } else { + // The device is smaller, so show the fragment fullscreen + FragmentTransaction transaction = fragmentManager.beginTransaction(); + // For a little polish, specify a transition animation + transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); + // To make it fullscreen, use the 'content' root view as the container + // for the fragment, which is always the root view for the activity + transaction.add(android.R.id.content, newFragment) + .addToBackStack(null).commit(); + } +} +</pre> + +<p>フラグメントのトランザクション実行の詳細については、「<a href="{@docRoot}guide/components/fragments.html">フラグメント</a>」のガイドをご覧ください。 +</p> + +<p>この例では、<code>mIsLargeLayout</code> ブール値によって、現在の端末でアプリの大きなレイアウト デザインを使う(その結果、全画面でなく、このフラグメントをダイアログとして表示する)かどうかが指定されます。 + +この種のブール値を設定する最良の方法は、異なる画面サイズに対して<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">別のリソース値</a>で<a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">ブールリソース値</a>を宣言することです。 + +次に、異なる画面サイズのブールリソースを 2 種類示します。 +</p> + +<p class="code-caption">res/values/bools.xml</p> +<pre> +<!-- Default boolean values --> +<resources> + <bool name="large_layout">false</bool> +</resources> +</pre> + +<p class="code-caption">res/values-large/bools.xml</p> +<pre> +<!-- Large screen boolean values --> +<resources> + <bool name="large_layout">true</bool> +</resources> +</pre> + +<p>アクティビティの {@link android.app.Activity#onCreate onCreate()} メソッド中に、{@code mIsLargeLayout} 値を初期化できます。 +</p> + +<pre> +boolean mIsLargeLayout; + +@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + mIsLargeLayout = getResources().getBoolean(R.bool.large_layout); +} +</pre> + + + +<h3 id="ActivityAsDialog">大画面でアクティビティをダイアログとして表示する</h3> + +<p>小画面のときにダイアログを全画面の UI として表示するのではなく、大画面のときに {@link android.app.Activity} をダイアログとして表示することで、同じ結果を得ることができます。 + +どちらの方法を選択するかはアプリのデザインによって異なりますが、アプリが小画面で設計されていて、存在期間が短いアクティビティをダイアログとして示すことでタブレットでの使用感を改善するときには、ほとんどの場合、アクティビティをダイアログとして表示する方法が役立ちます。 + + +</p> + +<p>大画面のときにのみ、アクティビティをダイアログとして表示するには、{@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge} テーマを <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a> マニフェスト要素に適用します。 + +</p> + +<pre> +<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" > +</pre> + +<p>テーマを使ったアクティビティのスタイル指定についての詳細は、「<a href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>」をご覧ください。</p> + + + +<h2 id="DismissingADialog">ダイアログを閉じる</h2> + +<p>{@link android.app.AlertDialog.Builder} で作成したアクション ボタンのいずれかがタップされると、システムはダイアログを閉じます。 +</p> + +<p>また、リストでラジオボタンやチェックボックスが使われている場合を除き、ダイアログ リストでアイテムがタップされると、ダイアログが閉じます。 +それ以外の場合は、{@link +android.support.v4.app.DialogFragment} で {@link android.support.v4.app.DialogFragment#dismiss()} を呼び出してダイアログを手動で閉じることができます。 +</p> + +<p>ダイアログが閉じるときに、特定のアクションを実行する必要がある場合は、{@link +android.support.v4.app.DialogFragment} で {@link +android.support.v4.app.DialogFragment#onDismiss onDismiss()} メソッドを実装できます。 +</p> + +<p>ダイアログを<em>キャンセル</em>することもできます。これは、ユーザーがタスクを完了せずに、明示的にダイアログを離れたことを示す特別なイベントです。 +ユーザーが [<em>戻る</em>] ボタンを押す、ダイアログ領域外の画面をタップする、または開発者が {@link +android.app.Dialog} で明示的に {@link android.app.Dialog#cancel()} を呼び出す(ダイアログの [キャンセル] ボタンに応じてなど)場合に実行されます。 + +</p> + +<p>上記の例のように、{@link +android.support.v4.app.DialogFragment} クラスで {@link android.support.v4.app.DialogFragment#onCancel onCancel()} を実装してキャンセル イベントに応答できます。 +</p> + +<p class="note"><strong>注:</strong> システムによって、{@link android.support.v4.app.DialogFragment#onCancel onCancel()} コールバックを呼び出す各イベントで {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} が呼び出されます。 + +ただし、{@link android.app.Dialog#dismiss Dialog.dismiss()} や {@link +android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()} を呼び出す場合、システムによって {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} が呼び出されますが、{@link android.support.v4.app.DialogFragment#onCancel onCancel()} は<em>呼び出されません</em>。 + + +通常は、ユーザーがダイアログの<em>ポジティブ</em>ボタンを押すときに、{@link android.support.v4.app.DialogFragment#dismiss dismiss()} を呼び出して、ビューからダイアログが削除されるようにしてください。 + +</p> + + diff --git a/docs/html-intl/intl/ja/guide/topics/ui/menus.jd b/docs/html-intl/intl/ja/guide/topics/ui/menus.jd new file mode 100644 index 000000000000..7d8090e7a0ad --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/ui/menus.jd @@ -0,0 +1,1031 @@ +page.title=メニュー +parent.title=ユーザー インターフェース +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>本書の内容</h2> +<ol> + <li><a href="#xml">XML でのメニューの定義</a></li> + <li><a href="#options-menu">オプション メニューの作成</a> + <ol> + <li><a href="#RespondingOptionsMenu">クリック イベントを処理する</a></li> + <li><a href="#ChangingTheMenu">実行時におけるメニュー アイテムの変更</a></li> + </ol> + </li> + <li><a href="#context-menu">コンテキスト メニューの作成</a> + <ol> + <li><a href="#FloatingContextMenu">フローティング コンテキスト メニューの作成</a></li> + <li><a href="#CAB">コンテキスト アクション モードの使用</a></li> + </ol> + </li> + <li><a href="#PopupMenu">ポップアップ メニューの作成</a> + <ol> + <li><a href="#PopupEvents">クリック イベントを処理する</a></li> + </ol> + </li> + <li><a href="#groups">メニュー グループの作成</a> + <ol> + <li><a href="#checkable">オンにできるメニュー アイテムの使用</a></li> + </ol> + </li> + <li><a href="#intents">インテントに基づくメニュー アイテムの追加</a> + <ol> + <li><a href="#AllowingToAdd">アクティビティを他のメニューに追加できるようにする</a></li> + </ol> + </li> +</ol> + + <h2>キークラス</h2> + <ol> + <li>{@link android.view.Menu}</li> + <li>{@link android.view.MenuItem}</li> + <li>{@link android.view.ContextMenu}</li> + <li>{@link android.view.ActionMode}</li> + </ol> + + <h2>関連ドキュメント</h2> + <ol> + <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li> + <li><a href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a></li> + <li><a href="http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html">Goodbye to the Menu Button</a> +</li> + </ol> +</div> +</div> + +<p>メニューは、さまざまなタイプのアプリケーションで共通するユーザー インターフェースです。使い慣れた一貫した操作感を提供するには、{@link android.view.Menu} API を使ってアクティビティでユーザーのアクションとその他のオプションを表示する必要があります。 + +</p> + +<p>Android 3.0(API レベル 11)からは、Android 搭載端末では専用の <em>Menu</em> ボタンを表示する必要はなくなりました。 +この変更により、Android アプリでは従来の 6 アイテムのメニューパネルの依存関係から離れて、共通のユーザー アクションを表示するアクションバーを提供する必要があります。 + +</p> + +<p>一部のメニュー アイテムのデザインと操作感は変わりましたが、一連のアクションとオプションを定義する意味論は、引き続き {@link android.view.Menu} API に基づきます。 +このガイドでは、すべてのバージョンの Android で表示されるメニューやアクションの基本的な 3 タイプを作成する方法について説明します。 + +</p> + +<dl> + <dt><strong>オプション メニューとアクションバー</strong></dt> + <dd><a href="#options-menu">オプション メニュー</a>は、アクティビティの主なメニュー アイテムのコレクションです。 +ここには、「検索」、「メールの作成」、「設定」のような、アプリにグローバルな影響があるアクションを配置する必要があります。 + + <p>Android 2.3 以前のバージョン向けに開発している場合は、ユーザーは <em>Menu</em> ボタンを押してオプション メニューパネルを表示できます。 +</p> + <p>Android 3.0 以降の場合、オプション メニューのアイテムは、画面上のアクション アイテムとオーバーフロー オプションの組み合わせで<a href="{@docRoot}guide/topics/ui/actionbar.html">アクションバー</a>に表示されます。 +Android 3.0 からは、<em>Menu</em> ボタンが廃止されたため(一部の端末にはこのボタンがありません)、アクションバーを使ってアクションや他のオプションにアクセスできるよう移行する必要があります。 + + +</p> + <p><a href="#options-menu">オプション メニューの作成</a>のセクションをご覧ください。</p> + </dd> + + <dt><strong>コンテキスト メニューとコンテキスト アクション モード</strong></dt> + + <dd>コンテキスト メニューは、ユーザーが要素を長押しクリックするときに表示される<a href="#FloatingContextMenu">フローティング メニュー</a>です。 +ここでは、選択したコンテンツやコンテキスト フレームに影響するアクションが提供されます。 + + <p>Android 3.0 以降向けに開発している場合は、<a href="#CAB">コンテキスト アクション モード</a>を使って選択されたコンテンツでのアクションを有効にする必要があります。このモードでは、画面最上部にあるバーで選択されたコンテンツに影響するアクション アイテムが表示され、ユーザーは複数のアイテムを選択できます。 + +</p> + <p><a href="#context-menu">コンテキスト メニューの作成</a>のセクションをご覧ください。</p> +</dd> + + <dt><strong>ポップアップ メニュー</strong></dt> + <dd>ポップアップ メニューでは、メニューを呼び出すビューに固定された縦方向のリストでアイテムが表示されます。 +特定のコンテンツに関連するアクションの概要を表示したり、コマンドの 2 番目の部分のオプションを表示したりする場合に適しています。 +ポップアップ メニューのアクションは対応するコンテンツに直接影響を<strong>与えない</strong>ようにしてください(そのためにコンテキスト アクションがあります)。 + +ポップアップ メニューは、アクティビティのコンテンツ領域に関連する拡張されたアクション用です。 + + <p><a href="#PopupMenu">ポップアップ メニューの作成</a>のセクションをご覧ください。</p> +</dd> +</dl> + + + +<h2 id="xml">XML でのメニューの定義</h2> + +<p>Android では、すべてのメニュータイプに、メニュー アイテムを定義するための標準の XML 形式が提供されます。 +アクティビティのコードでメニューをビルドするのではなく、メニューとそのすべてのアイテムを XML <a href="{@docRoot}guide/topics/resources/menu-resource.html">メニュー リソース</a>で定義してください。 +その際、アクティビティやフラグメントでメニュー リソースをインフレートできます({@link android.view.Menu} オブジェクトとして読み込む)。 + +</p> + +<p>メニュー リソースを使うことは、次のような理由で優れた方法と言えます。</p> +<ul> + <li>XML でメニュー構造の視覚化が簡単になる。</li> + <li>メニューのコンテンツを、アプリケーションの振る舞いコードと区別する。</li> + <li>別のプラットフォーム バージョン、画面サイズ、その他の構成用に、<a href="{@docRoot}guide/topics/resources/index.html">アプリリソース</a> フレームワークを活用して、代替のメニュー構成を作ることができる。 +</li> +</ul> + +<p>メニューを定義するには、プロジェクトの <code>res/menu/</code> ディレクトリ内で XML ファイルを作成し、次の要素を含むメニューをビルドします。 +</p> +<dl> + <dt><code><menu></code></dt> + <dd>メニュー アイテムのコンテナである {@link android.view.Menu} を定義します。<code><menu></code> 要素は、ファイルのルートノードである必要があります。また、1 つ以上の <code><item></code> と <code><group></code> 要素を持つことができます。 + +</dd> + + <dt><code><item></code></dt> + <dd>メニューで 1 つのアイテムを表示する {@link android.view.MenuItem} を作成します。この要素には、サブメニューを作成するために、ネストされた <code><menu></code> 要素を含めることができます。 +</dd> + + <dt><code><group></code></dt> + <dd>省略可能な {@code <item>} 要素の非表示コンテナ。メニュー アイテムでアクティブ状態や可視性のようなプロパティを共有できるよう、メニュー アイテムを分類できます。 +詳細については、<a href="#groups">メニュー グループの作成</a>のセクションをご覧ください。 +</dd> +</dl> + + +<p><code>game_menu.xml</code> という名前のメニュー例を次に示します。</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/new_game" + android:icon="@drawable/ic_new_game" + android:title="@string/new_game" + android:showAsAction="ifRoom"/> + <item android:id="@+id/help" + android:icon="@drawable/ic_help" + android:title="@string/help" /> +</menu> +</pre> + +<p><code><item></code> 要素では、アイテムの概観と動作を定義するために使用できるいくつかの属性がサポートされています。 +上記メニューのアイテムには、次の属性が含まれます。</p> + +<dl> + <dt>{@code android:id}</dt> + <dd>ユーザーがアイテムを選択するときに、アプリケーションがそのアイテムを認識できるようにする、アイテム固有のリソース ID。 +</dd> + <dt>{@code android:icon}</dt> + <dd>アイテムのアイコンとして使用するための、ドローアブルへの参照。</dd> + <dt>{@code android:title}</dt> + <dd>アイテムのタイトルとして使用するための、文字列への参照。</dd> + <dt>{@code android:showAsAction}</dt> + <dd>このアイテムが<a href="{@docRoot}guide/topics/ui/actionbar.html">アクションバー</a>のアクション アイテムとして、いつ、どのように表示される必要があるかを指定。</dd> +</dl> + +<p>これらの属性は使用する必要のある最も重要なものですが、他にもさまざまな属性があります。サポートされているすべての属性については、「<a href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a>」のドキュメントをご覧ください。 +</p> + +<p>サブメニューを除くすべてのメニューで、{@code <item>} の子として {@code <menu>} 要素を追加すると、アイテムにサブメニューを追加できます。 +PC アプリケーションのメニューバー(ファイル、編集、表示など)にあるアイテムのように、アプリケーションにトピックで分類できる多くの機能がある場合は、サブメニューが役立ちます。 + +次に例を示します。</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/file" + android:title="@string/file" > + <!-- "file" submenu --> + <menu> + <item android:id="@+id/create_new" + android:title="@string/create_new" /> + <item android:id="@+id/open" + android:title="@string/open" /> + </menu> + </item> +</menu> +</pre> + +<p>アクティビティでメニューを使うには、{@link android.view.MenuInflater#inflate(int,Menu) +MenuInflater.inflate()} を使って、メニュー リソースをインフレートする(XML リソースをプログラム可能なオブジェクトに変換する)必要があります。 +次のセクションでは、各メニュー アイテムのメニューをインフレートする方法を説明します。 +</p> + + + +<h2 id="options-menu">オプション メニューの作成</h2> + +<div class="figure" style="width:200px;margin:0"> + <img src="{@docRoot}images/options_menu.png" height="333" alt="" /> + <p class="img-caption"><strong>図 1.</strong> Android 2.3 のブラウザでのオプション メニュー。 +</p> +</div> + +<p>オプション メニューでは、「検索」、「メールの作成」、「設定」のような、現在のアクティビティ コンテキストに関連するアクションとその他のオプションを含める必要があります。 +</p> + +<p>オプション メニューのアイテムが画面上のどこに表示されるかは、開発対象のアプリケーションのバージョンによって異なります。 +</p> + +<ul> + <li><strong>Android 2.3.x(API レベル 10)以前</strong> 向けにアプリケーションを開発した場合、ユーザーが <em>Menu</em> ボタンを押すときに、図 1 のように、オプション メニューのコンテンツが画面下部に表示されます。 + +開いて最初に表示される部分は、最大 6 つのメニュー アイテムで構成されるアイコン メニューです。 + +7 つ以上のメニュー アイテムが含まれている場合、Android では 6 番目以降のアイテムがオーバーフロー メニューに配置されます。それらのアイテムは、<em>もっと見る</em> を選択して開くことができます。 + +</li> + + <li><strong>Android 3.0(API レベル 11)以降</strong>向けにアプリケーションを開発した場合、オプション メニューのアイテムは<a href="{@docRoot}guide/topics/ui/actionbar.html">アクションバー</a>に表示されます。 +デフォルトでは、システムによってアクション オーバーフローにすべてのアイテムが配置され、ユーザーはアクションバー右端にあるアクション オーバーフロー アイコンを使ってそのアイテムを表示できます。端末に <em>Menu</em> ボタンがある場合はそのボタンを押して表示できます。 + +重要なアクションにすみやかにアクセスできるようにするには、対応する {@code <item>} 要素に {@code android:showAsAction="ifRoom"} を追加して、いくつかのアイテムをアクションバーに表示させるようプロモートできます(図 2を参照)。 + + + + <p>アクション アイテムと他のアクションバーの動作の詳細については、「<a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>」のガイドをご覧ください。 </p> +<p class="note"><strong>注:</strong> Android 3.0 以降向けに開発して<em>いない</em>場合でも、同様の効果のために、自分のアクションバー レイアウトをビルドできます。 +アクションバー付きで以前のバージョンの Android をサポートする方法の一例については、<a href="{@docRoot}resources/samples/ActionBarCompat/index.html">アクションバーの互換性</a>のサンプルをご覧ください。 + +</p> +</li> +</ul> + +<img src="{@docRoot}images/ui/actionbar.png" alt="" /> +<p class="img-caption"><strong>図 2.</strong> ナビゲーション タブ、カメラ アクション アイテム、アクション オーバーフロー ボタンが表示されている <a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> アプリのアクションバー。 +</p> + +<p>{@link android.app.Activity} サブクラスや {@link android.app.Fragment} サブクラスのいずれかからオプション メニューのアイテムを宣言できます。 +アクティビティとフラグメントの両方でオプション メニューのアイテムを宣言する場合、それらは UI に統合されます。まず、アクティビティのアイテムが表示され、次にアクティビティに各フラグメントが追加される順序で各フラグメントのアイテムが表示されます。 + + +必要に応じて、移動する必要のある各 {@code <item>} で {@code android:orderInCategory} 属性を使ってメニュー アイテムの順序を並べ替えることができます。 +</p> + +<p>アクティビティのオプション メニューを指定するには、{@link +android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} をオーバーライドします(フラグメントは独自の {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()} コールバックを提供)。 +このメソッドでは、メニュー リソース(<a href="#xml">XML で定義</a>)をコールバックで提供される {@link +android.view.Menu} にインフレートできます。 +次に例を示します。</p> + +<pre> +@Override +public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = {@link android.app.Activity#getMenuInflater()}; + inflater.inflate(R.menu.game_menu, menu); + return true; +} +</pre> + +<p>{@link android.view.Menu#add(int,int,int,int) +add()} を使ってメニュー アイテムを追加し、{@link android.view.MenuItem} API でそのプロパティを修正するために、{@link android.view.Menu#findItem findItem()} でアイテムを取得することもできます。 +</p> + +<p>Android 2.3.x 以前向けにアプリケーションを開発した場合、システムは {@link +android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} を呼び出し、ユーザーが初めてそのメニューを開いたときにオプション メニューが作成されます。 +Android 3.0 以降向けに開発した場合、アクティビティの開始時にシステムが {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} を呼び出し、アクションバーにアイテムが表示されるようにします。 + +</p> + + + +<h3 id="RespondingOptionsMenu">クリック イベントを処理する</h3> + +<p>ユーザーがオプション メニューからアイテムを選択すると(アクションバーのアクション アイテムを含む)、アクティビティの {@link android.app.Activity#onOptionsItemSelected(MenuItem) +onOptionsItemSelected()} メソッドが呼び出されます。 +このメソッドでは、選択された {@link android.view.MenuItem} が渡されます。{@link android.view.MenuItem#getItemId()} を呼び出してアイテムを識別できます。これにより、メニュー アイテムに対して一意の ID が返されます(メニュー リソースで {@code android:id} 属性を定義するか、{@link android.view.Menu#add(int,int,int,int) add()} メソッドに指定された整数で)。 + + +この ID を既知のメニュー アイテムと突き合わせて適切なアクションを実行できます。 +次に例を示します。</p> + +<pre> +@Override +public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.new_game: + newGame(); + return true; + case R.id.help: + showHelp(); + return true; + default: + return super.onOptionsItemSelected(item); + } +} +</pre> + +<p>メニュー アイテムを正常に処理する場合、{@code true} を返します。メニュー アイテムを処理しない場合は、{@link +android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} のスーパークラスの実装を呼び出す必要があります(デフォルトの実装では fause が返されます)。 + +</p> + +<p>アクティビティにフラグメントが含まれる場合は、システムはまずアクティビティに対して {@link +android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} を呼び出し、次に {@code true} が返されるまで、またはすべてのフラグメントが呼び出されるまで、各フラグメントが追加された順序で、各フラグメントに対して呼び出します。 + +</p> + +<p class="note"><strong>ヒント:</strong> Android 3.0 では、{@code android:onClick} 属性を使って、メニュー アイテムのクリックでの動作を XML で定義できます。 +その属性値は、メニューを使ってアクティビティによって定義されるメソッド名である必要があります。 +そのメソッドは、パブリックであり、1 つの {@link android.view.MenuItem} パラメータを使用できる必要があります。システムがこのメソッドを呼び出すと、選択したメニュー アイテムが渡されます。 + +詳細と例については、「<a href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a>」のドキュメントをご覧ください。</p> + +<p class="note"><strong>ヒント:</strong> アプリケーションに複数のアクティビティが含まれていて、その一部で同じオプション メニューが提供されている場合、{@link android.app.Activity#onCreateOptionsMenu(Menu) +onCreateOptionsMenu()} と {@link android.app.Activity#onOptionsItemSelected(MenuItem) +onOptionsItemSelected()} メソッドのみを実装するアクティビティを作成することを検討します。 + +その後、同じオプション メニューを共有する必要のある各アクティビティのこのクラスを拡張します。 +この方法で、メニューの動作を継承するメニュー アクションとそれぞれの子クラスを処理するためのコードを 1 セットで管理できます。子孫アクティビティの 1 つにメニュー アイテムを追加する場合は、そのアクティビティの {@link android.app.Activity#onCreateOptionsMenu(Menu) +onCreateOptionsMenu()} をオーバーライドします。 + + +元のメニュー アイテムが作成されるように、{@code super.onCreateOptionsMenu(menu)} を呼び出し、{@link +android.view.Menu#add(int,int,int,int) menu.add()} で新しいメニュー アイテムを追加します。 +各メニュー アイテムのスーパークラスの行動をオーバーライドすることもできます。 +</p> + + +<h3 id="ChangingTheMenu">実行時におけるメニュー アイテムの変更</h3> + +<p>システムが {@link android.app.Activity#onCreateOptionsMenu(Menu) +onCreateOptionsMenu()} を呼び出した後、入力する {@link android.view.Menu} のインスタンスは残り、何らかの理由でメニューが無効にならない限り、{@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} をもう一度呼び出すことはありません。 + +ただし、初期のメニュー状態を作成し、アクティビティのライフサイクル中に変更しないという目的の場合に限って、{@link +android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} を使用する必要があります。 +</p> + +<p>アクティビティのライフサイクル中に発生するイベントに基づいてオプション メニューを変更する場合は、{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} メソッドでそれを実行できます。 + +このメソッドは、現在存在している {@link android.view.Menu} オブジェクトを渡し、それを編集(アイテムの追加、削除、無効化など)できるようにします。 + +(フラグメントでも {@link +android.app.Fragment#onPrepareOptionsMenu onPrepareOptionsMenu()} コールバックが提供されます)。</p> + +<p>Android 2.3.x 以前では、ユーザーが <em>Menu</em> ボタンを押してオプション メニューを開くたびに、システムによって {@link +android.app.Activity#onPrepareOptionsMenu(Menu) +onPrepareOptionsMenu()} が呼び出されます。 +</p> + +<p>Android 3.0 以降では、メニュー アイテムがアクションバーに表示されるときに、オプション メニューが常に開かれるとみなされます。 +イベントが発生し、メニューをアップデートするときは、{@link android.app.Activity#invalidateOptionsMenu invalidateOptionsMenu()} を呼び出して、システムが {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} を呼び出すようリクエストする必要があります。 + +</p> + +<p class="note"><strong>注:</strong> 現在フォーカスされている {@link android.view.View} に基づいてオプション メニューでアイテムを変更しないでください。 + +タッチモードの場合(ユーザーがトラックボールやリモコンの矢印ボタンを使うとき)、ビューはフォーカスを取得できないため、オプション メニューのアイテム変更のベースとしてフォーカスを使用しないでください。 + +{@link +android.view.View} に状況依存のメニュー アイテムを提供する場合は、<a href="#context-menu">コンテキスト メニュー</a>を使います。</p> + + + + +<h2 id="context-menu">コンテキスト メニューの作成</h2> + +<div class="figure" style="width:420px;margin-top:-1em"> + <img src="{@docRoot}images/ui/menu-context.png" alt="" /> + <p class="img-caption"><strong>図 3.</strong> フローティング コンテキスト メニュー(左)とコンテキスト アクションバー(右)のスクリーンショット +</p> +</div> + +<p>コンテキスト メニューでは、UI の特定のアイテムやコンテキスト フレームに影響するアクションが提供されます。どのビューでもコンテキスト メニューを提供できますが、ほとんどの場合は、{@link +android.widget.ListView}、{@link android.widget.GridView}、各アイテムでユーザーが直接実行できるその他のビュー コレクションのアイテムに使用されます。 + +</p> + +<p>コンテキスト アクションを提供するには次の 2 つの方法があります。</p> +<ul> + <li><a href="#FloatingContextMenu">フローティング コンテキスト メニュー</a>で。メニューは、ユーザーが長押しクリックする(押したままにする)と、コンテキスト メニューのサポートを宣言するビュー上で、メニュー アイテムのフローティング リストとして表示されます。 + +ユーザーは、一度に 1 つのアイテムでコンテキスト アクションを実行できます。 +</li> + + <li><a href="#CAB">コンテキスト アクション モード</a>で。このモードは、選択されたアイテムに影響するアクション アイテムと一緒に画面最上部に<em>コンテキスト アクションバー</em>を表示する {@link android.view.ActionMode} のシステム実装です。 + +このモードがアクティブなとき、ユーザーは一度に複数のアイテムでアクションを実行できます(アプリで許可されている場合)。 +</li> +</ul> + +<p class="note"><strong>注:</strong> コンテキスト アクション モードは、Android 3.0(API レベル 11)以降で使用可能で、使用可能な場合にコンテキスト アクションを表示するのに適した方法です。 + +アプリで 3.0 以前のバージョンをサポートする場合、その端末ではフローティング コンテキスト メニューを使う必要があります。 +</p> + + +<h3 id="FloatingContextMenu">フローティング コンテキスト メニューの作成</h3> + +<p>フローティング コンテキスト メニューを提供するには: </p> +<ol> + <li>{@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()} を呼び出し、{@link android.view.View} を渡して、コンテキスト メニューに関連付ける必要のある {@link android.view.View} を登録します。 + + + <p>アクティビティで {@link android.widget.ListView} や {@link android.widget.GridView} が使用され、各アイテムに同じコンテキスト メニューを提供する場合、{@link android.widget.ListView} や {@link android.widget.GridView} を {@link +android.app.Activity#registerForContextMenu(View) registerForContextMenu()} に渡してコンテキスト メニューにすべてのアイテムを登録します。 + +</p> +</li> + + <li>{@link android.app.Activity} や {@link android.app.Fragment} に {@link +android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()} メソッドを実装します。 + + <p>登録されたビューが長押しクリック イベントを受け取ると、システムは {@link +android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()} メソッドを呼び出します。 +通常、ここでメニュー リソースをインフレートして、メニュー アイテムを定義します。次に例を示します。 +</p> +<pre> +@Override +public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.context_menu, menu); +} +</pre> + +<p>{@link android.view.MenuInflater} では、<a href="{@docRoot}guide/topics/resources/menu-resource.html">メニュー リソース</a>からコンテキスト メニューをインフレートできます。そのコールバック メソッド パラメータには、ユーザーが選択した {@link android.view.View} と選択されたアイテムに関する追加情報を提供する {@link android.view.ContextMenu.ContextMenuInfo} オブジェクトが含まれます。 + + +アクティビティに、それぞれ別のコンテキスト メニューを提供する複数のビューがある場合、これらのパラメータを使ってインフレートするコンテキスト メニューを決定できます。 + +</p> +</li> + +<li>{@link android.app.Activity#onContextItemSelected(MenuItem) +onContextItemSelected()} を実装します。 + <p>ユーザーがメニュー アイテムを選択すると、システムによってこのメソッドが呼び出され、適切なアクションを実行できるようになります。 +次に例を示します。</p> + +<pre> +@Override +public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); + switch (item.getItemId()) { + case R.id.edit: + editNote(info.id); + return true; + case R.id.delete: + deleteNote(info.id); + return true; + default: + return super.onContextItemSelected(item); + } +} +</pre> + +<p>{@link android.view.MenuItem#getItemId()} メソッドは、選択されたメニュー アイテムの ID を照会します。<a href="#xml">XML でメニューを定義する</a>のセクションで説明されているように、{@code +android:id} 属性を使って XML で各メニュー アイテムを割り当てる必要があります。 + +</p> + +<p>メニュー アイテムを正常に処理する場合、{@code true} を返します。メニュー アイテムを処理しない場合は、スーパークラスの実装にメニュー アイテムを渡す必要があります。 +アクティビティにフラグメントが含まれる場合、そのアクティビティは最初にこのコールバックを受け取ります。 +未処理のときにスーパークラスを呼び出すと、システムは {@code true} や {@code false} が返されるまで、各フラグメントのそれぞれのコールバック メソッドに 1 つずつ、各フラグメントが追加された順序でイベントを渡します。 + +{@link android.app.Activity} と {@code android.app.Fragment} のデフォルトの実装では {@code +false} が返されるため、未処理のときは常にスーパークラスを呼び出す必要があります。 +</p> +</li> +</ol> + + +<h3 id="CAB">コンテキスト アクション モードの使用</h3> + +<p>コンテキスト アクション モードは、{@link android.view.ActionMode} のシステム実装で、ユーザーによるコンテキスト アクション実行のための操作に焦点が置かれています。 +ユーザーがアイテムを選択してこのモードを有効にすると、画面の最上部に<em>コンテキスト アクションバー</em>が表示され、現在選択中のアイテムで実行できるアクションが表示されます。 + +このモードが有効な間は、ユーザーは複数のアイテムを選択したり(許可されている場合)、アイテムを選択解除したり、アクティビティ内を移動し続けたり(許可されている範囲内で)することができます。 + +ユーザーがすべてのアイテムの選択を解除したり、Back ボタンをしたり、またはバーの左端で <em>Done</em> アクションを選択したりすると、このアクション モードは無効になり、コンテキスト アクションバーは表示されなくなります。 + +</p> + +<p class="note"><strong>注:</strong> コンテキスト アクションバーを<a href="{@docRoot}guide/topics/ui/actionbar.html">アクションバー</a>と関連付ける必要はありません。 +コンテキスト アクションバーが、視覚的にアクションバーの位置にかかる場合でも、個別に操作できます。 + +</p> + +<p>Android 3.0(API レベル 11)以降向けに開発中の場合、通常は<a href="#FloatingContextMenu">フローティング コンテキスト メニュー</a>ではなく、コンテキスト アクション モードを使ってコンテキスト アクションを表示します。 +</p> + +<p>コンテキスト アクションを提供するビューでは、通常は次の 2 つのイベントのいずれかまたは両方で、コンテキスト アクションを呼び出す必要があります。 +</p> +<ul> + <li>ユーザーがビューで長押しクリックする。</li> + <li>ユーザーがチェックボックスまたは同様の UI コンポーネントをビュー内で選択する。</li> +</ul> + +<p>アプリケーションがどのようにコンテキスト アクション モードを呼び出して各アクションの動作を定義するかは、デザインによって異なります。 +基本的に次の 2 つのデザインがあります。</p> +<ul> + <li>個別の任意のビューでのコンテキスト アクション用。</li> + <li>{@link +android.widget.ListView} または {@link android.widget.GridView} のアイテム グループでのバッチ コンテキスト アクション用(ユーザーが複数のアイテムを選択し、そのすべてにアクションを実行できるようにする)。 +</li> +</ul> + +<p>次のセクションでは、各シナリオに必要な設定について説明します。</p> + + +<h4 id="CABforViews">個別のビューに対してコンテキスト アクション モードを有効にする</h4> + +<p>ユーザーが特定のビューを選択するときにのみ、コンテキスト アクション モードを呼び出すには、次のことを行う必要があります。 +</p> +<ol> + <li>{@link android.view.ActionMode.Callback} インターフェースを実装します。このコールバック メソッドでは、コンテキスト アクションバーに対してアクションを指定して、アクション アイテムでのイベント クリックに応答し、アクション モードのその他のライフサイクル イベントを処理できます。 + +</li> + <li>ユーザーがビューを長押しクリックしたときなど、バーを表示するときに、{@link android.app.Activity#startActionMode startActionMode()} を呼び出します。 +</li> +</ol> + +<p>次に例を示します。</p> + +<ol> + <li>{@link android.view.ActionMode.Callback ActionMode.Callback} インターフェースを実装します。 +<pre> +private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { + + // Called when the action mode is created; startActionMode() was called + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + // Inflate a menu resource providing context menu items + MenuInflater inflater = mode.getMenuInflater(); + inflater.inflate(R.menu.context_menu, menu); + return true; + } + + // Called each time the action mode is shown. Always called after onCreateActionMode, but + // may be called multiple times if the mode is invalidated. + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; // Return false if nothing is done + } + + // Called when the user selects a contextual menu item + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_share: + shareCurrentItem(); + mode.finish(); // Action picked, so close the CAB + return true; + default: + return false; + } + } + + // Called when the user exits the action mode + @Override + public void onDestroyActionMode(ActionMode mode) { + mActionMode = null; + } +}; +</pre> + +<p>これらのイベント コールバックは、これらのそれぞれもイベントに関連する {@link +android.view.ActionMode} オブジェクトを渡すこと以外は、<a href="#options-menu">オプション メニュー</a>のコールバックとほぼ同じです。{@link +android.view.ActionMode} API を使って、{@link android.view.ActionMode#setTitle setTitle()} と {@link +android.view.ActionMode#setSubtitle setSubtitle()}(選択されているアイテム数を表示するのに役立つ)でタイトルとサブタイトルを変更するなど、CAB にさまざまな変更を行うことができます。 + +</p> + +<p>また、上記のサンプルでは、アクション モードが破棄されるときに {@code mActionMode} 変数が null に設定されます。 +次のステップでは、それがどのように初期化され、アクティビティやフラグメントでどのようにメンバー変数を保存するのが役立つかについて説明します。 +</p> +</li> + + <li>{@link android.app.Activity#startActionMode startActionMode()} を呼び出して、{@link +android.view.View} で長押しクリックに応答するときなど、適切な時にコンテキスト アクション モードを有効にします。 +</p> + +<pre> +someView.setOnLongClickListener(new View.OnLongClickListener() { + // Called when the user long-clicks on someView + public boolean onLongClick(View view) { + if (mActionMode != null) { + return false; + } + + // Start the CAB using the ActionMode.Callback defined above + mActionMode = getActivity().startActionMode(mActionModeCallback); + view.setSelected(true); + return true; + } +}); +</pre> + +<p>{@link android.app.Activity#startActionMode startActionMode()} を呼び出すと、システムは作成された {@link android.view.ActionMode} を返します。 +メンバー変数でこれを保存すると、その他のイベントに応じてコンテキスト アクションバーを変更できます。 +上記の例では、{@link android.view.ActionMode} を使って、{@link android.view.ActionMode} インスタンスがアクティブな状態である場合に、アクション モードを開始する前にメンバーが null であるかどうかを確認して、そのインスタンスが再作成されないようにしています。 + + +</p> +</li> +</ol> + + + +<h4 id="CABforListView">バッチ コンテキスト アクションを ListView または GridView で有効にする</h4> + +<p>{@link android.widget.ListView} や {@link +android.widget.GridView}(または {@link android.widget.AbsListView} の別の拡張)にアイテムのコレクションがあり、ユーザーがバッチ アクションを実行できるようにする場合は、次のことを行う必要があります。 +</p> + +<ul> + <li>{@link android.widget.AbsListView.MultiChoiceModeListener} インターフェースを実装して、{@link android.widget.AbsListView#setMultiChoiceModeListener +setMultiChoiceModeListener()} で ViewGroup にそれを設定する。 +リスナのコールバック メソッドでは、コンテキスト アクションバーに対してアクションを指定して、アクション アイテムでのイベント クリックに応答し、{@link android.view.ActionMode.Callback} インターフェースから継承されるその他のコールバックを処理できます。 + +</li> + + <li>{@link +android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL} 引数で {@link android.widget.AbsListView#setChoiceMode setChoiceMode()} を呼び出す。</li> +</ul> + +<p>次に例を示します。</p> + +<pre> +ListView listView = getListView(); +listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); +listView.setMultiChoiceModeListener(new MultiChoiceModeListener() { + + @Override + public void onItemCheckedStateChanged(ActionMode mode, int position, + long id, boolean checked) { + // Here you can do something when items are selected/de-selected, + // such as update the title in the CAB + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + // Respond to clicks on the actions in the CAB + switch (item.getItemId()) { + case R.id.menu_delete: + deleteSelectedItems(); + mode.finish(); // Action picked, so close the CAB + return true; + default: + return false; + } + } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + // Inflate the menu for the CAB + MenuInflater inflater = mode.getMenuInflater(); + inflater.inflate(R.menu.context, menu); + return true; + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + // Here you can make any necessary updates to the activity when + // the CAB is removed. By default, selected items are deselected/unchecked. + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + // Here you can perform updates to the CAB due to + // an {@link android.view.ActionMode#invalidate} request + return false; + } +}); +</pre> + +<p>これだけです。これで、ユーザーが長押しクリックでアイテムを選択すると、システムは {@link +android.widget.AbsListView.MultiChoiceModeListener#onCreateActionMode onCreateActionMode()} メソッドを呼び出して、特定のアクションでコンテキスト アクションバーを表示するようになります。 +コンテキスト アクションバーが表示されている間は、追加のアイテムを選択できます。 +</p> + +<p>コンテキスト アクションによって一般的なアクション アイテムが提供されるとき、ユーザーが長押しクリックの動作に気付かない可能性があることを考慮して、アイテムを選択できるようにチェックボックスや同様の UI 要素を追加したい場合もあります。 + +ユーザーがチェックボックスをオンにするとき、{@link android.widget.AbsListView#setItemChecked setItemChecked()} でオンにされた状態にそれぞれのリストアイテムを設定して、コンテキスト アクション モードを呼び出すことができます。 + +</p> + + + + +<h2 id="PopupMenu">ポップアップ メニューの作成</h2> + +<div class="figure" style="width:220px"> +<img src="{@docRoot}images/ui/popupmenu.png" alt="" /> +<p><strong>図 4.</strong>右上のオーバーフローボタンに固定された Gmail アプリのポップアップ メニュー。 +</p> +</div> + +<p>{@link android.widget.PopupMenu} は {@link android.view.View} に固定されるモーダル メニューです。スペースがある場合にはアンカービューの下に、スペースがない場合はビューの上に表示されます。 +次の場合に役立ちます。</p> +<ul> + <li>特定のコンテンツに<em>関連する</em>アクションにオーバーフロー スタイルのメニューを提供する(図 4 にある Gmail のメールヘッダーなど)。 + + <p class="note"><strong>注:</strong> これは、通常は選択したコンテンツに<em>影響する</em>アクション用であるコンテキスト メニューとは異なります。 +選択したコンテンツに影響するアクションには、<a href="#CAB">コンテキスト アクション モード</a>や<a href="#FloatingContextMenu">フローティング コンテキスト メニュー</a>を使います。 +</p></li> + <li>コマンド センテンスの 2 番目の部分を提供する(別の「追加」オプションを含むポップアップ メニューを生成する「追加」とマークされたボタンなど)。 +</li> + <li>固定選択を保持しない {@link android.widget.Spinner} のようなドロップダウンを提供する。 +</li> +</ul> + + +<p class="note"><strong>注:</strong> {@link android.widget.PopupMenu} は API レベル 11 以降で使用できます。 +</p> + +<p><a href="#xml">XML でメニューを定義する</a>場合の、ポップアップ メニューの表示方法について、次に示します。</p> +<ol> + <li>そのコンストラクタを使って {@link android.widget.PopupMenu} のインスタンスを作成します。これにより、メニューが固定される必要のある、現在のアプリケーションの {@link android.content.Context} と {@link android.view.View} が取得されます。 + +</li> + <li>{@link android.view.MenuInflater} を使って、{@link +android.widget.PopupMenu#getMenu() PopupMenu.getMenu()} によって返される {@link +android.view.Menu} オブジェクトにメニュー リソースをインフレートします。API レベル 14 以降では、代わりに {@link android.widget.PopupMenu#inflate PopupMenu.inflate()} を使うことができます。 +</li> + <li>{@link android.widget.PopupMenu#show() PopupMenu.show()} を呼び出します。</li> +</ol> + +<p>ポップアップ メニューを表示する {@link android.R.attr#onClick android:onClick} 属性を含むボタンの一例を以下に示します。 +</p> + +<pre> +<ImageButton + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_overflow_holo_dark" + android:contentDescription="@string/descr_overflow_button" + android:onClick="showPopup" /> +</pre> + +<p>アクティビティでは、次のようにポップアップ メニューが表示されます。</p> + +<pre> +public void showPopup(View v) { + PopupMenu popup = new PopupMenu(this, v); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.actions, popup.getMenu()); + popup.show(); +} +</pre> + +<p>API レベル 14 以降では、{@link +android.widget.PopupMenu#inflate PopupMenu.inflate()} でメニューをインフレートする 2 行を組み合わせることができます。</p> + +<p>ユーザーがアイテムを選択するか、メニュー領域外をタップすると、メニューが閉じます。 +{@link +android.widget.PopupMenu.OnDismissListener} を使って dismiss イベントをリッスンできます。</p> + +<h3 id="PopupEvents">クリック イベントを処理する</h3> + +<p>ユーザーがアイテム メニューを選択するときにアクションを実行するには、{@link +android.widget.PopupMenu.OnMenuItemClickListener} インターフェースを実装し、{@link android.widget.PopupMenu#setOnMenuItemClickListener +setOnMenuItemclickListener()} を呼び出して {@link +android.widget.PopupMenu} でそれを登録する必要があります。 +ユーザーがアイテムを選択すると、インターフェースで {@link +android.widget.PopupMenu.OnMenuItemClickListener#onMenuItemClick onMenuItemClick()} コールバックが呼び出されます。 +</p> + +<p>次に例を示します。</p> + +<pre> +public void showMenu(View v) { + PopupMenu popup = new PopupMenu(this, v); + + // This activity implements OnMenuItemClickListener + popup.setOnMenuItemClickListener(this); + popup.inflate(R.menu.actions); + popup.show(); +} + +@Override +public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.archive: + archive(item); + return true; + case R.id.delete: + delete(item); + return true; + default: + return false; + } +} +</pre> + + +<h2 id="groups">メニュー グループの作成</h2> + +<p>メニュー グループは、特定の特徴を共有するメニュー アイテムのコレクションです。グループを使って次のことを実行できます。 +</p> +<ul> + <li>{@link android.view.Menu#setGroupVisible(int,boolean) +setGroupVisible()} ですべてのアイテムを表示または非表示にする</li> + <li>{@link android.view.Menu#setGroupEnabled(int,boolean) +setGroupEnabled()} ですべてのアイテムを有効または無効にする</li> + <li>{@link +android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()} ですべてのアイテムをオンにできるかどうかを指定する</li> +</ul> + +<p>メニュー リソースの {@code <group>} 要素内で {@code <item>} 要素をネストするか、{@link +android.view.Menu#add(int,int,int,int) add()} メソッドでグループ ID を指定して、グループを作成できます。 +</p> + +<p>グループを含むメニュー リソースの一例を次に示します。</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/menu_save" + android:icon="@drawable/menu_save" + android:title="@string/menu_save" /> + <!-- menu group --> + <group android:id="@+id/group_delete"> + <item android:id="@+id/menu_archive" + android:title="@string/menu_archive" /> + <item android:id="@+id/menu_delete" + android:title="@string/menu_delete" /> + </group> +</menu> +</pre> + +<p>グループ内のアイテムは、最初のアイテムと同じレベルで表示されます(メニューの 3 つのアイテムすべてが兄弟)。 +ただし、グループ ID を参照するか、上記のメソッドを使って、グループ内の 2 つのアイテムの特徴を変更できます。 +システムが、グループ化されたアイテムを分けることもありません。 +たとえば、各アイテムに {@code +android:showAsAction="ifRoom"} を宣言する場合、その両方がアクションバーまたはアクション オーバーフローに表示されます。 +</p> + + +<h3 id="checkable">オンにできるメニュー アイテムの使用</h3> + +<div class="figure" style="width:200px"> + <img src="{@docRoot}images/radio_buttons.png" height="333" alt="" /> + <p class="img-caption"><strong>図 5.</strong> オンにできるアイテムを含むサブメニューのスクリーンショット。 +</p> +</div> + +<p>メニューは、オプションのオンとオフを切り替えるインターフェースとして役立ちます。スタンドアロンのオプションにはチェックボックスを、相互に排他的なオプションのグループにはラジオボタンを使います。 + +図 5 に、ラジオボタン付きのオンにできるアイテムを含むサブメニューを示します。 +</p> + +<p class="note"><strong>注:</strong> アイコン メニューのメニュー アイテム(オプション メニューから)ではチェックボックスやラジオボタンを表示できません。 +アイコン メニューのアイテムをオンにできるようにする場合、状態が変わるごとにアイコンやテキストを入れ替えて、オンにされた状態を手動で示す必要があります。 + +</p> + +<p>個々のメニュー アイテムには {@code <item>} 要素の {@code +android:checkable} 属性を、グループ全体には {@code <group>} 要素の {@code android:checkableBehavior} 属性を使って、オンにできる動作を定義できます。 +たとえば、このメニュー グループのすべてのアイテムはラジオボタンでオンにできます。 +</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <group android:checkableBehavior="single"> + <item android:id="@+id/red" + android:title="@string/red" /> + <item android:id="@+id/blue" + android:title="@string/blue" /> + </group> +</menu> +</pre> + +<p>{@code android:checkableBehavior} 属性では、次のいずれかが許容されます。 +<dl> + <dt>{@code single}</dt> + <dd>グループから 1 つのアイテムのみをオンにできる(ラジオボタン)</dd> + <dt>{@code all}</dt> + <dd>すべてのアイテムをオンにできる(チェックボックス)</dd> + <dt>{@code none}</dt> + <dd>どのアイテムもオンにできない</dd> +</dl> + +<p>{@code <item>} 要素の {@code android:checked} 属性を使って、デフォルトのオンにされた状態をアイテムに適用でき、{@link +android.view.MenuItem#setChecked(boolean) setChecked()} メソッドを使ってコード内でそれを変更できます。 +</p> + +<p>オンにできるアイテムが選択されると、システムは {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} のような、それぞれの item-selected コールバック メソッドを呼び出します。 +チェックボックスやラジオボタンによって自動的にその状態が変わることはないため、ここでチェックボックスの状態を設定する必要があります。 + +{@link android.view.MenuItem#isChecked()} で、アイテムの現在の状態(ユーザーが選択する前の状態)を照会できます。その後、{@link android.view.MenuItem#setChecked(boolean) setChecked()} でオンにされた状態を設定します。 + +次に例を示します。</p> + +<pre> +@Override +public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.vibrate: + case R.id.dont_vibrate: + if (item.isChecked()) item.setChecked(false); + else item.setChecked(true); + return true; + default: + return super.onOptionsItemSelected(item); + } +} +</pre> + +<p>この方法でオンにされた状態を設定しない場合には、アイテム(チェックボックスまたはラジオボタン)の表示状態はユーザーがオンにしたときに変更されません。 + +状態を設定すると、アクティビティはアイテムのオンにされた状態を維持して、ユーザーが後でメニューを開いたときに、開発者が設定したオンにされた状態が表示されるようになります。 + +</p> + +<p class="note"><strong>注:</strong> オンにできるメニュー アイテムは、セッション単位ベースのみでの使用を意図したもので、アプリケーションが破棄された後は、保存されません。 + +ユーザー用に保存するアプリケーション設定がある場合は、<a href="{@docRoot}guide/topics/data/data-storage.html#pref">共有のプリファレンス</a>を使ってデータを保存してください。 +</p> + + + +<h2 id="intents">インテントに基づくメニュー アイテムの追加</h2> + +<p>{@link android.content.Intent} を使ってメニュー アイテムでアクティビティが起動されるようにしたい場合もあります(自分のアプリケーションのアクティビティであるか、別のアプリケーションのアクティビティであるかにかかわらず)。 +使用するインテントがわかっていて、インテントを開始する必要のある特定のメニュー アイテムがある場合は、適切な on-item-selected コールバック メソッド({@link +android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} のような)中に、{@link android.app.Activity#startActivity(Intent) startActivity()} でインテントを実行できます。 + + +</p> + +<p>ただし、ユーザーの端末にインテントを処理するアプリケーションが含まれているかどうかが不明な場合、それを呼び出すメニュー アイテムを追加すると、そのインテントによってアクティビティが解決されないためにメニュー アイテムが機能しなくなることがあります。 + + +これを解決するために、Android では、インテントを処理する端末で Android によってアクティビティが検出されるときに、メニュー アイテムがメニューに動的に追加されるようにします。 +</p> + +<p>インテントを受け入れる使用可能なアクティビティに基づいてメニュー アイテムを追加するには: </p> +<ol> + <li>{@link android.content.Intent#CATEGORY_ALTERNATIVE} や {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} カテゴリでインテントを定義します。その他の要件も必要です。 + +</li> + <li>{@link +android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) +Menu.addIntentOptions()} を呼び出します。その際、Android によって、インテントを実行できるアプリケーションが検索され、メニューにそのアプリケーションが追加されます。 +</li> +</ol> + +<p>インテントを満たすアプリケーションがインストールされていない場合、メニュー アイテムは追加されません。 +</p> + +<p class="note"><strong>注:</strong> {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} は、現在画面で選択されている要素の処理に使われます。 + +このため、{@link +android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) +onCreateContextMenu()} でメニューを作成するときにのみ、それが使われる必要があります。</p> + +<p>次に例を示します。</p> + +<pre> +@Override +public boolean onCreateOptionsMenu(Menu menu){ + super.onCreateOptionsMenu(menu); + + // Create an Intent that describes the requirements to fulfill, to be included + // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE. + Intent intent = new Intent(null, dataUri); + intent.addCategory(Intent.CATEGORY_ALTERNATIVE); + + // Search and populate the menu with acceptable offering applications. + menu.addIntentOptions( + R.id.intent_group, // Menu group to which new items will be added + 0, // Unique item ID (none) + 0, // Order for the items (none) + this.getComponentName(), // The current activity name + null, // Specific items to place first (none) + intent, // Intent created above that describes our requirements + 0, // Additional flags to control items (none) + null); // Array of MenuItems that correlate to specific items (none) + + return true; +}</pre> + +<p>定義されたインテントに一致するインテント フィルタが提供されていることを見つけた各アクティビティに対して、メニュー アイテムのタイトルにインテント フィルタの <code>android:label</code> の値を、メニュー アイテムのアイコンにアプリケーション アイコンを使って、メニュー アイテムが追加されます。 + +{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) +addIntentOptions()} メソッドによって、追加されたメニュー アイテム数が返されます。 +</p> + +<p class="note"><strong>注:</strong> {@link +android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) +addIntentOptions()} を呼び出すとき、最初の引数で指定されたメニュー グループによって、すべてのメニュー アイテムがオーバーライドされます。 +</p> + + +<h3 id="AllowingToAdd">アクティビティを他のメニューに追加できるようにする</h3> + +<p>他のアプリケーションにアクティビティのサービスを提供して、アプリケーションを他のメニューに含めることができるようにすることもできます(前述の役割を逆にする)。 +</p> + +<p>他のアプリケーションのメニューに含まれるようにするには、通常どおりインテント フィルタを定義する必要がありますが、インテント フィルタのカテゴリに、{@link android.content.Intent#CATEGORY_ALTERNATIVE} や {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} 値を含めるようにしてください。 + + +次に例を示します。</p> +<pre> +<intent-filter label="@string/resize_image"> + ... + <category android:name="android.intent.category.ALTERNATIVE" /> + <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> + ... +</intent-filter> +</pre> + +<p>インテント フィルタの記述の詳細については、「<a href="/guide/components/intents-filters.html">インテントとインテント フィルタ</a>」をご覧ください。 +</p> + +<p>この方法を使ったサンプル アプリケーションについては、<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NoteEditor.html">Note Pad</a> のサンプルコードをご覧ください。 + +</p> diff --git a/docs/html-intl/intl/ja/guide/topics/ui/notifiers/notifications.jd b/docs/html-intl/intl/ja/guide/topics/ui/notifiers/notifications.jd new file mode 100644 index 000000000000..f341256a3225 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/ui/notifiers/notifications.jd @@ -0,0 +1,979 @@ +page.title=通知 +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> +<h2>本書の内容</h2> +<ol> + <li><a href="#Design">設計上の考慮事項</a></li> + <li><a href="#CreateNotification">通知を作成する</a> + <ol> + <li><a href="#Required">必須通知コンテンツ</a></li> + <li><a href="#Optional">省略可能な通知コンテンツと設定</a></li> + <li><a href="#Actions">通知アクション</a></li> + <li><a href="#Priority">通知の優先度</a></li> + <li><a href="#SimpleNotification">簡単な通知を作成する</a></li> + <li><a href="#ApplyStyle">通知に拡張レイアウトを適用する</a></li> + <li><a href="#Compatibility">互換性を確保する</a></li> + </ol> + </li> + <li><a href="#Managing">通知を管理する</a> + <ol> + <li><a href="#Updating">通知を更新する</a></li> + <li><a href="#Removing">通知を削除する</a></li> + </ol> + </li> + <li><a href="#NotificationResponse">アクティビティの開始時にナビゲーションを維持する</a> + <ol> + <li><a href="#DirectEntry">通常のアクティビティの PendingIntent を設定する</a></li> + <li><a href="#ExtendedNotification">特殊なアクティビティの PendingIntent を設定する</a></li> + </ol> + </li> + <li><a href="#Progress">通知に進捗状況を表示する</a> + <ol> + <li><a href="#FixedProgress">範囲固定の進捗インジケーターを表示する</a></li> + <li><a href="#ActivityIndicator">進行中アクティビティ インジケーターを表示する</a></li> + </ol> + </li> + <li><a href="#metadata">通知メタデータ</a></li> + <li><a href="#Heads-up">ヘッドアップ通知</a></li> + <li><a href="#lockscreenNotification">ロック画面通知</a></li> + <ol> + <li><a href="#visibility">可視性を設定する</a></li> + <li><a href="#controllingMedia">ロック画面でのメディア再生をコントロールする</a></li> + </ol> + <li><a href="#CustomNotification">カスタム通知レイアウト</a></li> +</ol> + + <h2>キークラス</h2> + <ol> + <li>{@link android.app.NotificationManager}</li> + <li>{@link android.support.v4.app.NotificationCompat}</li> + </ol> + <h2>ビデオ</h2> + <ol> + <li> + <a href="http://www.youtube.com/watch?v=Yc8YrVc47TI&feature=player_detailpage#t=1672s">Notifications in 4.1</a> + + </li> + </ol> +<h2>関連ドキュメント</h2> +<ol> + <li> + <a href="{@docRoot}design/patterns/notifications.html">Android Design: Notifications</a> + </li> +</ol> +</div> +</div> +<p> + 通知は、アプリケーションの通常の UI 以外で、ユーザーに表示できるメッセージです。システムが通知を発行通知すると、通知はまず<strong>通知エリア</strong>にアイコンで表示されます。 + +通知の詳細を確認するには、ユーザーが<strong>通知ドロワー</strong>を開く必要があります。 +ドロワー通知エリアと通知ドロワーはどちらも、システムによって制御されているエリアであり、ユーザーはいつでも見ることができます。 + +</p> +<img id="figure1" src="{@docRoot}images/ui/notifications/notification_area.png" height="" alt="" /> +<p class="img-caption"> + <strong>図 1.</strong> 通知エリアの通知。 +</p> +<img id="figure2" src="{@docRoot}images/ui/notifications/notification_drawer.png" width="280px" alt="" /> +<p class="img-caption"> + <strong>図 2.</strong> 通知ドロワーの通知。 +</p> + +<p class="note"><strong>注:</strong> 別途記載がある場合を除き、このガイドでは、バージョン 4 の <a href="{@docRoot}tools/support-library/index.html">サポート ライブラリ</a>の {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} クラスについて記述しています。クラス {@link android.app.Notification.Builder Notification.Builder} は、Android 3.0(API レベル 11)で追加されました。 + + + +</p> + +<h2 id="Design">設計上の考慮事項</h2> + +<p>通知は、Android ユーザー インターフェースの重要なパーツであり、独自の設計ガイドラインが設けられています。Android 5.0 (API レベル 21)で導入されたマテリアル デザインの変更は特に重要です。詳細については、「<a href="{@docRoot}training/material/index.html">マテリアル デザイン</a>」をご覧ください。 + + +通知とその操作の設計方法については、<a href="{@docRoot}design/patterns/notifications.html">通知</a>設計ガイドをご覧ください。 +</p> + +<h2 id="CreateNotification">通知を作成する</h2> + +<p>通知のための UI 情報とアクションを、{@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} オブジェクトに指定します。通知自体を作成するには、{@link android.support.v4.app.NotificationCompat.Builder#build NotificationCompat.Builder.build()} を呼び出します。これにより、指定された UI 情報とアクションを含む {@link android.app.Notification} オブジェクトが返されます。 + + + +通知を発行するには、{@link android.app.NotificationManager#notify NotificationManager.notify()} を呼び出して、この {@link android.app.Notification} オブジェクトをシステムに渡します。 + +</p> + +<h3 id="Required">必須通知コンテンツ</h3> +<p> + {@link android.app.Notification} オブジェクトの<em>必須</em>コンテンツは次のとおりです。 +</p> +<ul> + <li> + 小さなアイコン。{@link android.support.v4.app.NotificationCompat.Builder#setSmallIcon setSmallIcon()} で設定します。 + + </li> + <li> + タイトル。{@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()} で設定します。 + + </li> + <li> + 詳細テキスト。{@link android.support.v4.app.NotificationCompat.Builder#setContentText setContentText()} で設定します。 + + </li> +</ul> +<h3 id="Optional">省略可能な通知コンテンツと設定</h3> +<p> + 上記以外のすべての通知設定とコンテンツは省略可能です。省略可能な通知設定とコンテンツについては、{@link android.support.v4.app.NotificationCompat.Builder} のリファレンスをご覧ください。 + +</p> +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="Actions">通知アクション</h3> +<p> + 通知アクションは省略可能ですが、通知には、少なくとも 1 つのアクションを追加する必要があります。 + アクションは、ユーザーが通知からアプリケーションの {@link android.app.Activity} に直接移動することを可能にします。ユーザーは、移動先で、イベントを確認したりさらに作業を行ったりすることができます。 + + +</p> +<p> + 1 つの通知が複数のアクションを提供することもあります。そのため、ユーザーが通知をクリックした時にトリガーされるアクションを必ず定義してください。通常、このアクションは、アプリケーション内で {@link android.app.Activity} を開きます。 + +また、アラームのスヌーズやテキスト メッセージへの即時返信などの追加のアクションを実行するボタンを、通知に追加することもできます。この機能は、Android 4.1 から利用できるようになりました。 + +追加のアクション ボタンを使用する場合、それらのボタンの機能をアプリの {@link android.app.Activity} で利用できるようにする必要があります。詳細については、<a href="#Compatibility">互換性の確保</a>についてのセクションをご覧ください。 + + +</p> +<p> + {@link android.app.Notification} 内部では、アクションは、アプリケーションで {@link android.app.Activity} を開始する {@link android.content.Intent} が含まれる {@link android.app.PendingIntent} によって定義されます。 + + +{@link android.app.PendingIntent} を操作と関連付けるには、{@link android.support.v4.app.NotificationCompat.Builder} の該当するメソッドを呼び出します。 + +たとえば、ユーザーが通知ドロワーで通知のテキストをクリックしたときに {@link android.app.Activity} を開始する場合、{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()} を呼び出して {@link android.app.PendingIntent} を追加します。 + + + +</p> +<p> + ユーザーが通知をクリックしたときに {@link android.app.Activity} を開始することは、最も一般的なアクション シナリオです。 +ユーザーが通知を閉じた場合に {@link android.app.Activity} を開始することもできます。 +Android 4.1 以降では、アクション ボタンから {@link android.app.Activity} を開始できます。 +詳細については、{@link android.support.v4.app.NotificationCompat.Builder} のリファレンスをご覧ください。 + +</p> +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="Priority">通知の優先度</h3> +<p> + 必要に応じて、通知の優先度を設定できます。通知の優先度は、通知の表示方法についての端末 UI へのヒントの役割を果たします。 + + 通知の優先度を設定するには、{@link android.support.v4.app.NotificationCompat.Builder#setPriority(int) otificationCompat.Builder.setPriority()} を呼び出し、{@link android.support.v4.app.NotificationCompat} 優先度定数の 1 つを渡します。 + + +優先度レベルには、{@link android.support.v4.app.NotificationCompat#PRIORITY_MIN} (-2)から {@link android.support.v4.app.NotificationCompat#PRIORITY_MAX} (2)までの 5 段階あります。優先度レベルが設定されていない場合、優先度はデフォルト値の {@link android.support.v4.app.NotificationCompat#PRIORITY_DEFAULT} (0)になります。 + + + + + +</p> +<p> 適切な優先順位の設定方法については、<a href="{@docRoot}design/patterns/notifications.html">通知</a>設計ガイドの「Correctly set and manage notification priority」をご覧ください。 + + +</p> +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="SimpleNotification">簡単な通知を作成する</h3> +<p> + 次のスニペットでは、ユーザーに通知がクリックされたときに起動するアクティビティを指定する簡単な通知を作成しています。 +このコードでは {@link android.support.v4.app.TaskStackBuilder} オブジェクトを作成し、そのオブジェクトを使用して、アクションのための {@link android.app.PendingIntent} を作成していることにご注意ください。 + +詳細は、<a href="#NotificationResponse">アクティビティの開始時のナビゲーションの維持</a>セクションで説明しています。 + + +</p> +<pre> +NotificationCompat.Builder mBuilder = + new NotificationCompat.Builder(this) + .setSmallIcon(R.drawable.notification_icon) + .setContentTitle("My notification") + .setContentText("Hello World!"); +// Creates an explicit intent for an Activity in your app +Intent resultIntent = new Intent(this, ResultActivity.class); + +// The stack builder object will contain an artificial back stack for the +// started Activity. +// This ensures that navigating backward from the Activity leads out of +// your application to the Home screen. +TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); +// Adds the back stack for the Intent (but not the Intent itself) +stackBuilder.addParentStack(ResultActivity.class); +// Adds the Intent that starts the Activity to the top of the stack +stackBuilder.addNextIntent(resultIntent); +PendingIntent resultPendingIntent = + stackBuilder.getPendingIntent( + 0, + PendingIntent.FLAG_UPDATE_CURRENT + ); +mBuilder.setContentIntent(resultPendingIntent); +NotificationManager mNotificationManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +// mId allows you to update the notification later on. +mNotificationManager.notify(mId, mBuilder.build()); +</pre> +<p>これで、ユーザーに通知が行われました。</p> +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="ApplyStyle">通知に拡張レイアウトを適用する</h3> +<p> + 通知を拡張ビューに表示するには、まず {@link android.support.v4.app.NotificationCompat.Builder} オブジェクトを任意の標準ビュー オプションで作成します。 + +次に、{@link android.support.v4.app.NotificationCompat.Builder#setStyle Builder.setStyle()} を拡張レイアウト オブジェクトを引数に指定して呼び出します。 + +</p> +<p> + 通知の拡張機能は、Android 4.1 より前のバージョンでは利用できないことにご注意ください。Android 4.1 とそれ以前のプラットフォームでの通知の処理方法については、<a href="#Compatibility">互換性の確保</a>についてのセクションをご覧ください。 + + +</p> +<p> + たとえば、次のコード スニペットでは、先ほどのスニペットで作成した通知を変更して、拡張レイアウトを使用するようにしています。 + +</p> +<pre> +NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) + .setSmallIcon(R.drawable.notification_icon) + .setContentTitle("Event tracker") + .setContentText("Events received") +NotificationCompat.InboxStyle inboxStyle = + new NotificationCompat.InboxStyle(); +String[] events = new String[6]; +// Sets a title for the Inbox in expanded layout +inboxStyle.setBigContentTitle("Event tracker details:"); +... +// Moves events into the expanded layout +for (int i=0; i < events.length; i++) { + + inboxStyle.addLine(events[i]); +} +// Moves the expanded layout object into the notification object. +mBuilder.setStyle(inBoxStyle); +... +// Issue the notification here. +</pre> + +<h3 id="Compatibility">互換性を確保する</h3> + +<p> + 通知機能をセットするメソッドはサポート ライブラリのクラス {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} に登録されていますが、特定のバージョンですべての通知機能が利用できるわけではありません。 + + + たとえば、アクション ボタンは拡張通知の機能ですが、拡張通知自体が Android 4.1 以上でしか利用できないため、Android 4.1 以上でのみ表示されます。 + + +</p> +<p> + 可能な限り互換性を確保するには、{@link android.support.v4.app.NotificationCompat NotificationCompat} とそのサブクラス、特に {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} を使用して通知を作成します。 + + +さらに、通知の実装時に次の処理を行ってください。 +</p> +<ol> + <li> + ユーザーが利用しているバージョンにかかわらず、通知機能のすべてをすべてのユーザーに提供します。 +それには、アプリの {@link android.app.Activity} からすべての機能が利用できるようにする必要があります。このために、新しい {@link android.app.Activity} を追加した方がよい場合もあります。 + + + <p> + たとえば、{@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} を使用してメディア再生の開始と停止を行うコントロールを提供する場合、まずこのコントロールをアプリの {@link android.app.Activity} に実装します。 + + + + </p> + </li> + <li> + ユーザーが通知をクリックしたときにその {@link android.app.Activity} が起動するようにして、すべてのユーザーがその機能にアクセスできるようにします。 +それには、{@link android.app.Activity} のための {@link android.app.PendingIntent} を作成する必要があります。 + +{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()} を呼び出し、{@link android.app.PendingIntent} を通知に追加してください。 + + + </li> + <li> + 利用したい拡張通知機能を通知に追加します。追加した機能は、ユーザーが通知をクリックしたときに開始する {@link android.app.Activity} でも利用できることにご注意ください。 + + + </li> +</ol> + + +<!-- ------------------------------------------------------------------------------------------ --> +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="Managing">通知を管理する</h2> +<p> + 同じタイプのイベントのために通知を複数回発行する場合、そのたびに新しい通知を作成することは避ける必要があります。 +新しい通知を作成する代わりに、以前の通知を更新して一部の値を変更することやいくつかの値を追加することを検討してください。 + +</p> +<p> + たとえば、Gmail は新しいメールが届いたことを、未読メッセージの数を増やし通知に各メールの概要を追加することで、ユーザーに通知します。 +これは、通知の「スタッキング」と呼ばれています。詳細については、<a href="{@docRoot}design/patterns/notifications.html">通知</a>設計ガイドをご覧ください。 + + +</p> +<p class="note"> + <strong>注:</strong> この Gmail 機能には、「受信トレイ」の拡張レイアウトが必要です。これは、Android 4.1 以降で利用可能な拡張通知機能の 1 つです。 + +</p> +<p> + 次のセクションでは、通知の更新方法と通知の削除方法を説明します。 +</p> +<h3 id="Updating">通知を更新する</h3> +<p> + 後で更新できるように通知をセットアップするには、{@link android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()} を呼び出し、通知 ID を指定して通知を発行します。 + + 発行後に通知を更新するには、{@link android.support.v4.app.NotificationCompat.Builder} オブジェクトを更新または作成し、そのオブジェクトから {@link android.app.Notification} オブジェクトをビルドし、以前使用した ID と同じ ID で {@link android.app.Notification} を発行します。 + + +以前の通知がそのまま表示されている場合は、{@link android.app.Notification} オブジェクトのコンテンツから、その通知が更新されます。 + +以前の通知が閉じられている場合は、代わりに新しい通知が作成されます。 + +</p> +<p> + 次のスニペットでは、発生したイベントの数を反映するために通知が更新されています。 +このスニペットは通知をスタックし、概要を表示します。 +</p> +<pre> +mNotificationManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +// Sets an ID for the notification, so it can be updated +int notifyID = 1; +mNotifyBuilder = new NotificationCompat.Builder(this) + .setContentTitle("New Message") + .setContentText("You've received new messages.") + .setSmallIcon(R.drawable.ic_notify_status) +numMessages = 0; +// Start of a loop that processes data and then notifies the user +... + mNotifyBuilder.setContentText(currentText) + .setNumber(++numMessages); + // Because the ID remains unchanged, the existing notification is + // updated. + mNotificationManager.notify( + notifyID, + mNotifyBuilder.build()); +... +</pre> + +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="Removing">通知を削除する</h3> +<p> + 次のいずれかが発生するまで、通知は表示され続けます。 +</p> +<ul> + <li> + ユーザーが通知を個別に閉じるか、[Clear All] を使用して通知をすべて閉じる(通知を削除することができる場合)。 + + </li> + <li> + 作成時に {@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()} の呼び出しが行われた通知を、ユーザーがクリックする。 + + + </li> + <li> + 特定の通知 ID を指定して {@link android.app.NotificationManager#cancel(int) cancel()} を呼び出す(このメソッドは、実行中の処理に関する通知も削除します)。 + + </li> + <li> + {@link android.app.NotificationManager#cancelAll() cancelAll()} を呼び出す(このメソッドは、それまでに発行したすべての通知を削除します)。 + + </li> +</ul> +<!-- ------------------------------------------------------------------------------------------ --> +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="NotificationResponse">アクティビティの開始時にナビゲーションを維持する</h2> +<p> + 通知から {@link android.app.Activity} を開始する場合、ユーザーが期待するナビゲーション操作を変えないようにする必要があります。 +たとえば、 <i>[戻る]</i> がクリックされた場合、アプリケーションの標準的なワークフローでは、ホーム画面に戻る必要があります。また、 + <i>[最近使ったアプリ]</i> がクリックされた場合、{@link android.app.Activity} を別のタスクとして表示する必要があります。 +このナビゲーション操作を変えないようにするには、新たなタスクで {@link android.app.Activity} を開始する必要があります。 +{@link android.app.PendingIntent} を設定して新たなタスクを生成する方法は、開始する {@link android.app.Activity} の性質によって異なります。 + +通常は、次の 2 つの場合があります。 +</p> +<dl> + <dt> + 通常のアクティビティ + </dt> + <dd> + アプリケーションの標準的なワークフローの一部である {@link android.app.Activity} を開始します。 +この場合、{@link android.app.PendingIntent} を設定して新たなタスクを開始し、{@link android.app.PendingIntent} にバックスタックを提供します。これにより、アプリケーションの標準的な + + <i>「戻る」</i> 動作を再現します。 + <p> + Gmail アプリからの通知は、このタイプのアクティビティの一例です。1 つの電子メール メッセージの通知をクリックすると、メッセージそれ自体が表示されます。 +[<b>戻る</b>] をタップすると、通知から移動してきたのでなくホーム画面から Gmail に移動してきたかのように、Gmail からホーム画面に戻ります。 + + + </p> + <p> + これは、通知のタップ時に使用していたアプリケーションに関係なく発生します。 +たとえば、Gmail でメッセージを作成しているときに、1 つのメールの通知をクリックすると、すぐにそのメールに移動します。 +その場合、 <i>[戻る]</i> + をタップすると、作成中のメッセージに戻るのではなく、受信トレイ、ホーム画面の順に移動します。 + + </p> + </dd> + <dt> + 特殊なアクティビティ + </dt> + <dd> + ユーザーは、この {@link android.app.Activity} を、通知から開始した場合のみ見ることができます。 + ある意味では、通知自体に表示するのは難しい情報を提供することで、この {@link android.app.Activity} が通知を拡張しているということができます。 +このタイプのアクティビティでは、{@link android.app.PendingIntent} を設定して新たなタスクを開始します。 +ただし、開始した {@link android.app.Activity} はアプリケーションのアクティビティ フローには含まれていないので、バックスタックを作成する必要はありません。 + +たとえば、 <i>[戻る]</i> をクリックすると、ユーザーはホーム画面に移動します。 + + </dd> +</dl> +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="DirectEntry">通常のアクティビティの PendingIntent を設定する</h3> +<p> + ダイレクト エントリの {@link android.app.Activity} を開始する {@link android.app.PendingIntent} を設定するには、次の手順に従います。 + +</p> +<ol> + <li> + マニフェストに、アプリケーションの {@link android.app.Activity} の階層を定義します。 + <ol style="list-style-type: lower-alpha;"> + <li> + Android 4.0.3 以前へのサポートを追加します。これには、<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data></a></code> 要素を <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> の子として追加して、開始する {@link android.app.Activity} の親を指定します。 + + + + + <p> + この要素に、<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a>="android.support.PARENT_ACTIVITY"</code> を設定します。 + + <code><parent_activity_name></code> が親 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 要素の <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code> の値の場合は、<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#val">android:value</a>="<parent_activity_name>"</code> を設定します。 + + + + + +例については、以下の XML をご覧ください。 + </p> + </li> + <li> + また、Android 4.1 以降のサポートを追加します。これには、開始する {@link android.app.Activity} の <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 要素に、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">android:parentActivityName</a></code> 属性を追加します。 + + + + + </li> + </ol> + <p> + 最終的な XML は、次のようになります。 + </p> +<pre> +<activity + android:name=".MainActivity" + android:label="@string/app_name" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +<activity + android:name=".ResultActivity" + android:parentActivityName=".MainActivity"> + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value=".MainActivity"/> +</activity> +</pre> + </li> + <li> + {@link android.app.Activity} を開始する {@link android.content.Intent} に基づくバックスタックを作成します。 + + <ol style="list-style-type: lower-alpha;"> + <li> + {@link android.app.Activity} を開始する {@link android.content.Intent} を作成します。 + </li> + <li> + {@link android.app.TaskStackBuilder#create TaskStackBuilder.create()} を呼び出して、スタック ビルダーを作成します。 + + </li> + <li> + {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} を呼び出し、バックスタックをスタック ビルダーに追加します。 + + マニフェストに定義した階層のそれぞれの {@link android.app.Activity} ごとに、バックスタックに、{@link android.app.Activity} を開始する {@link android.content.Intent} が含まれます。 + +このメソッドは、新たなタスクでスタックを開始するためのフラグも追加します。 + + <p class="note"> + <strong>注:</strong> {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} の引数は開始した {@link android.app.Activity} への参照ですが、このメソッドの呼び出しによって、{@link android.app.Activity} を開始する {@link android.content.Intent} が追加されることはありません。 + + + +追加は、次の d. で行われます。 + </p> + </li> + <li> + {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()} を呼び出して、通知から {@link android.app.Activity} を開始する {@link android.content.Intent} を追加します。 + + + a. で作成した {@link android.content.Intent} を、引数として {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()} に渡します。 + + + </li> + <li> + 必要に応じて、{@link android.support.v4.app.TaskStackBuilder#editIntentAt TaskStackBuilder.editIntentAt()} を呼び出し、スタック上の {@link android.content.Intent} オブジェクトに引数を追加します。 + +これは、場合によっては、ターゲット {@link android.app.Activity} に、ユーザーが + + <i>[戻る]</i> を使って移動したときに、適切なデータが表示されるようにするために必要です。 + </li> + <li> + {@link android.support.v4.app.TaskStackBuilder#getPendingIntent getPendingIntent()} を呼び出し、このバックスタックのための {@link android.app.PendingIntent} を取得します。 + + この {@link android.app.PendingIntent} は、{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()} の引数として使用できます。 + + + </li> + </ol> + </li> +</ol> +<p> + 次のコード スニペットでは、上記の処理を行っています。 +</p> +<pre> +... +Intent resultIntent = new Intent(this, ResultActivity.class); +TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); +// Adds the back stack +stackBuilder.addParentStack(ResultActivity.class); +// Adds the Intent to the top of the stack +stackBuilder.addNextIntent(resultIntent); +// Gets a PendingIntent containing the entire back stack +PendingIntent resultPendingIntent = + stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); +... +NotificationCompat.Builder builder = new NotificationCompat.Builder(this); +builder.setContentIntent(resultPendingIntent); +NotificationManager mNotificationManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +mNotificationManager.notify(id, builder.build()); +</pre> +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="ExtendedNotification">特殊なアクティビティの PendingIntent を設定する</h3> +<p> + 次のセクションでは、特殊なアクティビティのための {@link android.app.PendingIntent} の設定方法を説明します。 + +</p> +<p> + 特殊な {@link android.app.Activity} はバックスタックを必要としません。そのため、マニフェストにその {@link android.app.Activity} の階層を定義する必要はありません。また、バックスタックを作成するために {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} を呼び出す必要もありません。 + + + +代わりに、マニフェストを利用して {@link android.app.Activity} のタスク オプションを設定し、{@link android.app.PendingIntent#getActivity getActivity()} を呼び出して {@link android.app.PendingIntent} を作成します。 + + +</p> +<ol> + <li> + マニフェストで、{@link android.app.Activity} の <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 要素に、次の属性を追加します。 + + + <dl> + <dt> +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code> + </dt> + <dd> + アクティビティの完全修飾クラス名。 + </dd> + <dt> +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code> + </dt> + <dd> + コードにセットした {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} フラグと組み合わせて、{@link android.app.Activity} がアプリケーションのデフォルトのタスクに入ることがないようにします。 + + +アプリケーションのアフィニティがデフォルトのままの既存タスクは影響を受けません。 + + </dd> + <dt> +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code> + </dt> + <dd> + 新しいタスクを、 <i>[最近使ったアプリ]</i> から除外し、ユーザーが新しいタスクに間違って戻ることがないようにします。 + + </dd> + </dl> + <p> + 次のスニペットは、この要素を示しています。 + </p> +<pre> +<activity + android:name=".ResultActivity" +... + android:launchMode="singleTask" + android:taskAffinity="" + android:excludeFromRecents="true"> +</activity> +... +</pre> + </li> + <li> + 通知をビルドし発行します。 + <ol style="list-style-type: lower-alpha;"> + <li> + {@link android.app.Activity} を開始する {@link android.content.Intent} を作成します。 + + </li> + <li> + フラグ {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} と {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK} を指定して {@link android.content.Intent#setFlags setFlags()} を呼び出し、{@link android.app.Activity} を新しい空のタスクで開始するように設定します。 + + + + + </li> + <li> + {@link android.content.Intent} に、必要に応じてオプションを設定します。 + </li> + <li> + {@link android.app.PendingIntent#getActivity getActivity()} を呼び出し、{@link android.content.Intent} から {@link android.app.PendingIntent} を作成します。 + + この {@link android.app.PendingIntent} は、{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()} の引数として使用できます。 + + + </li> + </ol> + <p> + 次のコード スニペットでは、上記の処理を行っています。 + </p> +<pre> +// Instantiate a Builder object. +NotificationCompat.Builder builder = new NotificationCompat.Builder(this); +// Creates an Intent for the Activity +Intent notifyIntent = + new Intent(this, ResultActivity.class); +// Sets the Activity to start in a new, empty task +notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TASK); +// Creates the PendingIntent +PendingIntent notifyPendingIntent = + PendingIntent.getActivity( + this, + 0, + notifyIntent, + PendingIntent.FLAG_UPDATE_CURRENT +); + +// Puts the PendingIntent into the notification builder +builder.setContentIntent(notifyPendingIntent); +// Notifications are issued by sending them to the +// NotificationManager system service. +NotificationManager mNotificationManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +// Builds an anonymous Notification object from the builder, and +// passes it to the NotificationManager +mNotificationManager.notify(id, builder.build()); +</pre> + </li> +</ol> +<!-- ------------------------------------------------------------------------------------------ --> +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="Progress">通知に進捗状況を表示する</h2> +<p> + 通知には、進行中の処理の状況をユーザーに示すアニメーション表示の進捗インジケーターを表示できます。 +その処理にどれくらいの時間がかかるかと、ある時点でその処理がどれだけ完了しているかを見積もることができる場合、「確定(determinate)」タイプのインジケーター(プログレスバー)を使用します。 + +処理にかかる時間を見積もることができない場合は、「不確定(indeterminate)」タイプのインジケーター(アクティビティ インジケーター)を使用します。 + +</p> +<p> + 進捗インジケーターは、{@link android.widget.ProgressBar} クラスのプラットフォーム実装で表示されます。 + +</p> +<p> + Android 4.0 以降のプラットフォーム上で進捗インジケーターを使用するには、{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()} を呼び出します。 +それ以前のバージョンでは、{@link android.widget.ProgressBar} ビューを含むカスタム通知レイアウトを作成する必要があります。 + + +</p> +<p> + 次のセクションでは、{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()} を使用して、通知に進捗状況を表示する方法を説明します。 + +</p> +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="FixedProgress">範囲固定の進捗インジケーターを表示する</h3> +<p> + 確定プログレスバーを表示するには、{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(max, progress, false)} を呼び出して通知にバーを追加してから、その通知を発行します。 + +処理の進行に合わせて、<code>progress</code> の値を増やし、通知を更新します。 +処理の最後には、<code>progress</code> が <code>max</code> と等しくなります。 +{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()} を呼び出す一般的な方法は、<code>max</code> に 100 を設定して、処理の「進捗度」の値である <code>progress</code> の値を増やすことです。 + + + +</p> +<p> + 処理の完了時には、プログレスバーを表示したままにすることも、削除することもできます。いずれの場合でも、通知のテキストを更新して、処理が完了したことを示すことを忘れないでください。 + + プログレスバーを削除するには、{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, false)} を呼び出します。 + +次に例を示します。 +</p> +<pre> +... +mNotifyManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +mBuilder = new NotificationCompat.Builder(this); +mBuilder.setContentTitle("Picture Download") + .setContentText("Download in progress") + .setSmallIcon(R.drawable.ic_notification); +// Start a lengthy operation in a background thread +new Thread( + new Runnable() { + @Override + public void run() { + int incr; + // Do the "lengthy" operation 20 times + for (incr = 0; incr <= 100; incr+=5) { + // Sets the progress indicator to a max value, the + // current completion percentage, and "determinate" + // state + mBuilder.setProgress(100, incr, false); + // Displays the progress bar for the first time. + mNotifyManager.notify(0, mBuilder.build()); + // Sleeps the thread, simulating an operation + // that takes time + try { + // Sleep for 5 seconds + Thread.sleep(5*1000); + } catch (InterruptedException e) { + Log.d(TAG, "sleep failure"); + } + } + // When the loop is finished, updates the notification + mBuilder.setContentText("Download complete") + // Removes the progress bar + .setProgress(0,0,false); + mNotifyManager.notify(ID, mBuilder.build()); + } + } +// Starts the thread by calling the run() method in its Runnable +).start(); +</pre> + +<!-- ------------------------------------------------------------------------------------------ --> +<h3 id="ActivityIndicator">進行中アクティビティ インジケーターを表示する</h3> +<p> + 不確定アクティビティ インジケーターを表示するには、{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, true)}(最初の 2 つの引数は無視されます)を使用して通知に追加し、通知を発行します。 + +このインジケーターの外見は、アニメーションが常時表示されていること以外はプログレスバーと同じです。 + +</p> +<p> + 処理の開始時に通知を発行します。通知を変更するまで、アニメーションは表示され続けます。 +処理が完了したら、{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, false)} を呼び出し、次に通知を更新してアクティビティ インジケーターを削除します。 + + + この操作を行わないと、処理が完了してもアニメーションが表示され続けることになります。また、通知のテキストを更新して、処理が完了したことを示すことを忘れないでください。 + +</p> +<p> + アクティビティ インジケーターの仕組みについては、上記のスニペットをご覧ください。次のコード行を探します。 +</p> +<pre> +// Sets the progress indicator to a max value, the current completion +// percentage, and "determinate" state +mBuilder.setProgress(100, incr, false); +// Issues the notification +mNotifyManager.notify(0, mBuilder.build()); +</pre> +<p> + 見つけたコードを次のコードに置き換えます。 +</p> +<pre> + // Sets an activity indicator for an operation of indeterminate length +mBuilder.setProgress(0, 0, true); +// Issues the notification +mNotifyManager.notify(0, mBuilder.build()); +</pre> + +<h2 id="metadata">通知メタデータ</h2> + +<p>通知は、次の {@link android.support.v4.app.NotificationCompat.Builder} メソッドを使用して割り当てるメタデータによって、ソートされることがあります。 +</p> + +<ul> + <li>{@link android.support.v4.app.NotificationCompat.Builder#setCategory(java.lang.String) setCategory()} は、端末が優先モードの場合のアプリ通知の処理方法を設定します(たとえば、通知が着信、インスタント メッセージ、アラームを知らせる場合など)。 + +</li> + <li>{@link android.support.v4.app.NotificationCompat.Builder#setPriority(int) setPriority()} は優先度フィールドに {@code PRIORITY_MAX} または {@code PRIORITY_HIGH} が設定されている通知が、音声または振動を発する通知の場合、小さなフローティング ウィンドウに表示されるようにします。 + +</li> + <li>{@link android.support.v4.app.NotificationCompat.Builder#addPerson(java.lang.String) addPerson()} を使用すると、通知に人物のリストを追加できます。 +アプリは、このリストを利用して、システムに合図を送り、特定の人達からの通知をグループ化したり、それらの人達からの通知を重要度が高い通知としてランク付けしたりします。 + +</li> +</ul> + +<div class="figure" style="width:230px"> + <img src="{@docRoot}images/ui/notifications/heads-up.png" alt="" width="" height="" id="figure3" /> + <p class="img-caption"> + <strong>図 3.</strong> ヘッドアップ通知を表示する全画面アクティビティ + </p> +</div> + +<h2 id="Heads-up">ヘッドアップ通知</h2> + +<p>Android 5.0(API レベル 21)では、端末がアクティブな場合(端末がロックされておらず、画面がオンになっている場合)に、小さなフローティング ウィンドウ(<em>ヘッドアップ通知</em>とも呼ばれます)に通知を表示することができます。 + +これらの通知は、ヘッドアップ通知がアクション ボタンも表示すること以外は、通知をコンパクトにしたものと同じように表示されます。 + +使用中のアプリから移動しなくても、ユーザーは、ヘッドアップ通知に反応したりヘッドアップ通知を閉じたりすることができます。 +</p> + +<p>ヘッドアップ通知のトリガーとなる条件には、たとえば以下のようなものがあります。</p> + +<ul> + <li>ユーザーのアクティビティが全画面モードであること(アプリが {@link android.app.Notification#fullScreenIntent} を使用していること)、または +</li> + <li>その通知が高い優先度を持ち、着信音または振動を使用していること +</li> +</ul> + +<h2 id="lockscreenNotification">ロック画面通知</h2> + +<p>Android 5.0(API レベル 21)では、通知をロック画面に表示できるようになりました。 +アプリは、この機能を利用してメディア再生コントロールやその他の一般的なアクションを提供できます。 +ユーザーは設定でロック画面に通知を表示するかどうか選ぶことができます。また、開発者も、アプリからの通知をロック画面に表示するかどうか指定できます。 +</p> + +<h3 id="visibility">可視性を設定する</h3> + +<p>アプリでは、保護されたロック画面に表示される通知の表示の詳細レベルをコントロールできます。 +{@link android.support.v4.app.NotificationCompat.Builder#setVisibility(int) setVisibility()} を呼び出し、次の値のいずれかを指定してください。 +</p> + +<ul> + <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC} では、通知のフルコンテンツが表示されます。 +</li> + <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_SECRET} では、ロック画面に、通知のいずれの部分も表示しません。 +</li> + <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} では、通知のアイコンやコンテンツのタイトルなどの基本的な情報を表示しますが、通知のフルコンテンツは表示されません。 +</li> +</ul> + +<p>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} を設定すると、特定の内容を非表示にした代替バージョンの通知コンテンツを提供できます。 +たとえば、SMS アプリで <em>3 件の新しいテキスト メッセージがある</em>ことを示す通知を表示する場合に、メッセージ コンテンツと送信者を非表示にできます。 + +この代替通知を提供するには、{@link android.support.v4.app.NotificationCompat.Builder} を使用してまず置換用の通知を作成し、 +プライベート通知オブジェクトを作成したら、その置換用の通知をプライベート通知オブジェクトに {@link android.support.v4.app.NotificationCompat.Builder#setPublicVersion(android.app.Notification) setPublicVersion()} メソッドを使用してアタッチしてください。 + + +</p> + +<h3 id="controllingMedia">ロック画面でのメディア再生をコントロールする</h3> + +<p>Android 5.0(API レベル 21)では、{@link android.media.RemoteControlClient} を使用したメディア コントロールは、ロック画面に表示されません。このクラスは廃止済みです。 +代わりに、{@link android.app.Notification.MediaStyle} テンプレートと {@link android.app.Notification.Builder#addAction(android.app.Notification.Action) addAction()} メソッドを使用します。このメソッドは、アクションをクリックできるアイコンに変換します。 + + +</p> + +<p class="note"><strong>注:</strong> このテンプレートと {@link android.app.Notification.Builder#addAction(android.app.Notification.Action) addAction()} メソッドはサポート ライブラリには含まれません。そのため、これらの機能は Android 5.0 以降でのみ動作します。 + +</p> + +<p>Android 5.0 でロック画面にメディア再生コントロールを表示するには、可視性を上記の{@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC} に設定します。 +その後、次のサンプルコードに従って、アクションを追加し {@link android.app.Notification.MediaStyle} テンプレートを設定します。 + +</p> + +<pre> +Notification notification = new Notification.Builder(context) + // Show controls on lock screen even when user hides sensitive content. + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setSmallIcon(R.drawable.ic_stat_player) + // Add media control buttons that invoke intents in your media service + .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0 + .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent) // #1 + .addAction(R.drawable.ic_next, "Next", nextPendingIntent) // #2 + // Apply the media style template + .setStyle(new Notification.MediaStyle() + .setShowActionsInCompactView(1 /* #1: pause button */) + .setMediaSession(mMediaSession.getSessionToken()) + .setContentTitle("Wonderful music") + .setContentText("My Awesome Band") + .setLargeIcon(albumArtBitmap) + .build(); +</pre> + +<p class="note"><strong>注:</strong> {@link android.media.RemoteControlClient} の廃止は、他の点でもメディアのコントロールに影響を与えています。 +新しい API でのメディア セッションの管理と再生のコントロールの詳細については、<a href="{@docRoot}about/versions/android-5.0.html#MediaPlaybackControl">メディア再生コントロール</a>をご覧ください。 + +</p> + + +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="CustomNotification">カスタム通知レイアウト</h2> +<p> + 通知フレームワークでは、カスタム通知レイアウトを定義することができます。カスタム通知レイアウトは、{@link android.widget.RemoteViews} オブジェクトに通知の外観を定義します。 + + カスタム レイアウトの通知は通常の通知と似ていますが、XML レイアウト ファイルに定義された {@link android.widget.RemoteViews} が使用されています。 + +</p> +<p> + カスタム通知レイアウトで使用できる高さは、通知ビューによって異なります。標準ビュー レイアウトでは 64 dp までで、拡張ビュー レイアウトでは 256 dp までです。 + +</p> +<p> + カスタム通知レイアウトを定義するには、まず、XML レイアウト ファイルをインフレートする {@link android.widget.RemoteViews} オブジェクトのインスタンスを作成します。 +次に、{@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()} などのメソッドを呼び出す代わりに、{@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()} を呼び出します。 + + +コンテンツの詳細をカスタム通知に設定するには、{@link android.widget.RemoteViews} のメソッドを使用してビューの子の値を設定します。 + + +</p> +<ol> + <li> + 別ファイルに通知の XML レイアウトを作成します。ファイル名はどのような名前でもかまいませんが、拡張子は必ず <code>.xml</code> にします。 + + </li> + <li> + アプリで、{@link android.widget.RemoteViews} メソッドを使用して、通知のアイコンとテキストを定義します。 +{@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()} を呼び出して、この {@link android.widget.RemoteViews} オブジェクトを {@link android.support.v4.app.NotificationCompat.Builder} にセットします。 + +{@link android.widget.RemoteViews} オブジェクトに背景 {@link android.graphics.drawable.Drawable} を設定することは避けてください。文字が読めなくなる場合があります。 + + + </li> +</ol> +<p> + {@link android.widget.RemoteViews} クラスには、通知のレイアウトに {@link android.widget.Chronometer} や {@link android.widget.ProgressBar} を簡単に追加できるメソッドも含まれています。 + +通知のカスタム レイアウトの作成についての詳細は、{@link android.widget.RemoteViews} のリファレンスをご覧ください。 + +</p> +<p class="caution"> + <strong>警告:</strong> カスタム通知レイアウトを使用する場合、そのカスタム通知レイアウトがさまざまな画面の向きと解像度で適切に表示されるかどうか、十分に注意してください。 +すべてのビュー レイアウトでさまざまな画面の向きと解像度への対応に注意する必要がありますが、通知ドロワーのスペースが限られているため、通知では特に注意する必要があります。 + +カスタム レイアウトは複雑にし過ぎないようにしてください。また、必ずさまざまな構成でテストするようにしてください。 + +</p> +<!-- ------------------------------------------------------------------------------------------ --> +<h4>カスタム通知のテキストにスタイル リソースを使用する</h4> +<p> + カスタム通知のテキストには、必ずスタイル リソースを使用してください。通知の背景色は端末やバージョンによって異なりますが、スタイル リソースを使用することで、この問題に対処できます。 + +Android 2.3 以降では、標準の通知レイアウトのテキストのスタイルは、システムによって定義されています。 +Android 2.3 以降を対象とするアプリケーションで同じスタイルを使用する場合は、表示される背景でテキストを読むことができるかご確認ください。 + +</p> diff --git a/docs/html-intl/intl/ja/guide/topics/ui/overview.jd b/docs/html-intl/intl/ja/guide/topics/ui/overview.jd new file mode 100644 index 000000000000..08d93560cb4e --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/ui/overview.jd @@ -0,0 +1,71 @@ +page.title=UI の概要 +@jd:body + + +<p>Android アプリのすべてのユーザー インターフェース エレメントは、{@link android.view.View} と {@link android.view.ViewGroup} オブジェクトを使ってビルドされています。 +{@link android.view.View} は、ユーザーが相互操作できる、画面上で何かを描画するオブジェクトです。 +{@link android.view.ViewGroup} は、インターフェースのレイアウトを定義するために、その他の {@link android.view.View}(と {@link android.view.ViewGroup})オブジェクトを保持するオブジェクトです。 + +</p> + +<p>Android では、共通の入力コントロール(ボタンやテキスト フィールドなど)とさまざまなレイアウトモデル(線形レイアウトや相対レイアウトなど)を提供する {@link android.view.View} と {@link android.view.ViewGroup} サブクラスの両方が提供されています。 + +</p> + + +<h2 id="Layout">ユーザー インターフェースのレイアウト</h2> + +<p>アプリの各コンポーネントのユーザー インターフェースは、図 1 のように、{@link +android.view.View} と {@link android.view.ViewGroup} オブジェクトの階層を使って定義されます。各ビューグループは、子ビューをまとめる非表示のコンテナであり、子ビューは UI の一部を描画する入力コントロールまたはその他のウィジェットです。この階層ツリーは、必要に応じて単純にまたは複雑にすることができますが、パフォーマンスの点では単純な階層ツリーが最適です。 + + + +</p> + +<img src="{@docRoot}images/viewgroup.png" alt="" /> +<p class="img-caption"><strong>図 1.</strong> UI レイアウトを定義するビュー階層の図。 +</p> + +<p>レイアウトを宣言するには、コードで {@link android.view.View} オブジェクトのインスタンスを作成してツリーのビルドを始めることができますが、レイアウトを定義する最も簡単で効率的な方法は XML ファイルを使用することです。XML では HTML のように、人が見える構造でレイアウトが提供されます。 + +</p> + +<p>ビューの XML 要素名は、それが表す Android クラスによって決まります。<code><TextView></code> 要素は UI で {@link android.widget.TextView} ウィジェットを、<code><LinearLayout></code> 要素は {@link android.widget.LinearLayout} ビューグループを作成します。 + + + </p> + +<p>たとえば、テキストビューとボタンを含む単純な縦レイアウトは次のようになります。</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="I am a TextView" /> + <Button android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="I am a Button" /> +</LinearLayout> +</pre> + +<p>アプリでレイアウト リソースを読み込むとき、Android はレイアウトの各ノードを初期化して、他の動作の定義、オブジェクト状態の照会、レイアウトの変更をするのに使用できるランタイム オブジェクトにします。 + +</p> + +<p>UI レイアウト作成のガイドについては、<a href="declaring-layout.html">XML レイアウト</a>をご覧ください。 + + + +<h2 id="UIComponents">ユーザー インターフェース コンポーネント</h2> + +<p>{@link android.view.View} と {@link android.view.ViewGroup} オブジェクトを使用してすべての UI をビルドする必要はありません。 +Android では、コンテンツの定義に必要な標準的な UI レイアウトを提供する複数のアプリ コンポーネントが提供されます。 +これらの各 UI コンポーネントには、それぞれのドキュメントで説明されている固有の API(<a href="{@docRoot}guide/topics/ui/actionbar.html">アクションバー</a>、<a href="{@docRoot}guide/topics/ui/dialogs.html">ダイアログ</a>、<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">状態通知</a>など)があります。 +</p> + + diff --git a/docs/html-intl/intl/ja/guide/topics/ui/settings.jd b/docs/html-intl/intl/ja/guide/topics/ui/settings.jd new file mode 100644 index 000000000000..9e6bb9d04169 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/ui/settings.jd @@ -0,0 +1,1202 @@ +page.title=設定 +page.tags=preference,preferenceactivity,preferencefragment + +@jd:body + + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>本書の内容</h2> +<ol> + <li><a href="#Overview">概要</a> + <ol> + <li><a href="#SettingTypes">プリファレンス</a></li> + </ol> + </li> + <li><a href="#DefiningPrefs">XML にプリファレンスを定義する</a> + <ol> + <li><a href="#Groups">設定グループを作成する</a></li> + <li><a href="#Intents">インテントを使用する</a></li> + </ol> + </li> + <li><a href="#Activity">プリファレンス アクティビティを作成する</a></li> + <li><a href="#Fragment">プリファレンス フラグメントを使用する</a></li> + <li><a href="#Defaults">デフォルト値を設定する</a></li> + <li><a href="#PreferenceHeaders">プリファレンス ヘッダーを使用する</a> + <ol> + <li><a href="#CreateHeaders">ヘッダー ファイルを作成する</a></li> + <li><a href="#DisplayHeaders">ヘッダーを表示する</a></li> + <li><a href="#BackCompatHeaders">旧バージョンでプリファレンス ヘッダーをサポートする</a></li> + </ol> + </li> + <li><a href="#ReadingPrefs">プリファレンスを読み込む</a> + <ol> + <li><a href="#Listening">プリファレンスの変化をリッスンする</a></li> + </ol> + </li> + <li><a href="#NetworkUsage">ネットワークの使用を管理する</a></li> + <li><a href="#Custom">カスタム プリファレンスを作成する</a> + <ol> + <li><a href="#CustomSelected">ユーザー インターフェースを指定する</a></li> + <li><a href="#CustomSave">設定の値を保存する</a></li> + <li><a href="#CustomInitialize">現在の値を初期化する</a></li> + <li><a href="#CustomDefault">デフォルト値を提供する</a></li> + <li><a href="#CustomSaveState">プリファレンスの状態を保存し復元する</a></li> + </ol> + </li> +</ol> + +<h2>キークラス</h2> +<ol> + <li>{@link android.preference.Preference}</li> + <li>{@link android.preference.PreferenceActivity}</li> + <li>{@link android.preference.PreferenceFragment}</li> +</ol> + + +<h2>関連ドキュメント</h2> +<ol> + <li><a href="{@docRoot}design/patterns/settings.html">Settings design guide</a></li> +</ol> +</div> +</div> + + + + +<p>多くの場合、アプリケーションには、ユーザーがアプリの機能や動作を変更できる設定が含まれています。たとえば、一部のアプリでは、通知を有効にするかどうかや、アプリケーションがクラウドとデータを同期する頻度を、ユーザーが指定できます。 + +</p> + +<p>アプリに設定機能を提供するには、Android の {@link android.preference.Preference} API を使用して、他の Android アプリ(システム設定を含む)の操作と整合性のあるインターフェースを構築する必要があります。 + +このドキュメントでは、{@link android.preference.Preference} API を使用して、アプリの設定機能を構築する方法について説明します。 +</p> + +<div class="note design"> +<p><strong>設定の設計</strong></p> + <p>設定の設計方法については、<a href="{@docRoot}design/patterns/settings.html">設定</a>のデザインガイドをご覧ください。</p> +</div> + + +<img src="{@docRoot}images/ui/settings/settings.png" alt="" width="435" /> +<p class="img-caption"><strong>図 1.</strong> Android SMS アプリの設定のスクリーンショット +{@link android.preference.Preference} で定義されたアイテムを選択すると、設定を変更するためのインターフェースが開きます。 +</p> + + + + +<h2 id="Overview">概要</h2> + +<p>設定は、{@link android.view.View} オブジェクトを使用してユーザー インターフェースを作成する方法ではなく、XML ファイルで宣言された {@link android.preference.Preference} クラスの各種のサブクラスを使用する方法で作成されます。 + +</p> + +<p>1 つの {@link android.preference.Preference} オブジェクトが、1 つの設定の構成要素になります。 +各 {@link android.preference.Preference} はアイテムとしてリストに表示され、ユーザーが設定を変更するための適切な UI を提供します。 +たとえば、{@link android.preference.CheckBoxPreference} はチェックボックスを表示するリストアイテムを作成し、{@link android.preference.ListPreference} は、選択リスト付きのダイアログを開くアイテムを作成します。 + +</p> + +<p>追加した各 {@link android.preference.Preference} は、アプリの設定のためのデフォルトの {@link android.content.SharedPreferences} ファイルに設定を保存するためにシステムが使用する対応するキーと値のペアを持ちます。 + +ユーザーが設定を変更する場合、システムが {@link android.content.SharedPreferences} ファイルの対応する値を更新します。 +関連する {@link android.content.SharedPreferences} ファイルを直接操作することが必要なのは、ユーザーの設定に基づいてアプリの動作を決定するために値を読み込むことが必要な場合のみです。 + +</p> + +<p>各設定の {@link android.content.SharedPreferences} に保存される値のデータ型は、次のいずれかにすることができます。 +</p> + +<ul> + <li>Boolean</li> + <li>Float</li> + <li>Int</li> + <li>Long</li> + <li>String</li> + <li>String {@link java.util.Set}</li> +</ul> + +<p>アプリの設定の UI は {@link android.view.View} オブジェクトではなく {@link android.preference.Preference} で作成されているため、リストの設定を表示するには、専用の {@link android.app.Activity} サブクラスまたは {@link android.app.Fragment} サブクラスを使用する必要があります。 + + +</p> + +<ul> + <li>アプリが 3.0 よりも前のバージョンの Android(API レベル 10 以下)をサポートしている場合は、{@link android.preference.PreferenceActivity} クラスを継承してアクティビティを作成する必要があります。 +</li> + <li>Android 3.0 以降では、代わりに、アプリの設定を表示する {@link android.preference.PreferenceFragment} をホストする従来の {@link android.app.Activity} を使用します。ただし、設定のグループが複数ある場合は、{@link android.preference.PreferenceActivity} を使用して大きな画面用の 2 ペイン レイアウトを作成することもできます。 + + +</li> +</ul> + +<p>{@link android.preference.PreferenceActivity} と {@link android.preference.PreferenceFragment} のインスタンスの設定方法は、<a href="#Activity">プリファレンス アクティビティを作成する</a>と<a href="#Fragment">プリファレンス フラグメントを使用する</a>セクションをご覧ください。 + +</p> + + +<h3 id="SettingTypes">プリファレンス</h3> + +<p>アプリの各設定は、{@link android.preference.Preference} クラスの個々のサブクラスに相当します。 +各サブクラスには、設定のタイトルやデフォルト値などを指定できる一連の核となるプロパティが含まれています。 +また、各サブクラスは、専用のプロパティとユーザー インターフェースを提供しています。 +たとえば、図 1. は、SMS アプリの設定のスクリーンショットです。 +設定画面の各リスト アイテムは、それぞれ異なる {@link android.preference.Preference} オブジェクトに基づいています。 +</p> + +<p>以下は、最も一般的なプリファレンスの一部です。</p> + +<dl> + <dt>{@link android.preference.CheckBoxPreference}</dt> + <dd>有効または無効にする設定のチェックボックス付きのアイテムを表示します。保存される値は、Boolean です(オンの場合、<code>true</code>)。 +</dd> + + <dt>{@link android.preference.ListPreference}</dt> + <dd>ラジオボタンのリスト付きのダイアログを開きます。保存される値は、サポートされるデータ型(上記参照)であればどのデータ型にもできます。 +</dd> + + <dt>{@link android.preference.EditTextPreference}</dt> + <dd>{@link android.widget.EditText} ウィジェット付きのダイアログを開きます。保存される値は、{@link java.lang.String} です。 +</dd> +</dl> + +<p>その他のサブクラスと対応するプロパティについては、{@link android.preference.Preference} クラスをご覧ください。 +</p> + +<p>もちろん、組み込みのクラスがすべてのニーズを満たすわけではなく、アプリケーションがより特殊な機能を必要とする可能性もあります。 +たとえば、プラットフォームは、現時点では、数字や日付を選択するための {@link android.preference.Preference} クラスを提供していません。 +そのため、独自の {@link android.preference.Preference} サブクラスを定義することが必要になる場合もあります。 +詳細については、<a href="#Custom">カスタム プリファレンスを作成する</a>セクションをご覧ください。</p> + + + +<h2 id="DefiningPrefs">XML にプリファレンスを定義する</h2> + +<p>実行時に新しい {@link android.preference.Preference} オブジェクトのインスタンスを作成することもできますが、{@link android.preference.Preference} オブジェクトの階層で XML に設定のリストを定義する必要があります。 + +XML ファイルは更新が容易な簡単に読むことができる構造を持つため XML ファイルを使用して設定のコレクションを定義することをお勧めします。 +また、アプリの設定は通常、事前設定されていますが、設定のコレクションを実行時に変更することもできます。 +</p> + +<p>各 {@link android.preference.Preference} サブクラスは、{@code <CheckBoxPreference>} などのクラス名と一致する XML 要素で定義できます。 +</p> + +<p>この XML ファイルは、{@code res/xml/} ディレクトリに保存する必要があります。この XML ファイルには好きな名前を付けることができますが、一般的には、{@code preferences.xml} という名前が使用されています。 +階層の分岐(この分岐がそれ自身の設定のリストを開きます)が {@link android.preference.PreferenceScreen} のネストされたインスタンスを使用して宣言されているため、必要なファイルは通常 1 ファイルのみです。 + +</p> + +<p class="note"><strong>注:</strong> 複数ペイン レイアウトの設定を作成する場合は、フラグメントごとに別々の XML ファイルが必要です。 +</p> + +<p>XML ファイルのルートノードは、{@link android.preference.PreferenceScreen <PreferenceScreen>} 要素にする必要があります。 +この要素内に、各 {@link android.preference.Preference} を追加します。 +{@link android.preference.PreferenceScreen <PreferenceScreen>} 要素内に追加したそれぞれの子は、設定のリストで 1 つのアイテムとして表示されます。 + +</p> + +<p>次に例を示します。</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <CheckBoxPreference + android:key="pref_sync" + android:title="@string/pref_sync" + android:summary="@string/pref_sync_summ" + android:defaultValue="true" /> + <ListPreference + android:dependency="pref_sync" + android:key="pref_syncConnectionType" + android:title="@string/pref_syncConnectionType" + android:dialogTitle="@string/pref_syncConnectionType" + android:entries="@array/pref_syncConnectionTypes_entries" + android:entryValues="@array/pref_syncConnectionTypes_values" + android:defaultValue="@string/pref_syncConnectionTypes_default" /> +</PreferenceScreen> +</pre> + +<p>この例には、{@link android.preference.CheckBoxPreference} と {@link android.preference.ListPreference} が含まれています。 +どちらのアイテムにも次の 3 つの属性が含まれています。</p> + +<dl> + <dt>{@code android:key}</dt> + <dd>この属性は、データ値を保持するプリファレンスで必要です。設定の値を {@link android.content.SharedPreferences} に保存するときにシステムが使用する一意のキー(文字列)を指定します。 + + + <p>プリファレンスが {@link android.preference.PreferenceCategory} または{@link android.preference.PreferenceScreen} の場合、またはプリファレンスが {@link android.content.Intent} の呼び出しを指定している場合(<a href="#Intents">{@code <intent>}</a> 要素を使用)、または {@link android.app.Fragment} の表示を指定している場合(<a href="{@docRoot}reference/android/preference/Preference.html#attr_android:fragment">{@code android:fragment}</a> 属性を使用)のみ、インスタンスでこの属性は<em>必要ありません</em>。 + + +</p> + </dd> + <dt>{@code android:title}</dt> + <dd>この属性は、ユーザーに表示される設定の名前です。</dd> + <dt>{@code android:defaultValue}</dt> + <dd>この属性は、システムが {@link android.content.SharedPreferences} ファイルに設定する必要がある初期値を指定します。 +すべての設定のデフォルト値を指定する必要があります。 +</dd> +</dl> + +<p>その他のサポートされている属性については、{@link android.preference.Preference}(と対応するサブクラス)のドキュメントをご覧ください。 +</p> + + +<div class="figure" style="width:300px"> + <img src="{@docRoot}images/ui/settings/settings-titles.png" alt="" /> + <p class="img-caption"><strong>図 2.</strong> カテゴリを設定しタイトルを付ける + <br/><b>1.</b>カテゴリは、{@link android.preference.PreferenceCategory <PreferenceCategory>} 要素で指定します。 + <br/><b>2.</b>タイトルは、{@code android:title} 属性で指定します。 +</p> +</div> + + +<p>設定のリストが 10 アイテムを超える場合は、タイトルを追加して設定のグループを定義するか、それらのグループを別の画面に表示することをお勧めします。 + +詳細については、次のセクションで説明します。</p> + + +<h3 id="Groups">設定グループを作成する</h3> + +<p>10 以上の設定のリストがある場合、ユーザーが目を通して把握し処理することが難しくなる場合があります。 +この問題を解決するには、設定の一部またはすべてをグループに分割し、1 つの長いリストを複数の短いリストに変えます。 + +関連設定のグループは、次の 2 つの方法のいずれかで表示できます。</p> + +<ul> + <li><a href="#Titles">タイトルを使用する</a></li> + <li><a href="#Subscreens">サブ画面を使用する</a></li> +</ul> + +<p>これらのグループ化方法の 1 つまたは両方を利用して、アプリの設定を整理できます。使用する方法と設定の分割方法を決定する際は、Android Design の<a href="{@docRoot}design/patterns/settings.html">Settings</a> ガイドのガイドラインに従ってください。 + +</p> + + +<h4 id="Titles">タイトルを使用する</h4> + +<p>設定のグループの間に見出しを入れる場合(図 2. 参照)、{@link android.preference.Preference} オブジェクトをグループごとに 1 つの {@link android.preference.PreferenceCategory} 内にセットしてください。 + +</p> + +<p>次に例を示します。</p> + +<pre> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <PreferenceCategory + android:title="@string/pref_sms_storage_title" + android:key="pref_key_storage_settings"> + <CheckBoxPreference + android:key="pref_key_auto_delete" + android:summary="@string/pref_summary_auto_delete" + android:title="@string/pref_title_auto_delete" + android:defaultValue="false"... /> + <Preference + android:key="pref_key_sms_delete_limit" + android:dependency="pref_key_auto_delete" + android:summary="@string/pref_summary_delete_limit" + android:title="@string/pref_title_sms_delete"... /> + <Preference + android:key="pref_key_mms_delete_limit" + android:dependency="pref_key_auto_delete" + android:summary="@string/pref_summary_delete_limit" + android:title="@string/pref_title_mms_delete" ... /> + </PreferenceCategory> + ... +</PreferenceScreen> +</pre> + + +<h4 id="Subscreens">サブ画面を使用する</h4> + +<p>設定のグループをサブ画面に配置する場合(図 3. 参照)、{@link android.preference.Preference} オブジェクトのグループを {@link android.preference.PreferenceScreen} 内にセットしてください。 + +</p> + +<img src="{@docRoot}images/ui/settings/settings-subscreen.png" alt="" /> +<p class="img-caption"><strong>図 3.</strong> 子画面を設定する。{@code <PreferenceScreen>} は、選択されると、ネストされた設定を表示するための個別のリストを開くアイテムを作成します。 + +</p> + +<p>次に例を示します。</p> + +<pre> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- opens a subscreen of settings --> + <PreferenceScreen + android:key="button_voicemail_category_key" + android:title="@string/voicemail" + android:persistent="false"> + <ListPreference + android:key="button_voicemail_provider_key" + android:title="@string/voicemail_provider" ... /> + <!-- opens another nested subscreen --> + <PreferenceScreen + android:key="button_voicemail_setting_key" + android:title="@string/voicemail_settings" + android:persistent="false"> + ... + </PreferenceScreen> + <RingtonePreference + android:key="button_voicemail_ringtone_key" + android:title="@string/voicemail_ringtone_title" + android:ringtoneType="notification" ... /> + ... + </PreferenceScreen> + ... +</PreferenceScreen> +</pre> + + +<h3 id="Intents">インテントを使用する</h3> + +<p>設定画面ではなく、ウェブページを表示するためのウェブブラウザなどの別のアクティビティを開くプリファレンス アイテムが必要になることもあります。 +ユーザーがプリファレンス アイテムを選択したときに {@link android.content.Intent} が呼び出されるようにするには、対応する {@code <Preference>} 要素の子として {@code <intent>} 要素を追加します。 + +</p> + +<p>たとえば、次の方法で、プリファレンス アイテムを使用してウェブページを開くことができます。</p> + +<pre> +<Preference android:title="@string/prefs_web_page" > + <intent android:action="android.intent.action.VIEW" + android:data="http://www.example.com" /> +</Preference> +</pre> + +<p>次の属性を使用して、明示的なインテントと黙示的なインテントの両方を作成できます。</p> + +<dl> + <dt>{@code android:action}</dt> + <dd>{@link android.content.Intent#setAction setAction()} メソッドで割り当てるアクション。 +</dd> + <dt>{@code android:data}</dt> + <dd>{@link android.content.Intent#setData setData()} メソッドで割り当てるデータ。</dd> + <dt>{@code android:mimeType}</dt> + <dd>{@link android.content.Intent#setType setType()} メソッドで割り当てる MIME タイプ。 +</dd> + <dt>{@code android:targetClass}</dt> + <dd>{@link android.content.Intent#setComponent setComponent()} メソッドでのコンポーネント名のクラス部分。 +</dd> + <dt>{@code android:targetPackage}</dt> + <dd>{@link android.content.Intent#setComponent setComponent()} メソッドでのコンポーネント名のパッケージ部分。 +</dd> +</dl> + + + +<h2 id="Activity">プリファレンス アクティビティを作成する</h2> + +<p>アクティビティに設定を表示するには、{@link android.preference.PreferenceActivity} クラスを継承します。 +このクラスは、{@link android.preference.Preference} オブジェクトの階層に基づいて設定のリストを表示する従来の {@link android.app.Activity} クラスを継承したものです。 + +{@link android.preference.PreferenceActivity} は、ユーザーが変更を行ったときに、各 {@link android.preference.Preference} に対応する設定を自動的に保存します。 + +</p> + +<p class="note"><strong>注:</strong> Android 3.0 以降向けにアプリケーションを開発する場合は、代わりに {@link android.preference.PreferenceFragment} を使用する必要があります。 +<a href="#Fragment">プリファレンス フラグメントの使用</a>についての詳細は、次のセグメントをご覧ください。 +</p> + +<p>注意する必要があるのは、{@link android.preference.PreferenceActivity#onCreate onCreate()} のコールバック時に、ビューのレイアウトをロードしてはならないことを忘れないでください。 +代わりに {@link android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} を呼び出し、XML ファイルで宣言済みのプリファレンスをアクティビティに追加する必要があります。 + +以下は、{@link android.preference.PreferenceActivity} を機能させるために最小限必要なコードです。 +</p> + +<pre> +public class SettingsActivity extends PreferenceActivity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.preferences); + } +} +</pre> + +<p>ユーザーがプリファレンスを変更するとすぐに、ユーザーの設定のチェックが必要なときに他のアプリケーション コンポーネントが読み取ることができるデフォルトの {@link android.content.SharedPreferences} ファイルにシステムによって変更が保存されるため、実際一部のアプリではこのコードで十分です。 + +ただし、多くのアプリでは、プリファレンスに発生する変化をリッスンするために、もう少し多くのコードが必要になります。{@link android.content.SharedPreferences} ファイルの変更のリッスンについての詳細は、<a href="#ReadingPrefs">プリファレンスの読み取り</a>についてのセクションをご覧ください。 + + +</p> + + + + +<h2 id="Fragment">プリファレンス フラグメントを使用する</h2> + +<p>Android 3.0(API レベル 11)以降向けに開発を行っている場合は、{@link android.preference.PreferenceFragment} を使用して {@link android.preference.Preference} オブジェクトのリストを表示する必要があります。 + +{@link android.preference.PreferenceFragment} はどのアクティビティにでも追加できます — {@link android.preference.PreferenceActivity} を使用する必要はありません。 +</p> + +<p>作成するアクティビティの種類にかかわらず、<a href="{@docRoot}guide/components/fragments.html">フラグメント</a>を使用すると、アクティビティを単体で使用する場合と比べて、柔軟なアーキテクチャを持つアプリケーションを作成できます。 + +そのため、可能な限り {@link android.preference.PreferenceActivity} ではなく、{@link android.preference.PreferenceFragment} を使用して設定の表示を管理することをお勧めします。 + +</p> + +<p>{@link android.preference.PreferenceFragment} の実装は、{@link android.preference.PreferenceFragment#onCreate onCreate()} メソッドを {@link android.preference.PreferenceFragment#addPreferencesFromResource addPreferencesFromResource()} を使用してプリファレンス ファイルをロードするように定義するだけと簡単です。 + + +次に例を示します。</p> + +<pre> +public static class SettingsFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.preferences); + } + ... +} +</pre> + +<p>他の {@link android.app.Fragment} と同様に、このフラグメントは {@link android.app.Activity} に追加できます。 +次に例を示します。</p> + +<pre> +public class SettingsActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Display the fragment as the main content. + getFragmentManager().beginTransaction() + .replace(android.R.id.content, new SettingsFragment()) + .commit(); + } +} +</pre> + +<p class="note"><strong>注:</strong> {@link android.preference.PreferenceFragment} は、独自の {@link android.content.Context} オブジェクトを持ちません。 +{@link android.content.Context} オブジェクトが必要な場合は、{@link android.app.Fragment#getActivity()} を呼び出すことができます。 +ただし、{@link android.app.Fragment#getActivity()} はフラグメントがアクティビティにアタッチされている場合にのみ呼び出すようにしてください。 +フラグメントがまだアタッチされていない場合や、ライフサイクルの終了時にデタッチされた場合は、{@link android.app.Fragment#getActivity()} は null を返します。 + +</p> + + +<h2 id="Defaults">デフォルト値を設定する</h2> + +<p>作成するプリファレンスは、多くの場合、アプリケーションにとって重要ないくつかの動作を定義します。そのため、ユーザーが最初にプリケーションを開いたときに、各 {@link android.preference.Preference} のデフォルト値で、関連する {@link android.content.SharedPreferences} ファイルを初期化する必要があります。 + + +</p> + +<p>まず、{@code android:defaultValue} 属性を使用して、XML ファイルの各 {@link android.preference.Preference} オブジェクトにデフォルト値を指定してください。 + +指定する値は、対応する {@link android.preference.Preference} オブジェクトで使用できるデータ型であればどのようなデータ型でもかまいません。 +次に例を示します。 +</p> + +<pre> +<!-- default value is a boolean --> +<CheckBoxPreference + android:defaultValue="true" + ... /> + +<!-- default value is a string --> +<ListPreference + android:defaultValue="@string/pref_syncConnectionTypes_default" + ... /> +</pre> + +<p>次に、アプリケーションのメイン アクティビティ、およびユーザーがアプリケーションを最初に開いたときに表示されるその他のアクティビティの {@link android.app.Activity#onCreate onCreate()} メソッドから、{@link android.preference.PreferenceManager#setDefaultValues setDefaultValues()} を呼び出します。 + + +</p> + +<pre> +PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false); +</pre> + +<p>{@link android.app.Activity#onCreate onCreate()} 時に、このメソッドを呼び出すと、アプリケーションがデフォルト設定で適切に初期化されます。アプリケーションには、動作(セルラー ネットワーク上でデータをダウンロードするかどうかなど)を決定するために、デフォルト設定を読み込むことが必要な場合があります。 + + +</p> + +<p>このメソッドは次の 3 つの引数を取ります。</p> +<ul> + <li>アプリケーションの {@link android.content.Context}。</li> + <li>デフォルト値を設定するプリファレンス XML ファイルのリソース ID。</li> + <li>デフォルト値を複数回設定すべきかどうかを示すブール値。 +<p><code>false</code> の場合、デフォルト値は過去にこのメソッドが 1 度も呼ばれたことがない場合(または、デフォルト値の共有プリファレンス ファイルの{@link android.preference.PreferenceManager#KEY_HAS_SET_DEFAULT_VALUES} が false の場合)のみ設定されます。 + +</p></li> +</ul> + +<p>この 3 番目の引数を <code>false</code> に設定している限り、アクティビティが開始するたびに、ユーザーが保存したプリファレンスをデフォルト値にリセットして上書きすることなく、安全にこのメソッドを呼び出すことができます。 + +この引数を <code>true</code> に設定した場合は、以前の値がすべてデフォルト値で上書きされます。 +</p> + + + +<h2 id="PreferenceHeaders">プリファレンス ヘッダーを使用する</h2> + +<p>まれに、最初の画面が<a href="#Subscreens">サブ画面</a>のリストのみを表示するように設定を設計した方がよい場合もあります(図 4. と図. 5 のシステム設定アプリなど)。 + +このような設計を Android 3.0 以降で開発する場合、ネストした {@link android.preference.PreferenceScreen} 要素でサブ画面を作成するのではなく、Android 3.0 の新しい「ヘッダー」機能を使用する必要があります。 + +</p> + +<p>ヘッダーを使用して設定を作成するには、次の準備が必要です。</p> +<ol> + <li>設定をグループごとに {@link android.preference.PreferenceFragment} の別々のインスタンスに分けます。 +この場合、設定のグループごとに、個別の XML ファイルが必要になります。 +</li> + <li>各設定グループをリストアップし対応する設定のリストを含むのがどのフラグメントかを宣言する XML ヘッダー ファイルを作成します。 +</li> + <li>{@link android.preference.PreferenceActivity} クラスを継承し、設定をホストします。</li> + <li>{@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} コールバックを実装して、ヘッダー ファイルを指定します。 + +</li> +</ol> + +<p>この設計を使用する大きなメリットは、大きな画面で実行する場合に、{@link android.preference.PreferenceActivity} によって自動的に図. 4 の 2 ペイン レイアウトで表示されることです。 +</p> + +<p>アプリケーションが 3.0 より前のバージョンの Android をサポートしている場合でも、3.0 より前の端末で従来の多画面階層をサポートしながら、{@link android.preference.PreferenceFragment} を使用して 3.0 以降の端末で 2 ペイン表示を行うことができます(詳細については、<a href="#BackCompatHeaders">旧バージョンでのプリファレンス ヘッダーのサポート</a>についてのセクションをご覧ください)。 + + + +</p> + +<img src="{@docRoot}images/ui/settings/settings-headers-tablet.png" alt="" /> +<p class="img-caption"><strong>図 4.</strong>ヘッダー付きの 2 ペイン レイアウト。 <br/><b>1.</b>ヘッダーは、XML ヘッダー ファイルで定義します。 + <br/><b>2.</b>設定の各グループは、XML ヘッダー ファイルの {@code <header>} 要素で指定された {@link android.preference.PreferenceFragment} ファイルで定義します。 + +</p> + +<img src="{@docRoot}images/ui/settings/settings-headers-handset.png" alt="" /> +<p class="img-caption"><strong>図 5.</strong> ヘッダーが設定されたモバイル端末。アイテムが選択されると、対応する {@link android.preference.PreferenceFragment} がヘッダーを置き換えます。 + +</p> + + +<h3 id="CreateHeaders" style="clear:left">ヘッダー ファイルを作成する</h3> + +<p>ヘッダーのリストの設定の各グループは、ルート {@code <preference-headers>} 要素内の単独の {@code <header>} 要素によって指定されます。 +次に例を示します。</p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> + <header + android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne" + android:title="@string/prefs_category_one" + android:summary="@string/prefs_summ_category_one" /> + <header + android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo" + android:title="@string/prefs_category_two" + android:summary="@string/prefs_summ_category_two" > + <!-- key/value pairs can be included as arguments for the fragment. --> + <extra android:name="someKey" android:value="someHeaderValue" /> + </header> +</preference-headers> +</pre> + +<p>{@code android:fragment} 属性を使用して、各ヘッダーは、ユーザーがヘッダーを選択したときに開く {@link android.preference.PreferenceFragment} のインスタンスを宣言します。 +</p> + +<p>{@code <extras>} 要素を使用すると、キーと値のペアを {@link android.os.Bundle} のフラグメントに渡すことができます。 +{@link android.app.Fragment#getArguments()} を呼び出すことで、フラグメントは引数を取得できます。 +さまざまな理由でフラグメントに引数を渡す場合がありますが、各グループの {@link android.preference.PreferenceFragment} の同じサブクラスを再利用し、引数を使用してフラグメントがロードするプリファレンス XML ファイルを指定することは、効果的な引数の使い方の 1 つです。 + + +</p> + +<p>たとえば、次のフラグメントは、各ヘッダーが {@code "settings"} キーを使用して {@code <extra>} 引数を定義している場合、複数の設定グループで再利用できます。 +</p> + +<pre> +public static class SettingsFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + String settings = getArguments().getString("settings"); + if ("notifications".equals(settings)) { + addPreferencesFromResource(R.xml.settings_wifi); + } else if ("sync".equals(settings)) { + addPreferencesFromResource(R.xml.settings_sync); + } + } +} +</pre> + + + +<h3 id="DisplayHeaders">ヘッダーを表示する</h3> + +<p>プリファレンス ヘッダーを表示するには、{@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} コールバックメソッドを実装し、{@link android.preference.PreferenceActivity#loadHeadersFromResource loadHeadersFromResource()} を呼び出す必要があります。 + + +次に例を示します。</p> + +<pre> +public class SettingsActivity extends PreferenceActivity { + @Override + public void onBuildHeaders(List<Header> target) { + loadHeadersFromResource(R.xml.preference_headers, target); + } +} +</pre> + +<p>ユーザーがヘッダーのリストからアイテムを選択した場合、システムが対応する {@link android.preference.PreferenceFragment} を開きます。 +</p> + +<p class="note"><strong>注:</strong> プリファレンス ヘッダーを使用する場合、アクティビティで必要なタスクはヘッダーのロードのみであるため、{@link android.preference.PreferenceActivity} のサブクラスが {@link android.preference.PreferenceActivity#onCreate onCreate()} メソッドを実装する必要はありません。 + + +</p> + + +<h3 id="BackCompatHeaders">旧バージョンでプリファレンス ヘッダーをサポートする</h3> + +<p>アプリケーションが Android 3.0 よりも前のバージョンをサポートしている場合でも、3.0 以降で実行するときに、ヘッダーを使用して 2 ペイン レイアウトを提供できます。 +必要なことは、3.0 よりも前のバージョンの Android で使用するために、ヘッダー アイテムのように動作する基本的な {@link android.preference.Preference <Preference>} 要素を使用する追加のプリファレンス XML ファイルを作成することだけです。 + + +</p> + +<p>新しい {@link android.preference.PreferenceScreen} を開く代わりに、各 {@link android.preference.Preference <Preference>} 要素が、ロードするプリファレンス XML ファイルが指定されている {@link android.preference.PreferenceActivity} に {@link android.content.Intent} を送ります。 + + +</p> + +<p>たとえば、以下は Android 3.0 以降で使用されるプリファレンス ヘッダーの XML ファイル({@code res/xml/preference_headers.xml})です。 +</p> + +<pre> +<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> + <header + android:fragment="com.example.prefs.SettingsFragmentOne" + android:title="@string/prefs_category_one" + android:summary="@string/prefs_summ_category_one" /> + <header + android:fragment="com.example.prefs.SettingsFragmentTwo" + android:title="@string/prefs_category_two" + android:summary="@string/prefs_summ_category_two" /> +</preference-headers> +</pre> + +<p>また、以下は Android 3.0 よりも前のバージョンに同じヘッダーを提供するプリファレンス ファイル({@code res/xml/preference_headers_legacy.xml})です。 +</p> + +<pre> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <Preference + android:title="@string/prefs_category_one" + android:summary="@string/prefs_summ_category_one" > + <intent + android:targetPackage="com.example.prefs" + android:targetClass="com.example.prefs.SettingsActivity" + android:action="com.example.prefs.PREFS_ONE" /> + </Preference> + <Preference + android:title="@string/prefs_category_two" + android:summary="@string/prefs_summ_category_two" > + <intent + android:targetPackage="com.example.prefs" + android:targetClass="com.example.prefs.SettingsActivity" + android:action="com.example.prefs.PREFS_TWO" /> + </Preference> +</PreferenceScreen> +</pre> + +<p>{@code <preference-headers>} のサポートは Android 3.0 で追加されたため、Android 3.0 以降で実行されている場合のみ、システムは {@link android.preference.PreferenceActivity} の {@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} を呼び出します。 + +「レガシー」ヘッダー ファイル({@code preference_headers_legacy.xml})をロードするには、Android のバージョンを確認し、Android 3.0({@link android.os.Build.VERSION_CODES#HONEYCOMB})よりも前のバージョンの場合、{@link android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} を呼び出す必要があります。 + + + + +次に例を示します。</p> + +<pre> +@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ... + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + // Load the legacy preferences headers + addPreferencesFromResource(R.xml.preference_headers_legacy); + } +} + +// Called only on Honeycomb and later +@Override +public void onBuildHeaders(List<Header> target) { + loadHeadersFromResource(R.xml.preference_headers, target); +} +</pre> + +<p>残りの手順は、アクティビティに渡される {@link android.content.Intent} を処理して、ロードするプリファレンス ファイルを指定するだけです。 +それには、インテントのアクションを取得し、プリファレンス XML の {@code <intent>} タグで使用した既知のアクション文字列と比較します。 +</p> + +<pre> +final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE"; +... + +@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + String action = getIntent().getAction(); + if (action != null && action.equals(ACTION_PREFS_ONE)) { + addPreferencesFromResource(R.xml.preferences); + } + ... + + else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + // Load the legacy preferences headers + addPreferencesFromResource(R.xml.preference_headers_legacy); + } +} +</pre> + +<p>{@link android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} の連続呼び出しは、すべてのプリファレンスを 1 つのリストにスタックすることに注意してください。そのため、else if ステートメントを使用して条件を適切に記述して、1 度のみ呼び出されるようにしてください。 + + +</p> + + + + + +<h2 id="ReadingPrefs">プリファレンスを読み込む</h2> + +<p>デフォルトでは、アプリのプリファレンスは、静的メソッド {@link android.preference.PreferenceManager#getDefaultSharedPreferences PreferenceManager.getDefaultSharedPreferences()} を呼び出すとアプリケーション内のどこからでもアクセス可能なファイルに保存されます。 + + +このメソッドは、{@link android.preference.PreferenceActivity} で使用される {@link android.preference.Preference} オブジェクトに関連するすべてのキーと値のペアを含む {@link android.content.SharedPreferences} を返します。 + + +</p> + +<p>たとえば、次の方法で、アプリケーションのその他のアクティビティからプリファレンスの値の 1 つを読み込むことができます。 +</p> + +<pre> +SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); +String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, ""); +</pre> + + + +<h3 id="Listening">プリファレンスの変化をリッスンする</h3> + +<p>さまざまな理由で、ユーザーがプリファレンスを変更してすぐに通知を受け取ることが必要になることがあります。 +プリファレンスの 1 つに変化が発生したときにコールバックを受け取るには、 {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener SharedPreference.OnSharedPreferenceChangeListener} インターフェースを実装し、{@link android.content.SharedPreferences#registerOnSharedPreferenceChangeListener registerOnSharedPreferenceChangeListener()} を呼び出して {@link android.content.SharedPreferences} オブジェクトにリスナを登録します。 + + + + +</p> + +<p>このインターフェースには、コールバック メソッドが {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged onSharedPreferenceChanged()} 1 つのみしか含まれておらず、アクティビティの一部として簡単に実装できます。 + + +次に例を示します。</p> + +<pre> +public class SettingsActivity extends PreferenceActivity + implements OnSharedPreferenceChangeListener { + public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType"; + ... + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (key.equals(KEY_PREF_SYNC_CONN)) { + Preference connectionPref = findPreference(key); + // Set summary to be the user-description for the selected value + connectionPref.setSummary(sharedPreferences.getString(key, "")); + } + } +} +</pre> + +<p>この例では、メソッドが、変更された設定が、既知のプリファレンス キーの設定かどうかチェックしています。メソッドは {@link android.preference.PreferenceActivity#findPreference findPreference()} を呼び出して、変更された {@link android.preference.Preference} オブジェクトを取得しています。これにより、メソッドは、ユーザー選択の説明として表示されるアイテムの概要を変更できます。 + + +つまり、その設定が {@link android.preference.ListPreference} またはその他の複数選択可の設定の場合、設定が変更されたときに {@link android.preference.Preference#setSummary setSummary()} を呼び出して現在のステータス(図 5. のスリープ設定など)を表示する必要があります。 + + +</p> + +<p class="note"><strong>注:</strong> Android Design の <a href="{@docRoot}design/patterns/settings.html">Settings</a> に説明されているように、ユーザーがプリファレンスを変更するごとに、{@link android.preference.ListPreference} の概要を更新して最新の設定を表示することをお勧めします。 + +</p> + +<p>アクティビティでの適切なライフサイクル管理のために、{@link android.app.Activity#onResume} と {@link android.app.Activity#onPause} のそれぞれのコールバック時に、{@link android.content.SharedPreferences.OnSharedPreferenceChangeListener} の登録と登録解除を行うことをお勧めします。 + +</p> + +<pre> +@Override +protected void onResume() { + super.onResume(); + getPreferenceScreen().getSharedPreferences() + .registerOnSharedPreferenceChangeListener(this); +} + +@Override +protected void onPause() { + super.onPause(); + getPreferenceScreen().getSharedPreferences() + .unregisterOnSharedPreferenceChangeListener(this); +} +</pre> + +<p class="caution"><strong>警告:</strong> {@link android.content.SharedPreferences#registerOnSharedPreferenceChangeListener registerOnSharedPreferenceChangeListener()} を呼び出す場合、現時点では、プリファレンス マネージャーにはリスナへの強い参照を格納できません。 + + +リスナへの強い参照を格納しない場合は、リスナがガベージ コレクションの影響を受けやすくなります。 +リスナが必要な間存在し続けるオブジェクトのインスタンス データ内に、リスナへの参照を保持することをお勧めします。 + +</p> + +<p>たとえば、以下のコードでは、呼び出し元は、リスナへの参照を保持していません。 +結果として、リスナはガベージ コレクションの影響を受けることになり、その後のいずれかの時点でエラーになります。 +</p> + +<pre> +prefs.registerOnSharedPreferenceChangeListener( + // Bad! The listener is subject to garbage collection! + new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + // listener implementation + } +}); +</pre> + +<p>そのため、リスナが必要な間存在し続けるオブジェクトのインスタンス データ フィールドに、リスナへの参照を格納してください。 +</p> + +<pre> +SharedPreferences.OnSharedPreferenceChangeListener listener = + new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + // listener implementation + } +}; +prefs.registerOnSharedPreferenceChangeListener(listener); +</pre> + +<h2 id="NetworkUsage">ネットワークの使用を管理する</h2> + + +<p>Android 4.0 以降では、フォアグラウンドとバックグラウンドでのアプリケーションのネットワーク データの使用量を、システムの設定アプリケーションでユーザーが確認できます。 +また、ユーザーは、個々のアプリのバックグラウンド データの使用を無効にできます。 +アプリのバックグラウンドからのデータへのアクセスをユーザーが無効にすることを防ぐには、データ接続を効率的に使用することと、アプリケーションの設定でアプリのデータの利用方法をユーザーが調整できるようにすることが必要です。 + +<p> + +<p>たとえば、データを同期する頻度や、Wi-Fi 上でのみアップロードやダウンロードを実行するようにするかどうか、ローミング時にデータを使用するかどうかなどを、ユーザーが設定できるようにすることができます。 +これらをユーザーが管理できる場合、システム設定に設定した限度にデータ使用量が近づいたときに、データへのアプリのアクセスをユーザーが無効にする可能性は減少します。ユーザーはアプリのアクセスを無効にする代わりに、アプリのデータの使用量を厳密に管理できます。 + + +</p> + +<p>アプリのデータ使用を管理するために {@link android.preference.PreferenceActivity} に必要なプリファレンスを追加したら、マニフェスト ファイルに {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} のインテント フィルタを追加する必要があります。 + +次に例を示します。</p> + +<pre> +<activity android:name="SettingsActivity" ... > + <intent-filter> + <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> +</activity> +</pre> + +<p>このインテント フィルタは、これがアプリケーションのデータ使用をコントロールしているアクティビティであるとシステムに示します。 +これにより、ユーザーがシステム設定アプリからアプリのデータ使用量を調べるときに、[<em>View application settings</em>] ボタンを使用できるようになります。このボタンを押すと、{@link android.preference.PreferenceActivity} が開始し、アプリのデータ使用量を調整できるようになります。 + + +</p> + + + + + + + +<h2 id="Custom">カスタム プリファレンスを作成する</h2> + +<p>Android フレームワークには、異なる設定タイプの UI を作成できるさまざまな {@link android.preference.Preference} サブクラスが含まれています。ただし、番号ピッカーや日付ピッカーなど、組み込みソリューションがない場合に必要な設定が存在する可能性もあります。 + + +このような場合、{@link android.preference.Preference} クラスまたは他のサブクラスの 1 つを継承して、カスタム プリファレンスを作成する必要があります。 +</p> + +<p>{@link android.preference.Preference} クラスを継承する場合、次のことが必要です。 +</p> + +<ul> + <li>ユーザーがその設定を選択したときに表示されるユーザー インターフェースを指定する。</li> + <li>適切なタイミングで設定の値を保存する。</li> + <li>{@link android.preference.Preference} が表示されるときに、現在の値(またはデフォルト値)で初期化する。 +</li> + <li>システムによってリクエストされた場合にデフォルト値を提供する。</li> + <li>{@link android.preference.Preference} が独自の UI(ダイアログなど)を提供している場合、状態を保存し復元してライフサイクルの変化を処理する(ユーザーが画面を回転させた場合など)。 +</li> +</ul> + +<p>以下の各セクションでは、上記の各事項を実現する方法を説明します。</p> + + + +<h3 id="CustomSelected">ユーザー インターフェースを指定する</h3> + + <p>{@link android.preference.Preference} クラスを直接継承する場合、{@link android.preference.Preference#onClick()} を実装して、ユーザーがアイテムを選択したときに発生するアクションを定義する必要があります。 + +ただし、大部分のカスタム設定では、手順が簡単な {@link android.preference.DialogPreference} を継承してダイアログを表示する方法が利用されています。 +{@link android.preference.DialogPreference} を継承する場合、クラス コンストラクタで {@link android.preference.DialogPreference#setDialogLayoutResource setDialogLayoutResourcs()} を呼び出してダイアログのレイアウトを指定する必要があります。 + + +</p> + + <p>たとえば、以下のカスタム {@link android.preference.DialogPreference} のコンストラクタでは、レイアウトを宣言しデフォルトのポジティブとネガティブのダイアログ ボタンのテキストを指定しています。 + +</p> + +<pre> +public class NumberPickerPreference extends DialogPreference { + public NumberPickerPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + setDialogLayoutResource(R.layout.numberpicker_dialog); + setPositiveButtonText(android.R.string.ok); + setNegativeButtonText(android.R.string.cancel); + + setDialogIcon(null); + } + ... +} +</pre> + + + +<h3 id="CustomSave">設定の値を保存する</h3> + +<p>設定の値が整数の場合、またはブール値を保存する{@link android.preference.Preference#persistBoolean persistBoolean()} の場合、{@link android.preference.Preference#persistInt persistInt()} など、{@link android.preference.Preference} クラスの {@code persist*()} メソッドのいずれかを呼び出すことで、設定の値をいつでも保存できます。 + + +</p> + +<p class="note"><strong>注:</strong> 各 {@link android.preference.Preference} には、1 つのデータ型のデータのみ保存できます。そのため、カスタム {@link android.preference.Preference} で使用されているデータ型に対応する {@code persist*()} メソッドを使用する必要があります。 + +</p> + +<p>設定をいつ保存したらよいかは、継承する {@link android.preference.Preference} クラスによって異なります。 +{@link android.preference.DialogPreference} を継承する場合、ポジティブな結果でダイアログが閉じられたとき(ユーザーが [OK] ボタンを選択したとき)のみ、値を保存する必要があります。 + +</p> + +<p>{@link android.preference.DialogPreference} が閉じられたときには、システムが {@link android.preference.DialogPreference#onDialogClosed onDialogClosed()} メソッドを呼び出します。 +このメソッドには、ユーザーの結果が「Positive」かどうかを指定するブール値の引数が含まれています — この値が <code>true</code> の場合はユーザーがポジティブ ボタンを選択しているということであり、新しい値を保存する必要があります。 + +次に例を示します。 +</p> + +<pre> +@Override +protected void onDialogClosed(boolean positiveResult) { + // When the user selects "OK", persist the new value + if (positiveResult) { + persistInt(mNewValue); + } +} +</pre> + +<p>この例では、<code>mNewValue</code> は、設定の現在の値を保持するクラスの 1 つです。 +{@link android.preference.Preference#persistInt persistInt()} を呼び出すと、値が {@link android.content.SharedPreferences} ファイルに保存されます(この {@link android.preference.Preference} の XML ファイルに指定されたキーを自動的に使用して保存されます)。 + +</p> + + +<h3 id="CustomInitialize">現在の値を初期化する</h3> + +<p>システムは {@link android.preference.Preference} を画面に追加すると、{@link android.preference.Preference#onSetInitialValue onSetInitialValue()} を呼び出し、その設定用に保存されている値がある場合は通知します。 + +保存されている値がない場合、この呼び出しによりデフォルト値が設定されます。 +</p> + +<p>この {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} メソッドは、ブール値の <code>restorePersistedValue</code> を、その設定用に値が保存済みかどうか示すために渡します。 + +<code>true</code> の場合、{@link android.preference.Preference} クラスの {@code getPersisted*()} メソッド(整数用の {@link android.preference.Preference#getPersistedInt getPersistedInt()} など)のいずれかを呼び出して保存されている値を取得する必要があります。 + + +通常は保存されている値を取得するのは、UI を更新して以前保存した値を反映させるためです。 + +</p> + +<p><code>restorePersistedValue</code> が <code>false</code> の場合、2 番目の引数で渡されたデフォルト値を使用する必要があります。 +</p> + +<pre> +@Override +protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) { + if (restorePersistedValue) { + // Restore existing state + mCurrentValue = this.getPersistedInt(DEFAULT_VALUE); + } else { + // Set default state from the XML attribute + mCurrentValue = (Integer) defaultValue; + persistInt(mCurrentValue); + } +} +</pre> + +<p>各 {@code getPersisted*()} メソッドは、値が保存されていない場合またはキーが存在しない場合に使用するデフォルト値を指定する引数を取ります。 +上記の例では、{@link android.preference.Preference#getPersistedInt getPersistedInt()} が保存されている値を返すことができない場合に備えて、ローカル定数がデフォルト値を指定するために使用されています。 + +</p> + +<p class="caution"><strong>警告:</strong> <code>defaultValue</code> は、<code>restorePersistedValue</code> が <code>true</code> の場合、常に null になるため、{@code getPersisted*()} メソッドでデフォルト値として使用<strong>できません</strong>。 + +</p> + + +<h3 id="CustomDefault">デフォルト値を提供する</h3> + +<p>{@link android.preference.Preference} クラスのインスタンスがデフォルト値を指定している場合({@code android:defaultValue} 属性を使用)、システムは、オブジェクトのインスタンスを作成するときに {@link android.preference.Preference#onGetDefaultValue onGetDefaultValue()} を呼び出してデフォルト値を取得します。 + + +システムでデフォルト値を {@link android.content.SharedPreferences} に保存するには、このメソッドを実装する必要があります。 + +次に例を示します。</p> + +<pre> +@Override +protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getInteger(index, DEFAULT_VALUE); +} +</pre> + +<p>このメソッドは、属性の配列と取得する必要がある {@code android:defaultValue} のインデックス位置を提供しており、これらはデフォルト値を保存するために必要な情報のすべてです。 +属性からデフォルト値を抽出するためにこのメソッドの実装が必要なのは、デフォルト値が定義されていないときのために属性のローカル デフォルト値を指定する必要があるためです。 + +</p> + + + +<h3 id="CustomSaveState">プリファレンスの状態を保存し復元する</h3> + +<p>レイアウトの {@link android.view.View} と同じく、{@link android.preference.Preference} サブクラスは、アクティビティやフラグメントが再開される場合(ユーザーが画面を回転させた場合など)に状態の保存と復元を担当します。 + +{@link android.preference.Preference} クラスの状態を適切に保存し復元するには、ライフサイクル コールバック メソッドの {@link android.preference.Preference#onSaveInstanceState onSaveInstanceState()} と {@link android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} を実装する必要があります。 + + + +</p> + +<p>{@link android.preference.Preference} の状態は、{@link android.os.Parcelable} インターフェースを実装するオブジェクトによって定義されます。 +Android フレームワークでは、このようなオブジェクトである{@link android.preference.Preference.BaseSavedState} クラスが状態オブジェクトを定義するための起点として提供されています。 + +</p> + +<p>{@link android.preference.Preference} クラスが状態を保存する方法を定義するには、{@link android.preference.Preference.BaseSavedState} クラスを継承する必要があります。 +いくつかのメソッドをオーバーライドして {@link android.preference.Preference.BaseSavedState#CREATOR} オブジェクトを定義してください。 + +</p> + +<p>大部分のアプリでは、次の実装をコピーして、{@link android.preference.Preference} サブクラスが整数以外のデータ型のデータを保存している場合は、{@code value} を処理している行を変更するだけで使用できます。 + +</p> + +<pre> +private static class SavedState extends BaseSavedState { + // Member that holds the setting's value + // Change this data type to match the type saved by your Preference + int value; + + public SavedState(Parcelable superState) { + super(superState); + } + + public SavedState(Parcel source) { + super(source); + // Get the current preference's value + value = source.readInt(); // Change this to read the appropriate data type + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + // Write the preference's value + dest.writeInt(value); // Change this to write the appropriate data type + } + + // Standard creator object using an instance of this class + public static final Parcelable.Creator<SavedState> CREATOR = + new Parcelable.Creator<SavedState>() { + + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; +} +</pre> + +<p>{@link android.preference.Preference.BaseSavedState} の上記の実装をアプリに追加(通常、{@link android.preference.Preference} サブクラスのサブクラスとして追加)するとともに、{@link android.preference.Preference} サブクラスの {@link android.preference.Preference#onSaveInstanceState onSaveInstanceState()} と {@link android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} を実装する必要があります。 + + + + +</p> + +<p>次に例を示します。</p> + +<pre> +@Override +protected Parcelable onSaveInstanceState() { + final Parcelable superState = super.onSaveInstanceState(); + // Check whether this Preference is persistent (continually saved) + if (isPersistent()) { + // No need to save instance state since it's persistent, + // use superclass state + return superState; + } + + // Create instance of custom BaseSavedState + final SavedState myState = new SavedState(superState); + // Set the state's value with the class member that holds current + // setting value + myState.value = mNewValue; + return myState; +} + +@Override +protected void onRestoreInstanceState(Parcelable state) { + // Check whether we saved the state in onSaveInstanceState + if (state == null || !state.getClass().equals(SavedState.class)) { + // Didn't save the state, so call superclass + super.onRestoreInstanceState(state); + return; + } + + // Cast state to custom BaseSavedState and pass to superclass + SavedState myState = (SavedState) state; + super.onRestoreInstanceState(myState.getSuperState()); + + // Set this Preference's widget to reflect the restored state + mNumberPicker.setValue(myState.value); +} +</pre> + diff --git a/docs/html-intl/intl/ja/guide/topics/ui/ui-events.jd b/docs/html-intl/intl/ja/guide/topics/ui/ui-events.jd new file mode 100644 index 000000000000..1cff3f62d022 --- /dev/null +++ b/docs/html-intl/intl/ja/guide/topics/ui/ui-events.jd @@ -0,0 +1,291 @@ +page.title=入力イベント +parent.title=ユーザー インターフェース +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>本書の内容</h2> + <ol> + <li><a href="#EventListeners">イベントリスナ</a></li> + <li><a href="#EventHandlers">イベント ハンドラ</a></li> + <li><a href="#TouchMode">タッチモード</a></li> + <li><a href="#HandlingFocus">フォーカスの処理</a></li> + </ol> + +</div> +</div> + +<p>Android では、アプリケーションでのユーザーの操作からイベントをインターセプトする方法が複数用意されていますが、ユーザー インターフェース内のイベントをインターセプトする場合は、ユーザーが操作する個々の View オブジェクトからイベントを取得することになります。 + +View クラスは、このための手段を提供しています。</p> + +<p>レイアウトを構成するために使用する各種の View クラスには、UI イベントの処理に役に立ついくつかのパブリック コールバック メソッドが含まれています。 +これらのパブリック コールバック メソッドは、オブジェクトで対応するアクションが発生したときに Android フレームワークによって呼び出されます。 +たとえば、ビュー(ボタンなど)がタップされたときには、そのオブジェクト上で <code>onTouchEvent()</code> メソッドが呼び出されます。 +このようなイベントをインターセプトするには、クラスを継承しメソッドをオーバーライドする必要があります。 +ただし、このようなイベントを処理するたびに View オブジェクトを継承することは、実用的とは言えません。 +そのため、View クラスには、簡単に定義できるコールバックを持つネストされたインターフェースのコレクションも含まれています。 +これらのインターフェースは、<a href="#EventListeners">イベントリスナ</a>と呼ばれ、UI へのユーザーの操作を取得するために使用されます。 +</p> + +<p>通常は、イベントリスナを使用して、ユーザーの操作をリッスンすることになりますが、カスタム コンポーネントを作成するために View クラスを継承する場合や、 +処理を工夫するために {@link android.widget.Button} クラスを継承することもできます。 + +その場合は、クラスの<a href="#EventHandlers">イベント ハンドラ</a>を使用して、クラスにデフォルトのイベント動作を定義できます。 +</p> + + +<h2 id="EventListeners">イベントリスナ</h2> + +<p>イベントリスナは、コールバック メソッド 1 つを含む {@link android.view.View} クラスのインターフェースです。 +以下のメソッドは、イベントリスナが登録されているビューが UI アイテムへのユーザーの操作によってトリガーされたときに、Android フレームワークによって呼び出されます。 +</p> + +<p>イベントリスナ インターフェースに含まれているのは、以下のコールバック メソッドです。</p> + +<dl> + <dt><code>onClick()</code></dt> + <dd>{@link android.view.View.OnClickListener} のメソッド。ユーザーがアイテムをタップしたとき(タッチモードの場合)、またはナビゲーション キーまたはトラックボールでアイテムにフォーカスを合わせ、適切な「エンター」キーまたはトラックボールを押したときに、呼び出されます。 + + +</dd> + <dt><code>onLongClick()</code></dt> + <dd>{@link android.view.View.OnLongClickListener} のメソッド。ユーザーがアイテムをタップしてホールドしたとき(タッチモードの場合)、またはナビゲーション キーまたはトラックボールでアイテムにフォーカスを合わせ、適切な「エンター」キーまたはトラックボールを長押し(1 秒間)したときに、呼び出されます。 + + +</dd> + <dt><code>onFocusChange()</code></dt> + <dd>{@link android.view.View.OnFocusChangeListener} のメソッド。ナビゲーション キーやトラックボールを使用してユーザーがアイテムに移動してきたときまたはアイテムから離れるときに、呼び出されます。 +</dd> + <dt><code>onKey()</code></dt> + <dd>{@link android.view.View.OnKeyListener} のメソッド。ユーザーがアイテムにフォーカスを合わせて端末のハードウェア キーを押したとき、または離したときに、呼び出されます。 +</dd> + <dt><code>onTouch()</code></dt> + <dd>{@link android.view.View.OnTouchListener} のメソッド。画面(アイテムの境界線内)での押す、離す、移動操作などのタップイベントと認定されるアクションをユーザーが実行した場合に呼び出されます。 + +</dd> + <dt><code>onCreateContextMenu()</code></dt> + <dd>{@link android.view.View.OnCreateContextMenuListener} のメソッド。コンテキスト メニュー(「長押しクリック」し続けると作成されます)の作成中に呼び出されます。 +コンテキスト メニューについての詳細は、「<a href="{@docRoot}guide/topics/ui/menus.html#context-menu">メニュー</a>」のデベロッパー ガイドをご覧ください。 + +</dd> +</dl> + +<p>これらのメソッドは、それぞれのインターフェースにおける唯一のメソッドです。これらのいずれかのメソッドを定義しイベントを処理するには、ネストされたインターフェースをアクティビティに実装するか、ネストされたインターフェースを匿名クラスとして定義します。次に、その実装のインスタンスを対応する <code>View.set...Listener()</code> メソッドに渡します。 + + +(例: <code>{@link android.view.View#setOnClickListener(View.OnClickListener) setOnClickListener()}</code> を呼び出し、{@link android.view.View.OnClickListener OnClickListener} の実装を渡します)。 + +</p> + +<p>次の例は、ボタンへの on-click リスナの登録方法を示しています。 </p> + +<pre> +// Create an anonymous implementation of OnClickListener +private OnClickListener mCorkyListener = new OnClickListener() { + public void onClick(View v) { + // do something when the button is clicked + } +}; + +protected void onCreate(Bundle savedValues) { + ... + // Capture our button from layout + Button button = (Button)findViewById(R.id.corky); + // Register the onClick listener with the implementation above + button.setOnClickListener(mCorkyListener); + ... +} +</pre> + +<p>OnClickListener をアクティビティの一部として実装すると、余分なクラスのロードとオブジェクトの割り当てを避けることができます。 +次に例を示します。</p> +<pre> +public class ExampleActivity extends Activity implements OnClickListener { + protected void onCreate(Bundle savedValues) { + ... + Button button = (Button)findViewById(R.id.corky); + button.setOnClickListener(this); + } + + // Implement the OnClickListener callback + public void onClick(View v) { + // do something when the button is clicked + } + ... +} +</pre> + +<p>上の例の <code>onClick()</code> コールバックには戻り値がありませんが、イベントリスナ メソッドの中には、ブール値を返すことが必要なものもあることに注意してください。 +ブール値が示す事柄はイベントによって異なります。 +以下はその例です。</p> +<ul> + <li><code>{@link android.view.View.OnLongClickListener#onLongClick(View) onLongClick()}</code> - イベントを消費済みでこれ以上イベントを引き継ぐべきでないかどうかを示すブール値を返します。 +つまり、イベントが処理済みでイベントの停止が必要なことを示す場合は、<em>true</em> を返します。イベントが未処理の場合や、他の on-click リスナへのイベントの引き継ぎが必要な場合は、<em>false</em> を返します。 + + +</li> + <li><code>{@link android.view.View.OnKeyListener#onKey(View,int,KeyEvent) onKey()}</code> - イベントを消費済みでこれ以上イベントを引き継ぐべきでないかどうかを示すブール値を返します。 + + つまり、イベントが処理済みでイベントの停止が必要なことを示す場合は、<em>true</em> を返します。イベントが未処理の場合や、他の on-key リスナへのイベントの引き継ぎが必要な場合は、<em>false</em> を返します。 + +</li> + <li><code>{@link android.view.View.OnTouchListener#onTouch(View,MotionEvent) onTouch()}</code> - リスナがイベントを消費しているかどうかを示すブール値を返します。 +ここで注意する必要があるのは、このイベントが相互にフォローし合う複数のアクションを含むことがあることです。 +ダウン アクション イベントが受け取られたときに <em>false</em> を返すと、そのイベントを消費しておらず、そのイベントから続けて発生するアクションに関心がないことを示すことになります。 + +そのため、指での操作などのそのイベント内のその他のアクションや操作の最後に発生する アップ アクション イベントで、呼び出されることはなくなります。 +</li> +</ul> + +<p>ハードウェア キー イベントは常に、その時点でフォーカスがあるビューに届けられることに注意してください。ハードウェア・キー・イベントは、ビュー階層の一番上から下に適切な対象に到達するまでディスパッチされます。 +ビュー(またはビューの子)にフォーカスがある場合、イベントが <code>{@link android.view.View#dispatchKeyEvent(KeyEvent) +dispatchKeyEvent()}</code> メソッドを介して伝わっていると判断できます。 +ビューを通じてキーイベントを取得する別の方法としては、<code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code> と <code>{@link android.app.Activity#onKeyUp(int,KeyEvent) onKeyUp()}</code> を使用してアクティビティ内のすべてのイベントを受け取る方法もあります。 + +</p> + +<p>また、アプリケーションのテキスト入力について検討する際は、多くの端末にソフトウェア入力メソッドしかないことに注意してください。 +ソフトウェア入力メソッドでは、キーの利用は必要ありません。音声入力や手書き入力などを利用できるものもあります。入力メソッドがキーボードに似たインターフェースを提供していたとしても、そのインターフェースは通常、<code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code> ファミリーのイベントをトリガー<strong>しません</strong>。 + +アプリケーションの使用をハードウェア キーボード付きの端末に限定するのではない限り、制御するために特定のキーを押すことが必要な UI は作成しないでください。 + +特に、ユーザーのリターンキー押下時に入力を検証するような処理は行わないようにし、代わりに {@link android.view.inputmethod.EditorInfo#IME_ACTION_DONE} などのアクションを使用して入力メソッドにアプリケーションが求める反応を伝えてください。そうすることで、入力メソッドが UI を意味のあるものにします。 + +ソフトウェア入力メソッドの動作を推測し、その推測に基づいて、書式設定済みのテキストをアプリケーションに提供することは避けてください。 +</p> + +<p class="note"><strong>注:</strong> Android では、まずイベント ハンドラが呼び出され、次にクラス定義から適切なデフォルト ハンドラが呼び出されます。 +そのため、これらのイベントリスナから <em>true</em> が返された場合、イベントの他のイベントリスナへの伝播は止まり、ビューのデフォルトのイベント ハンドラへのコールバックもブロックされます。 + +そのため、イベントを終了させたいことが確実な場合のみ、<em>true</em> を返すようにしてください。</p> + + +<h2 id="EventHandlers">イベント ハンドラ</h2> + +<p>ビューからカスタム コンポーネントを作成する場合、デフォルトのイベント ハンドラとして使用される複数のコールバック メソッドを定義できます。イベント ハンドリングに使用される次のような一般的なコールバックの一部については、詳細を<a href="{@docRoot}guide/topics/ui/custom-components.html">カスタム コンポーネント</a>についてのドキュメントでご覧いただけます。 + + + +</p> +<ul> + <li><code>{@link android.view.View#onKeyDown}</code> - 新しいキーイベントの発生時に呼び出されます。</li> + <li><code>{@link android.view.View#onKeyUp}</code> - キー アップ イベントの発生時に呼び出されます。</li> + <li><code>{@link android.view.View#onTrackballEvent}</code> - トラックボール モーション イベントの発生時に呼び出されます。</li> + <li><code>{@link android.view.View#onTouchEvent}</code> - タッチスクリーン モーション イベント発生時に呼び出されます。</li> + <li><code>{@link android.view.View#onFocusChanged}</code> - ビューがフォーカスを取得した場合または失った場合に呼び出されます。</li> +</ul> +<p>View クラスに含まれていないメソッドの中にも、イベントの処理の方法に直接関係するメソッドがいくつかあります。 +そのため、レイアウト内の複雑なイベントを管理する場合は、以下のメソッドの使用を検討してください。 +</p> +<ul> + <li><code>{@link android.app.Activity#dispatchTouchEvent(MotionEvent) + Activity.dispatchTouchEvent(MotionEvent)}</code> - {@link android.app.Activity} が、すべてのタップイベントをウィンドウにディスパッチされる前にインターセプトできるようにします。 +</li> + <li><code>{@link android.view.ViewGroup#onInterceptTouchEvent(MotionEvent) + ViewGroup.onInterceptTouchEvent(MotionEvent)}</code> - {@link android.view.ViewGroup} が、イベントが子ビューにディスパッチされたときにイベントを監視できるようにします。 +</li> + <li><code>{@link android.view.ViewParent#requestDisallowInterceptTouchEvent(boolean) + ViewParent.requestDisallowInterceptTouchEvent(boolean)}</code> - このメソッドを親ビュー上で呼び出すことで、<code>{@link + android.view.ViewGroup#onInterceptTouchEvent(MotionEvent)}</code> による親ビューのタップイベントのインターセプトを許可しないことを示すことができます。 +</li> +</ul> + +<h2 id="TouchMode">タッチモード</h2> +<p> +ユーザーが方向キーまたはトラックボールを使用してユーザー インターフェースを操作する場合、入力を受け付けるアイテムがどのアイテムなのかユーザーが知ることができるようにアクション可能なアイテム(ボタンなど)にフォーカスを与えることが必要になります。 + +ただし、端末にタッチ機能がある場合は、ユーザーはタップでインターフェースの操作を開始するため、アイテムをハイライトすることや、特定のビューにフォーカスを与えることは必要ではなくなりました。 + +そのため、「タッチモード」と名付けられた操作モードが存在します。 + +</p> +<p> +タッチ可能な端末では、ユーザーが画面をタップすると、端末がタッチモードになります。 +端末がタッチモードの場合、テキスト編集ウィジェットなどの {@link android.view.View#isFocusableInTouchMode} が true のビューのみがフォーカス可能であり、ボタンなどのタップ可能なその他のビューは、タップされたときにフォーカスされることはありません。それらのビューは、押されたときに、on-click リスナを起動します。 + + + +</p> +<p> +ユーザーが方向キーを押すか、またはトラックボールをスクロールすると、端末はタッチモードから抜け、ビューがフォーカスを取得します。 +これにより、ユーザーは、画面をタップすることなく、ユーザー インターフェースの操作を再開できます。 + +</p> +<p> +タッチモード状態は、システム全体(すべてのウィンドウとアクティビティ)で維持されます。端末が現在タッチモードかどうか確認するには、{@link android.view.View#isInTouchMode} を呼び出します。 + + +</p> + + +<h2 id="HandlingFocus">フォーカスの処理</h2> + +<p>フレームワークは、ユーザーに入力に応じて、通常のフォーカス移動を処理します。フレームワークが処理するフォーカス移動には、ビューが削除されたり非表示になったり、新しいビューが利用可能になったりしたことによるフォーカスの変化も含まれます。 + +ビューは、<code>{@link android.view.View#isFocusable()}</code> メソッドで、フォーカスが取得可能なことを示します。 +ビューのフォーカスの取得可否を変更するには、<code>{@link android.view.View#setFocusable(boolean) setFocusable()}</code> を呼び出します。 +タッチモードでは、<code>{@link android.view.View#isFocusableInTouchMode()}</code> でビューがフォーカスを取得可能かどうか確認できます。ビューのフォーカスの取得可否は、<code>{@link android.view.View#setFocusableInTouchMode(boolean) setFocusableInTouchMode()}</code> で変更できます。 + + +</p> + +<p>フォーカスの移動は、所定の方向で最も近くにあるアイテムを見つけるアルゴリズムに基づきますが、 +まれに、デフォルトのアルゴリズムが開発者の意図する動作と一致しない場合もあります。 +この場合、レイアウト ファイルの + +<var>nextFocusDown</var>、 <var>nextFocusLeft</var>、 <var>nextFocusRight</var>、 +<var>nextFocusUp</var> の各 XML 属性を明示的にオーバーライドできます。これらの属性のいずれかを、フォーカスの移動<em>元</em>のビューに追加します。 +フォーカスの移動<em>先</em>のビューの ID になる属性の値を定義します。 +次に例を示します。</p> +<pre> +<LinearLayout + android:orientation="vertical" + ... > + <Button android:id="@+id/top" + android:nextFocusUp="@+id/bottom" + ... /> + <Button android:id="@+id/bottom" + android:nextFocusDown="@+id/top" + ... /> +</LinearLayout> +</pre> + +<p>本来、上記の縦方向のレイアウトでは、1 番上のボタンから上に移動しようとしても、2 番目のボタンから下に移動しようしても、どこにもフォーカスが移動しないはずでしたが、上記の処理により、 +1 番上のボタンによって 1 番下のボタンが + <var>nextFocusUp</var> として定義され(逆の場合も同様)、フォーカスが、上から下と下から上に順番に移動するようになります。 +</p> + +<p>UI でビューをフォーカス可能にする場合は(従来は、ビューはフォーカス可能ではありません)、レイアウトの宣言で <code>android:focusable</code> XML 属性をビューに追加し、値を + + <var>true</var> に設定します。また、<code>android:focusableInTouchMode</code> を使用して、タッチモードのときにビューをフォーカス可能にすることもできます。 +</p> +<p>特定のビューへのフォーカスをリクエストするには、<code>{@link android.view.View#requestFocus()}</code> を呼び出します。</p> +<p>フォーカス イベントをリッスンするには(ビューがフォーカスを受け取ったときまたは失ったときに通知を受け取るには)、上記の<a href="#EventListeners">イベントリスナ</a>のセクションの説明に従って <code>{@link android.view.View.OnFocusChangeListener#onFocusChange(View,boolean) onFocusChange()}</code> を使用します。 + +</p> + + + +<!-- +<h2 is="EventCycle">Event Cycle</h2> + <p>The basic cycle of a View is as follows:</p> + <ol> + <li>An event comes in and is dispatched to the appropriate View. The View + handles the event and notifies any listeners.</li> + <li>If, in the course of processing the event, the View's bounds may need + to be changed, the View will call {@link android.view.View#requestLayout()}.</li> + <li>Similarly, if in the course of processing the event the View's appearance + may need to be changed, the View will call {@link android.view.View#invalidate()}.</li> + <li>If either {@link android.view.View#requestLayout()} or {@link android.view.View#invalidate()} were called, + the framework will take care of measuring, laying out, and drawing the tree + as appropriate.</li> + </ol> + + <p class="note"><strong>Note:</strong> The entire View tree is single threaded. You must always be on + the UI thread when calling any method on any View. + If you are doing work on other threads and want to update the state of a View + from that thread, you should use a {@link android.os.Handler}. + </p> +--> diff --git a/docs/html-intl/intl/ja/index.jd b/docs/html-intl/intl/ja/index.jd index a11136d55c2f..755ec6205bfe 100644 --- a/docs/html-intl/intl/ja/index.jd +++ b/docs/html-intl/intl/ja/index.jd @@ -5,43 +5,81 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body -<!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> -</div> --> -<section class="dac-hero-carousel"> +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> -<!-- <article class="dac-expand dac-hero dac-invert active" style="background-color: rgb(38, 50, 56);"> --> -<article class="dac-expand dac-hero dac-invert dac-darken mprev active" style="background-color: #75d1ff;"> -<a href="/preview/index.html"> +<section class="dac-expand dac-hero dac-invert" style="background-color:#455A64"> <div class="wrap" style="max-width:1100px;margin-top:0"> - <div class="cols dac-hero-content"> - <div class="col-8of16 col-push-6of16 dac-hero-figure mprev"> - </div> - <div class="col-8of16 col-pull-7of16"> - <div class="dac-hero-tag"></div> - - <h1 class="dac-hero-title" style="white-space:nowrap;">Android 6.0 Marshmallow</h1> - <p class="dac-hero-description">次期バージョンの Android に向けて準備しましょう。 - Nexus 5、6、9、Nexus Player でアプリをテストします。 </p> - - <a class="dac-hero-cta" href="{@docRoot}preview/index.html"> + <div class="col-7of16 col-push-9of16" style="padding-left:2em;"> + <a href="{@docRoot}preview/index.html"> + <h1 class="dac-hero-title">Android N Developer Preview</h1> + <p class="dac-hero-description"> + Get ready for the next version of Android! + <strong>Test your apps</strong> on Nexus and other devices. Support new system + behaviors to <strong>save power and memory</strong>. + Extend your apps with <strong>multi-window UI</strong>, + <strong>direct reply notifications</strong> and more. + </p> + <a class="dac-hero-cta" href="/preview/index.html"> <span class="dac-sprite dac-auto-chevron"></span> - スタートガイド - </a><br> - <a class="dac-hero-cta" href="{@docRoot}preview/support.html"> + Learn more + </a><!--<br> + <a class="dac-hero-cta" href="/preview/support.html"> <span class="dac-sprite dac-auto-chevron"></span> - Developer Preview 3 (final SDK)</a> - - </div> + Update to Developer Preview (final SDK) + </a><br>--> + </a> + </div> + <div class="col-9of16 col-pull-7of16 dac-hero-figure" style="margin-top:0em;padding-right:1.5em;"> + <a href="{@docRoot}preview/index.html"> + <img style="" class="dac-hero-image" src="/images/home/n-preview-hero.png" + srcset="/images/home/n-preview-hero.png 1x, + /images/home/n-preview-hero_2x.png 2x"> + </a> </div> </div> -</a> -</article></section> +</section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -51,17 +89,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="//www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html-intl/intl/ja/preview/api-overview.jd b/docs/html-intl/intl/ja/preview/api-overview.jd deleted file mode 100644 index 2c0816b54605..000000000000 --- a/docs/html-intl/intl/ja/preview/api-overview.jd +++ /dev/null @@ -1,521 +0,0 @@ -page.title=API の概要 -page.keywords=プレビュー,sdk,互換性 -page.tags=previewresources, androidm sdk.platform.apiLevel=22-mnc -page.image=images/cards/card-api-overview_16-9_2x.png -@jd:body - - - -<div id="qv-wrapper"> -<div id="qv"> - -<h2>本書の内容 - <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle"> - <span class="more">詳細を表示</span> - <span class="less" style="display:none">詳細を非表示</span></a></h2> - -<ol id="toc44" class="hide-nested"> - <li><a href="#app-linking">アプリのリンク機能</a></li> - <li><a href="#backup">アプリの自動バックアップ</a></li> - <li><a href="#authentication">認証</a> - <ol> - <li><a href="#fingerprint-authentication">指紋認証</a></li> - <li><a href="#confirm-credential">資格情報の確認</a></li> - </ol> - </li> - <li><a href="#direct-share">ダイレクト シェア</a></li> - <li><a href="#voice-interactions">音声インタラクション</a></li> - <li><a href="#assist">Assist API</a></li> - <li><a href="#notifications">通知</a></li> - <li><a href="#bluetooth-stylus">Bluetooth スタイラスのサポート</a></li> - <li><a href="#ble-scanning">Bluetooth Low Energy のスキャンの改善</a></li> - <li><a href="#hotspot">アクセス ポイント2.0 リリース 1 のサポート</a></li> - <li><a href="#4K-display">4K ディスプレイ モード</a></li> - <li><a href="#behavior-themeable-colorstatelists">テーマ化可能な ColorStateLists</a></li> - <li><a href="#audio">オーディオ機能</a></li> - <li><a href="#video">ビデオ機能</a></li> - <li><a href="#camera">カメラ機能</a> - <ol> - <li><a href="#flashlight">Flashlight API</a></li> - <li><a href="#reprocessing">カメラの再処理</a></li> - </ol> - </li> - <li><a href="#afw">Android for Work の機能</a></li> -</ol> - -<h2>API の変更点</h2> -<ol> -<li><a href="{@docRoot}preview/download.html">API レベル 22 から M Preview»</a> </li> -</ol> - -</div> -</div> - -<p>M Developer Preview では、ユーザーやアプリ開発者に Android プラットフォームの次期リリースの新機能をいち早く試していただくことができます。 - -このドキュメントでは、いくつかの注目すべき API の概要について説明します。</p> - -<p>M Developer Preview は、<strong>Developer の早期導入者</strong>と<strong>テスター</strong>を対象としています。 -是非 -<a href="{@docRoot}preview/setup-sdk.html">M Developer Preview を試して</a>フィードバックをご提供ください。あなたのご意見が、Android フレームワークの方向性を決定する上で貴重な情報になります。 - -</p> - -<p class="caution"><strong>注意:</strong> M Developer Preview を使用したアプリは、Google Play ストアには公開しないでください。 -</p> - -<p class="note"><strong>注</strong>: このドキュメントには、まだ <a href="{@docRoot}">developer.android.com</a> のリファレンス マテリアルにないクラスやメソッドが多数登場します。 -このドキュメントでは、API エレメントは {@code code style} 形式で記載されています(ハイパーリンクなし)。 -これらのエレメントに関する API ドキュメント(準備段階)については、<a href="{@docRoot}preview/download.html#docs">プレビューのリファレンス</a>をダウンロードしてください。 -</p> - -<h3>重要な動作の変更点</h3> - -<p>過去に Android にアプリを公開したことがある場合は、アプリがプラットフォームの変更による影響を受ける場合があります。 -</p> - -<p>詳細については、<a href="behavior-changes.html">Behavior Changes</a> をご覧ください。</p> - -<h2 id="app-linking">アプリのリンク機能</h2> -<p>このプレビューでは、アプリのリンク機能を強化することで Android のインテント システムが向上しました。この機能では、所有するウェブドメインにアプリを関連付けることができます。 -この関連付けに基づいて、プラットフォームが特定のウェブリンクの処理に使用するデフォルトのアプリを決めることができ、ユーザーにアプリを選択させる操作をスキップできます。この機能の実装方法については、 -<a href="{@docRoot}preview/features/app-linking.html">アプリのリンク機能</a>をご覧ください。 - - - -<h2 id="backup">アプリの自動バックアップ</h2> -<p>システムで、アプリの自動フルデータ バックアップと復元を実行できるようになりました。この動作は、M Preview を対象としたアプリでデフォルトで有効になっています。追加のコードは必要ありません。 -ユーザーが Google アカウントを削除すると、バックアップ データも削除されます。 -この機能の仕組みとファイル システムでバックアップ対象を設定する方法については、 -<a href="{@docRoot}preview/backup/index.html">アプリの自動バックアップ</a>をご覧ください。 -</p> - -<h2 id="authentication">認証</h2> -<p>このプレビューでは、サポートされる端末での指紋スキャンを使用したユーザー認証や、端末のロック解除メカニズム(ロック画面のパスワードなど)を使って最後にユーザーが認証された時期の確認などを行える新しい API が提供されます。 - -これらの API は、<a href="{@docRoot}training/articles/keystore.html">Android キーストローク システム</a>と共に使用します。 -</p> - -<h3 id="fingerprint-authentication">指紋認証</h3> - -<p>指紋スキャンでユーザーを認証するには、新しい -{@code android.hardware.fingerprint.FingerprintManager} クラスのインスタンスを取得して、 -{@code FingerprintManager.authenticate()} メソッドを呼び出します。アプリは、指紋センサー付きの、互換性のある端末上で実行している必要があります。 -指紋認証フローのユーザー インターフェースをアプリに実装し、UI には標準の Android 指紋アイコンを使用する必要があります。Android 指紋アイコン({@code c_fp_40px.png})は<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">サンプルアプリ</a>に含まれています。指紋認証を使用するアプリを複数開発する場合は、それぞれのアプリで個別にユーザーの指紋を認証する必要があります。 - - - - -</p> - -<p>アプリでこの機能を使用するには、まずマニフェストに {@code USE_FINGERPRINT} パーミッションを追加する必要があります。 -</p> - -<pre> -<uses-permission - android:name="android.permission.USE_FINGERPRINT" /> -</pre> - -<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" /> - -<p>アプリでの指紋認証の実装については、 -<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">指紋ダイアログのサンプル</a>をご覧ください。 -</p> - -<p>この機能をテストする場合は、次の手順を使用します。</p> -<ol> -<li>Android SDK Tools Revision 24.3 をインストールします(まだインストールしていない場合)。</li> -<li> -<strong>[設定] > [セキュリティ] > [指紋]</strong> の登録手順に従い、エミュレータに新しい指紋を登録します。</li> -<li>エミュレータを使って、次のコマンドで指紋のタッチ ベントをエミュレートします。 -同じコマンドを使って、ロック画面やアプリでの指紋のタッチイベントをエミュレートします。 - -<pre class="no-prettyprint"> -adb -e emu finger touch <finger_id> -</pre> -<p>Windows では、{@code telnet 127.0.0.1 <emulator-id>}、 -{@code finger touch <finger_id>} の順に実行する必要がある場合があります。 -</p> -</li> -</ol> - -<h3 id="confirm-credential">資格情報の確認</h3> -<p>アプリでは、ユーザーがいつ、最後に端末のロックを解除したかに基づいて、ユーザーを認証できます。この機能によって、ユーザーがアプリ固有のパスワードを覚えたり、開発者が独自の認証ユーザー インターフェースを実装したりする必要性がなくなります。 - -アプリでこの機能を使用する場合は、ユーザー認証用の公開鍵か秘密鍵を実装する必要があります。 -</p> - -<p>ユーザーが正常に認証された後、同じキーを再使用できるタイムアウト期間を設定するには、{@link javax.crypto.KeyGenerator} か -{@link java.security.KeyPairGenerator} のセットアップ後に新しい -{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()} メソッドを呼び出します。 - -現在、この機能は対象暗号化操作で動作します。 -</p> - -<p>再認証ダイアログを過度に表示しないようにします。アプリでは、まず暗号オブジェクトを使用し、タイムアウトした場合は -{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()} メソッドを使用してユーザーをアプリ内で再認証するようにします。 - - -</p> - -<p>アプリでのこの機能の実装については、 -<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">資格情報の確認サンプル</a>をご覧ください。 -</p> - -<h2 id="direct-share">ダイレクト シェア</h2> - -<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" /> - -<p>このプレビューでは、ユーザーが直感的にすばやく共有できるようにする API が提供されます。アプリで特定のアクティビティを起動する<em>ダイレクト シェアのターゲット</em>を定義すると、それらのダイレクト シェアのターゲットは <em>[共有]</em> メニューに表示されるようになります。 - -この機能を使うと、他のアプリ内にある連絡先などのターゲットにコンテンツを共有できます。 -たとえば、ダイレクト シェアのターゲットによって他のソーシャル ネットワーク アプリのアクティビティが起動し、そのアプリ内の特定の友人やコミュニティに直接コンテンツを共有できるようになります。 - -</p> - -<p>ダイレクト シェアのターゲットを有効にするには、まず -{@code android.service.} を拡張するクラスを定義する必要があります。 <br> -{@code chooser.ChooserTargetService} クラス。マニフェストで -{@code ChooserTargetService} を宣言します。その宣言内で、 -{@code BIND_CHOOSER_TARGET_SERVICE} パーミッションと、 -{@code SERVICE_INTERFACE} アクションを使ったインテント フィルタを指定します。</p> -<p>次の例は、マニフェストで {@code ChooserTargetService} を宣言する方法を示しています。 -</p> -<pre> -<service android:name=".ChooserTargetService" - android:label="@string/service_name" - android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE"> - <intent-filter> - <action android:name="android.service.chooser.ChooserTargetService" /> - </intent-filter> -</service> -</pre> - -<p>{@code ChooserTargetService} に公開するアクティビティごとに、 {@code "android.service.chooser.chooser_target_service"} という名前の -{@code <meta-data>} 要素をアプリのマニフェストに追加します。 - -</p> - -<pre> -<activity android:name=".MyShareActivity” - android:label="@string/share_activity_label"> - <intent-filter> - <action android:name="android.intent.action.SEND" /> - </intent-filter> -<meta-data - android:name="android.service.chooser.chooser_target_service" - android:value=".ChooserTargetService" /> -</activity> -</pre> - -<h2 id="voice-interactions">音声インタラクション</h2> -<p> -このプレビューでは、<a href="https://developers.google.com/voice-actions/" class="external-link">音声アクション</a>と共に使用することでアプリに対話形式の音声操作をビルドできる新しい音声インタラクション API が提供されます。 - - -{@code android.app.Activity.isVoiceInteraction()} メソッドを呼び出して、アクティビティが音声アクションへの応答として開始されたかどうかを確認します。 -音声アクションへの応答であった場合、アプリで -{@code android.app.VoiceInteractor} クラスを使用してユーザーに音声の確認や、オプションのリストからの選択などを要求できます。 -音声アクションの実装の詳細については、 -<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">音声アクションの開発者サイト</a>をご覧ください。 -</p> - -<h2 id="assist">Assist API</h2> -<p> -このプレビューでは、アシスタントを介してユーザーがアプリを操作できる新しい方法が用意されています。この機能を使用するには、ユーザーが現在のコンテキストを使うようアシスタントを有効にする必要があります。 -有効にすると、<strong>ホーム</strong> ボタンを長押しすることで、すべてのアプリ内でアシスタントを呼び出すことができます。 -</p> -<p> -{@link android.view.WindowManager.LayoutParams#FLAG_SECURE} フラグを設定すると、アプリが現在のコンテキストをアシスタントと共有しないようにできます。新しい {@code android.app.Activity.AssistContent} クラスを使用すると、プラットフォームがアシスタントに渡す標準的な情報セットの他に、アプリで追加の情報を共有できます。 - -</p> - -<p>アプリから追加のコンテキストをアシスタントに提供するには、次の手順を使用します。</p> - -<ol> -<li>{@link android.app.Application.OnProvideAssistDataListener} インターフェースを実装します。</li> -<li> -{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()} を使用してこのリスナーを登録します。</li> -<li>アクティビティ固有の文脈情報を提供するには、 -{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} コールバックと、任意で新しい -{@code Activity.onProvideAssistContent()} コールバックをオーバーライドします。 -</ol> - -<h2 id="notifications">通知</h2> -<p>このプレビューでは、通知に関して次のような API の変更点が追加されています。</p> -<ul> - <li>新しい<em>アラームのみの</em> Do not disturb モードに相当する新しい {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} フィルタレベル。 -</li> - <li>ユーザーが予定したリマインダを他のイベント({@link android.app.Notification#CATEGORY_EVENT})やアラーム({@link android.app.Notification#CATEGORY_ALARM})から区別する際に使用される新しい{@code Notification.CATEGORY_REMINDER} カテゴリの値。 - - -</li> - <li>{@code Notification.Builder.setSmallIcon(Icon)} メソッドや {@code Notification.Builder.setLargeIcon(Icon)} メソッド経由で通知にアタッチできる新しい {@code android.graphics.drawable.Icon} クラス。 - -</li> - <li>現在どの通知がアクティブなのかをアプリが検出できるようにする新しい {@code NotificationManager.getActiveNotifications()} メソッド。 -この機能を使用するアプリの実装については、<a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">アクティブな通知のサンプル</a>をご覧ください。 -</li> -</ul> - -<h2 id="bluetooth-stylus">Bluetooth スタイラスのサポート</h2> -<p>このプレビューでは、Bluetooth スタイラスを使用したユーザー入力のサポートが強化されました。互換性のある Bluetooth スタイラスと電話やタブレットをペアリングして接続できます。 -接続されている間、タッチスクリーンからの位置情報とスタイラスからの筆圧やボタン情報を合わせることで、タッチスクリーン単独の場合よりも表現の幅が大きく広がります。 - -新しい -{@code View.onStylusButtonPressListener} コールバックと {@code GestureDetector.OnStylusButtonPressListener} コールバックをアクティビティに登録すると、スタイラスのボタンが押されたことをアプリがリッスンし、次のアクションを実行できるようになります。 - -</p> - -<p>スタイラスのボタン操作を検出するには、{@link android.view.MotionEvent} メソッドと定数を使用します。 -</p> -<ul> -<li>ユーザーがスタイラスでアプリ画面のボタンをタップすると、 -{@link android.view.MotionEvent#getToolType(int) getTooltype()} メソッドが -{@link android.view.MotionEvent#TOOL_TYPE_STYLUS} を返します。</li> -<li>M Preview を対象としたアプリでは、ユーザーがプライマリのスタイラス ボタンを押すと -{@link android.view.MotionEvent#getButtonState() getButtonState()} メソッドが {@code MotionEvent.STYLUS_BUTTON_PRIMARY} を返します。 - -スタイラスにセカンダリ ボタンがある場合は、ユーザーがそのボタンを押したときに同じメソッドで {@code MotionEvent.STYLUS_BUTTON_SECONDARY} が返されます。 -ユーザーが同時に両方のボタンを押した場合は、両方の値が OR で返されます({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}) - -</li> -<li> -以前のプラットフォーム バージョンを対象としたアプリでは、 -{@link android.view.MotionEvent#getButtonState() getButtonState()} メソッドは -{@link android.view.MotionEvent#BUTTON_SECONDARY}(プライマリのスタイラス ボタンが押されたとき)、 -{@link android.view.MotionEvent#BUTTON_TERTIARY}(セカンダリのスタイラス ボタンが押されたとき)、または両方を返します。 -</li> -</ul> - -<h2 id="ble-scanning">Bluetooth Low Energy のスキャンの改善</h2> -<p> -アプリで Bluetooth Low Energy スキャンを実行する場合は、新しい -{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} メソッドを使って、設定された -{@link android.bluetooth.le.ScanFilter} に一致する宣伝パケットが最初に見つかったときと、それが長期間見つからない場合に通知する目的でのみコールバックが必要であると指定できます。 - -このスキャン アプローチは、以前のプラットフォーム バージョンで提供されていたものよりもはるかに効率的です。 - -</p> - -<h2 id="hotspot">アクセス ポイント 2.0 リリース 1 のサポート</h2> -<p> -このプレビューでは、Nexus 6 と Nexus 9 端末のアクセス ポイント2.0 Release 1 仕様のサポートが追加されました。アクセス ポイント 2.0 の資格情報をアプリに提供するには、 -{@code setPlmn()} や {@code setRealm()} などの -{@link android.net.wifi.WifiEnterpriseConfig} クラスの新しいメソッドを使用します。 -{@link android.net.wifi.WifiConfiguration} オブジェクトで、 -{@link android.net.wifi.WifiConfiguration#FQDN} フィールドと {@code providerFriendlyName} フィールドを設定できます。新しい {@code ScanResult.PasspointNetwork} プロパティは、検出されたネットワークがアクセス ポイント 2.0 のアクセス ポイントを表しているかどうかを示します。 - - -</p> - -<h2 id="4K-display">4K ディスプレイ モード</h2> -<p>互換性のあるハードウェアで、ディスプレイの解像度を 4K レンダリングにアップグレードするようアプリから要求できるようになりました。 -現在の物理的解像度を照会するには、新しい -{@code android.view.Display.Mode} API を使用します。UI が低い論理的解像度で描画されていて、より高い物理的解像度にアップスケールされた場合は、 -{@code Display.Mode.getPhysicalWidth()} メソッドが返す物理的解像度が {@link android.view.Display#getSize(android.graphics.Point) getSize()} で報告される論理的解像度と異なる場合があります。 - -</p> - -<p>アプリ ウィンドウの -{@code WindowManager.LayoutParams.preferredDisplayModeId} プロパティを設定することで、アプリの実行時に物理的解像度を変更するようシステムに要求できます。この機能は、4K ディスプレイの解像度に切り替えたい場合に便利です。 -4K ディスプレイ モード中、UI は引き続き元の解像度(1080p など)で表示され、4K にアップスケールされますが、 -{@link android.view.SurfaceView} オブジェクトではコンテンツをネイティブの解像度で表示する場合があります。 -</p> - -<h2 id="behavior-themeable-colorstatelists">テーマ化可能な ColorStateLists</h2> -<p>M Preview を実行する端末で、テーマの属性が -{@link android.content.res.ColorStateList} でサポートされるようになりました。 -{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} メソッドと -{@link android.content.res.Resources#getColor(int) getColor()} メソッドは廃止されました。これらの API を呼び出す場合は、代わりに新しい {@code Context.getColorStateList()} メソッドか -{@code Context.getColor()} メソッドを呼び出します。 -これらのメソッドは、{@link android.support.v4.content.ContextCompat} の v4 appcompat ライブラリにもあります。 -</p> - -<h2 id="audio">オーディオ機能</h2> - -<p>このプレビューでは、次のように Android でのオーディオ処理が改善されました。 </p> -<ul> - <li>新しい {@code android.media.midi} API を使った <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a> プロトコルのサポート。 -これらの API を使用して MIDI イベントを送受信できます。 -</li> - <li>デジタル オーディオの録音を作成して、それぞれのオブジェクトを再生し、システムのデフォルトをオーバーライドするオーディオ ソースとシンク プロパティを構成するための新しい {@code android.media.AudioRecord.Builder} クラスと {@code android.media.AudioTrack.Builder} クラス - -。</li> - <li>オーディオと入力端末を関連付ける API フック。これは、ユーザーが Android TV に接続されているゲーム コントローラーやリモート コントロールから音声検索を開始できるアプリの場合に特に便利です。ユーザーが検索を開始すると、システムが新しい -{@code android.app.Activity.onSearchRequested()} コールバックを呼び出します。 - -ユーザーの入力端末に組み込みのマイクがあるかどうかを確認するには、そのコールバックから {@link android.view.InputDevice} オブジェクトを取得して、新しい -{@code InputDevice.hasMic()} メソッドを呼び出します。 -</li> - <li>アタッチされたすべてのソースとシンク オーディオ端末の一覧を取得できる新しい {@code android.media.AudioDevicesManager} クラス。 -また、オーディオ端末の接続時と接続解除時にアプリで通知を受けたい場合は、 -{@code android.media.OnAudioDeviceConnectionListener} オブジェクトを指定することもできます。 -</li> -</ul> - -<h2 id="video">ビデオ機能</h2> -<p>このプレビューでは、ビデオ処理の API に次のような新機能が追加されました。</p> -<ul> -<li>アプリでオーディオ ストリームとビデオ ストリームを同調してレンダリングできる新しい {@code android.media.MediaSync}。 -オーディオ バッファはノンブロッキング方式で送信され、コールバック経由で返されます。 -ダイナミック再生レートもサポートしています。 -</li> -<li>アプリで開かれたセッションが、リソース マネージャーによって再要求されたことを示す新しい {@code MediaDrm.EVENT_SESSION_RECLAIMED} イベント。 -アプリが DRM セッションを使用する場合は、必ずこのイベントを処理し、再要求されたセッションは使用しないようにします。 - -</li> -<li>リソース マネージャーがコーデックで使用されたメディア リソースを再要求したことを示す新しい {@code MediaCodec.CodecException.ERROR_RECLAIMED} エラーコード。 -この例外では、コーデックはターミナル状態に移動するため、解放する必要があります。 - -</li> -<li>同時に発生できるコーデック インスタンスの最大数のヒントを得られる新しい {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} インターフェース。 - -</li> -<li>高速または低速モーション再生におけるメディアの再生レートを設定する新しい {@code MediaPlayer.setPlaybackParams()} メソッド。 -ビデオと共にオーディオの再生を自動的に延ばしたり早めたりもします。 -</li> -</ul> - -<h2 id="camera">カメラ機能</h2> -<p>このプレビューでは、カメラのフラッシュやカメラによる画像の再処理にアクセスするための新しい API が用意されています。 -</p> - -<h3 id="flashlight">Flashlight API</h3> -<p>カメラ端末にフラッシュ ユニットが付属している場合は、{@code CameraManager.setTorchMode()} メソッドを呼び出すことで、カメラ端末を開かずにフラッシュ ユニットのタッチモードのオン/オフを切り替えることができます。 -アプリには、フラッシュ ユニットやカメラ端末のフラッシュの独占所有権はありません。 -トーチモードは、カメラ端末が利用不可になったときや、トーチを付けている他のカメラリソースが利用不可になったときにオフになり、利用できなくなります。 - -他のアプリでも {@code setTorchMode()} を呼び出してトーチモードをオフにできます。 -最後にトーチモードをオンにしたアプリが閉じられると、トーチモードはオフになります。 -</p> - -<p> -{@code CameraManager.registerTorchCallback()} メソッドを呼び出すことで、トーチモードの状態に関する通知を受けるようコールバックを登録できます。コールバックを初めて登録したときに、現在検知されているすべてのフラッシュ ユニット付きのカメラ端末のトーチモードの状態が即座に呼び出されます。 - -トーチモードが正常にオン/オフされると、 -{@code CameraManager.TorchCallback.onTorchModeChanged()} メソッドが呼び出されます。</p> - -<h3 id="reprocessing">Reprocessing API</h3> -<p>{@link android.hardware.camera2 Camera2} API は、YUV とプライベートな不透明形式の画像の再処理をサポートするよう拡張されました。 -アプリは、再処理機能が利用可能かどうかを {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES} 経由で確認します。 -端末が再処理をサポートしている場合は、 -{@code CameraDevice.createReprocessableCaptureSession()} を呼び出して再処理可能なカメラ撮影セッションを作成し、入力バッファの再処理の要求を作成できます。 - -</p> - -<p>入力バッファのフローをカメラの再処理入力に接続するには、{@code ImageWriter} クラスを使用します。 -空のバッファを取得するには、次のプログラミング モデルを使用します。</p> - -<ol> -<li>{@code ImageWriter.dequeueInputImage()} メソッドを呼び出します。</li> -<li>入力バッファにデータを入力します。</li> -<li>{@code ImageWriter.queueInputImage()} メソッドを呼び出して、バッファをカメラに送ります。</li> -</ol> - -<p>{@code ImageWriter} オブジェクトを -{@code android.graphics.ImageFormat.PRIVATE} 画像と共に使用する場合、アプリから直接画像データにアクセスすることはできません。 -代わりに、{@code ImageWriter.queueInputImage()} メソッドをバッファコピーなしで呼び出して、{@code ImageFormat.PRIVATE} 画像を直接 -{@code ImageWriter} に渡します。 -</p> - -<p>{@code ImageReader} クラスで {@code android.graphics.ImageFormat.PRIVATE} 形式の画像ストリームがサポートされるようになりました。 -これにより、アプリが -{@code ImageReader} 出力画像の循環的な画像のキューを維持でき、1 つ以上の画像を選択して、それらをカメラの再処理用に -{@code ImageWriter} に送ることができます。</p> - -<h2 id="afw">Android for Work の機能</h2> -<p>このプレビューには、次のような Android for Work 用の新しい API が含まれています。</p> -<ul> - <li><strong>企業の専用端末の制御の強化:</strong>デバイス オーナーは次の設定を制御でき、企業の専用端末を管理しやすくなります。 - - - <ul> - <li> -{@code DevicePolicyManager.setKeyguardEnabledState()} メソッドを使ったキーガードの無効化と有効化。</li> - <li> -{@code DevicePolicyManager.setStatusBarEnabledState()} メソッドを使ったステータスバー(クイック設定、通知、Google Now を起動するスワイプアップのジェスチャ)の無効化と有効化。 -</li> - <li>{@link android.os.UserManager} の定数 {@code DISALLOW_SAFE_BOOT} を使ったセーフブートの無効化と有効化。 -</li> - <li> -{@link android.provider.Settings.Global} の定数 {@code STAY_ON_WHILE_PLUGGED_IN} を使った電源接続時の画面オフの回避。</li> - </ul> - </li> - <li><strong>デバイス オーナーによるアプリのサイレント インストールとアンインストール:</strong>デバイス オーナーでは、{@link android.content.pm.PackageInstaller} API を使って、Google Play for Work から独立してアプリケーションをサイレントにインストール、アンインストールできます。 - -デバイス オーナー経由で、ユーザー操作なしでアプリを取得したりインストールしたりできる端末を提供できます。 -この機能は、Google アカウントのアクティベートなしでキオスクや同様の端末のワンタッチ プロビジョニングを有効にする際に便利です。 -</li> -<li><strong>企業証明書のサイレント アクセス: </strong>ユーザーが証明書の選択を求められる前にアプリが -{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()} を呼び出すと、プロファイルやデバイス オーナーが {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()} メソッドを呼び出して要求元のアプリケーションにエイリアスをサイレントに提供できるようになりました。 - - -この機能によって、ユーザー操作なしでマネージド アプリが証明書にアクセスできるようになります。 -</li> -<li><strong>システムアップデートの自動受信。</strong> -{@code DevicePolicyManager.setSystemUpdatePolicy()} を使ってシステムアップデートのポリシーを設定することで、デバイス オーナーがキオスク端末などでシステムアップデートを自動的に受信できるようにしたり、ユーザーが操作しないようアップデートを最大 30 日間保留したりできます。 - -さらに、管理者はアップデートを実行する時間枠を、キオスク端末が使用されていない時間帯などに設定できます。 -利用可能なシステムアップデートがある場合、システムは Work Policy Controller アプリにシステムアップデートのポリシーがあるかどうかを確認し、それに基づいて動作します。 - - -</li> -<li> -<strong>代理証明書のインストール:</strong>プロファイルやデバイス オーナーで、サードパーティ アプリが次の {@link android.app.admin.DevicePolicyManager} 証明書の管理 API を呼び出す権限を付与できるようになりました。 - - -<ul> - <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName) -getInstalledCaCerts()}</li> - <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[]) -hasCaCertInstalled()}</li> - <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[]) -installCaCert()}</li> - <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[]) -uninstallCaCert()}</li> - <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName) -uninstallAllUserCaCerts()}</li> - <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String) -installKeyPair()}</li> -</ul> -</li> -<li><strong>企業のファクトリー リセット制限:</strong>デバイス オーナーをプロビジョニングする際、 -{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS} バンドルを設定して、ファクトリー リセット保護(FRP)をロック解除するようパラメータを構成できます。 -NFC プログラマー アプリでは、端末が FRP のロック解除するようリセットされ、端末がプロビジョニングされた後にこれらのパラメータを提供でき、事前に Google アカウントを設定しておく必要はありません。 - -これらのパラメータを修正しない場合、FRP は続行し、事前にアクティブ化された Google の資格情報なしで端末がアクティベートされないようにします。 - - -<p>さらに、Google Play サービスでアプリの制限を設定することで、デバイス オーナーは FRP のロック解除用の別の Google アカウントを指定して、端末でアクティベートされたアカウントを置き換えることができます。 -</p> -</li> -<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" /> -<li><strong>データ使用のトラッキング</strong>プロファイルやデバイス オーナーでは、新しい -{@code android.app.usage.NetworkStatsManager} メソッドを使用して、<strong>[設定] > [データ]</strong> に表示されるデータ使用の統計を照会できます。 -プロファイル オーナーには、管理するプロファイルのデータを照会するパーミッションが自動的に付与され、デバイス オーナーは管理されたプライマリ ユーザーの使用データへのアクセス権が付与されます。 - -</li> -<li><strong>実行時パーミッションの管理:</strong> -<p>プロファイルやデバイス オーナーは、 -{@code DevicePolicyManager.setPermissionPolicy()} を使用するすべてのアプリケーションのすべての実行時の要求に対するパーミッション ポリシーを設定でき、通常のとおりユーザーにパーミッションを付与するよう要求する、自動的に付与する、パーミッションをサイレントに拒否する、のいずれかを行うことができます。 - -後者のポリシーが設定されている場合、ユーザーはプロファイルやデバイス オーナーによって選択された内容を <strong>[設定]</strong> にあるアプリのパーミッション画面で修正できません。 - -</p></li> -<li><strong>設定の VPN:</strong>VPN アプリは、<strong>[設定] > [その他] > [VPN]</strong> に表示されます。さらに、VPN の使用に関する通知は、その VPN の構成状況によるものになります。 - - -プロファイル オーナーの場合、通知は VPN が マネージド プロファイル、個人プロファイル、または両方のどれに構成されているかによって、それ固有のものになります。 -デバイス オーナーの場合、通知は VPN が端末全体に構成されているかどうかによって、それ固有のものになります。 -</li> -<li><strong>ワーク ステータスの通知:</strong>マネージド プロファイルからのアプリのアクティビティがフォアグラウンドにある場合は、ステータスバーのブリーフケース アイコンが表示されます。 -さらに、端末がマネージド プロファイルのアプリのアクティビティに直接ロック解除されている場合、ユーザーがワーク プロファイル内にいることがトースト通知で表示されます。 - - -</li> -</ul> - -<p class="note"> - M Developer Preview のすべての API の変更点の詳細については、<a href="{@docRoot}preview/download.html">API Differences Report</a> をご覧ください。 -</p> diff --git a/docs/html-intl/intl/ja/preview/backup/index.jd b/docs/html-intl/intl/ja/preview/backup/index.jd deleted file mode 100644 index b558cdd0843c..000000000000 --- a/docs/html-intl/intl/ja/preview/backup/index.jd +++ /dev/null @@ -1,327 +0,0 @@ -page.title=アプリの自動バックアップ -page.tags=バックアップ, previewresources, androidm -page.keywords=バックアップ,自動バックアップ,プレビュー -page.image=images/cards/card-auto-backup_2x.png -@jd:body - -<div id="qv-wrapper"> - <div id="qv"> - <h2>本書の内容</h2> - <ol> - <li><a href="#overview">概要</a></li> - <li><a href="#configuring">データのバックアップを設定する</a></li> - <li><a href="#testing">バックアップ設定をテストする</a></li> - <li><a href="#issues">既知の問題</a></li> - </ol> - </div> -</div> - -<p> - アプリ内のデータ作成や環境設定は、多大な労力と時間を必要とする作業です。 -端末が破損したり、新しい端末にアップグレードしたりする場合に、そのデータを保持することが、快適な操作性を提供する上で非常に重要です。 -Android M Preview を実行する端末では、アプリデータを Google ドライブに自動的にバックアップすることで、前述のような状況でも快適な操作性を実現できます。 - -アプリデータは、ユーザーが端末を変更したりアップグレードしたりした場合に自動的に復元されます。 - -</p> - -<p> - 自動バックアップは、Android M Preview を実行する端末にインストールされているすべてのアプリで有効になっています。追加のアプリコードは必要ありません。 -ユーザーは、自動データ バックアップを使用しないよう選択することもできます。 -また、バックアップするアプリのデータを制限することもできます。 -</p> - -<p> - このドキュメントでは、新しいシステムの動作と、バックアップするアプリデータを指定する方法について説明します。 - -</p> - -<h2 id="overview">概要</h2> - -<p> - 自動バックアップ機能では、アプリがユーザーの端末上に作成するデータを、ユーザーの Google ドライブ アカウントにアップロードして暗号化することで、そのデータを保持します。 -開発者やユーザーにデータ ストレージの費用が発生することはなく、保存されたデータはユーザー個人のドライブ容量にはカウントされません。 -M Preview の期間中、ユーザーは 1 つの Android アプリにつき最大 25 MB までのデータを保存できます。 - -</p> - -<p> - 自動バックアップは、端末がアイドル中で、電源に接続されていて、Wi-Fi に接続されている場合に、24 時間ごとに実行されます。 -これらの条件を満たしたとき、バックアップ マネージャー サービスが利用可能なすべてのバックアップ データをクラウドにアップロードします。 -ユーザーが新しい端末に切り替えたり、バックアップされたアプリをアンインストールしたり再インストールしたりした場合、復元操作によりバックアップされたデータが新しくインストールされたアプリのデータ ディレクトリにコピーされます。 - - -</p> - -<p class="note"> - <strong>注:</strong> アプリが以前の <a href="{@docRoot}google/backup/index.html">Android バックアップ サービス</a>を利用している場合、この新しい動作は適用されず、既存のバックアップ動作が引き続き適用されます。 - - -</p> - - -<h3 id="auto-exclude">自動的に除外されたデータファイル</h3> - -<p> - 一時ファイルやキャッシュなど、バックアップする必要のないアプリデータもあるため、自動バックアップ サービスではデフォルトで一部のデータ ファイルを除外します。 - -</p> - -<ul> - <li>{@link android.content.Context#getCacheDir - getCacheDir()} メソッドと {@link android.content.ContextWrapper#getCodeCacheDir getCodeCacheDir()} - メソッドに参照されるディレクトリ内のファイル。 - </li> - - <li> -{@link android.content.Context#getExternalFilesDir getExternalFilesDir()} - メソッドに参照されるディレクトリ内のものを除く、外部ストレージ内のファイル。 - </li> - - <li> -{@link android.content.Context#getNoBackupFilesDir getNoBackupFilesDir()} メソッドに参照されるディレクトリ内のファイル。 - </li> -</ul> - -<h2 id="configuring">データのバックアップを設定する</h2> - -<p> - 前のセクションの自動除外ファイル一覧にあるものを除いて、M Preview 端末にインストールされたすべてのアプリで作成されるデータがバックアップ対象です。 -そこからさらに、アプリ マニフェストの設定を使用して、アプリからバックアップするデータを制限したり設定したりできます。 - -</p> - -<h3 id="include-exclude">対象データと除外データ</h3> - -<p> - アプリに必要なデータとその保存方法によって、特定のファイルやディレクトリを対象とするか、除外するかの明確なルールが必要になる場合があります。 -自動バックアップ サービスでは、XML 構成ファイルとアプリ マニフェストを使ってそのようなバックアップ ツールを設定できます。 - -アプリ マニフェストでは、次の例のように、バックアップ スキームの構成ファイルを指定できます。 - -</p> - -<pre> -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="com.my.appexample"> - <uses-sdk android:minSdkVersion="MNC"/> - <uses-sdk android:targetSdkVersion="MNC"/> - <app ... -<strong> android:fullBackupContent="@xml/mybackupscheme"></strong> - </app> - ... -</manifest> -</pre> - -<p> - このサンプル コードでは、<code>android:fullBackupContent</code> 属性がアプリの開発プロジェクトの <code>res/xml/</code> ディレクトリにある <code>mybackupscheme.xml</code> という名前の XML ファイルを指定しています。 - -この構成ファイルには、バックアップ対象とするファイルのルールが含まれています。 -次のサンプル コードは、バックアップから特定のファイルを除外する構成ファイルを示しています。 - -</p> - -<pre> -<?xml version="1.0" encoding="utf-8"?> -<full-backup-content> - <exclude domain="database" path="device_info.db"/> -</full-backup-content> -</pre> - -<p> - この例のバックアップ構成では、特定のデータベース ファイルのみをバックアップから除外しています。 - それ以外のファイルはすべてバックアップされます。 -</p> - -<h4>バックアップ設定の構文</h4> - -<p> - バックアップ サービスの設定では、バックアップに含める、または除外するファイルを指定できます。 -データ バックアップ設定の xml ファイルの構文は次のとおりです。 -</p> - -<pre> -<full-backup-content> - <include domain=["file" | "database" | "sharedpref" | "external" | "root"] path="string" /> - <exclude domain=["file" | "database" | "sharedpref" | "external" | "root"] path="string" /> -</full-backup-content> -</pre> - -<p> - 次のエレメントと属性を使って、バックアップに含める、または除外するファイルを指定できます。 - -</p> - -<ul> - <li> - <code><include></code>。システムにデフォルトでアプリのすべてのデータをバックアップさせるのではなく、バックアップするリソースを自身で指定する場合、このエレメントを使用します。 -<code><include></code> タグを指定すると、システムはこのエレメントで<em>指定されたリソースのみ</em>をバックアップします。 - - - </li> - - <li> - <code><exclude></code>。バックアップから除外するリソースを指定するには、このエレメントを使用します。 -システムは、このエレメントで指定されたリソース以外のすべてのアプリ データをバックアップします。 - - </li> - - <li> - <code>domain.</code> バックアップに含める、または除外するリソースのタイプ。この属性を指定する際に有効な値: - - </li> - - <li style="list-style: none"> - <ul> - <li> - <code>root</code>。リソースがアプリのルート ディレクトリにあることを指定します。 - </li> - - <li> - <code>file</code>。 -{@link android.content.Context#getFilesDir getFilesDir()} メソッドで返されるディレクトリ内のリソースに相当します。 - </li> - - <li> - <code>database</code>。 -{@link android.content.Context#getDatabasePath getDatabasePath()} メソッドや -{@link android.database.sqlite.SQLiteOpenHelper} クラスを使用して返されるデータベースに相当します。 - </li> - - <li> - <code>sharedpref</code>。 -{@link android.content.Context#getSharedPreferences getSharedPreferences()} メソッドで返される -{@link android.content.SharedPreferences} オブジェクトに相当します。 - </li> - - <li> - <code>external</code>。リソースが外部ストレージにあることを指定し、 -{@link android.content.Context#getExternalFilesDir getExternalFilesDir()} - メソッドで返されるディレクトリ内のファイルに相当します。 - </li> - - <li> - <code>path</code>。バックアップに含める、または除外するリソースへのファイルパス。 - - </li> - </ul> - </li> -</ul> - - -<h3 id="prohibit">データ バックアップの禁止</h3> - -<p> - マニフェストのアプリ エレメントにある <code>android:allowBackup</code> 属性を <code>false</code> に設定すると、一切のデータを自動バックアップしないように選択できます。 - -この設定を、次のサンプル コードで示します。 -</p> - -<pre> -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="com.my.appexample"> - <uses-sdk android:minSdkVersion="MNC"/> - <uses-sdk android:targetSdkVersion="MNC"/> - <app ... -<strong> android:allowBackup="false"></strong> - </app> - ... -</manifest> -</pre> - - -<h2 id="testing">バックアップ設定をテストする</h2> - -<p> - バックアップ設定を作成したら、アプリでデータが保存され、正常に復元されることをテストして確認する必要があります。 - -</p> - - -<h4>バックアップのログの有効化</h4> - -<p> - バックアップで XML ファイルがどのように解析されるかを確認するため、テストのバックアップを実行する前にログ機能を有効にします。 - -</p> - -<pre class="noprettyprint"> -$ adb shell setprop log.tag.BackupXmlParserLogging VERBOSE -</pre> - -<h4>バックアップのテスト</h4> - -<p>手動でバックアップを実行するには、まず次のコマンドを呼び出してバックアップ マネージャーを初期化する必要があります。 - -</p> - -<pre class="noprettyprint"> -$ adb shell bmgr run -</pre> - -<p> - 次に、次のコマンドを使って、アプリのパッケージ名を <code><PACKAGE></code> パラメータで指定して手動でアプリケーションをバックアップします。 - -</p> - -<pre class="noprettyprint"> -$ adb shell bmgr fullbackup <PACKAGE></pre> - - -<h4>復元のテスト</h4> - -<p> - アプリのバックアップ後に手動で復元を開始するには、アプリのパッケージ名を <code><PACKAGE></code> パラメータで指定します。 - -</p> - -<pre class="noprettyprint"> -$ adb shell bmgr restore <PACKAGE> -</pre> - -<p class="warning"> - <b>警告:</b> このアクションを実行すると、アプリが停止し、復元操作を実行する前にデータが消去されます。 - -</p> - -<p> - アプリをアンインストールしてから再インストールすることで、アプリの復元プロセスを開始します。アプリのインストールが完了すると、アプリデータが自動的にクラウドから復元されます。 - -</p> - - -<h4>バックアップのトラブルシューティング</h4> - -<p> - 問題が発生した場合は、<strong>[設定] > [バックアップ]</strong>でバックアップをオン/オフに切り替え、端末を工場出荷時の状態にリセットするか、次のコマンドを呼び出して、バックアップ データと関連メタデータを消去できます。 - - -</p> - -<pre>$ adb shell bmgr wipe <TRANSPORT> <PACKAGE></pre> - -<p> - <code><TRANSPORT></code> には、<code>com.google.android.gms</code> というプレフィクスが付く必要があります。 - Transport の一覧を取得するには、次のコマンドを呼び出します。 -</p> - -<pre>$ adb shell bmgr list transports</pre> - -<h2 id="issues">既知の問題</h2> - -<p>自動バックアップ サービスには、次のような既知の問題があります。</p> - -<ul> - <li><strong>Google Cloud Messaging</strong> - プッシュ通知に Google Cloud Messaging を使用するアプリの場合、Messaging の登録時に返された登録 ID をバックアップすると、復元されたアプリのプッシュ通知が破損することがあるという既知の問題があります。古い登録 ID がバックアップされている場合を除いて、新しい端末へのインストール後は、新しい 登録 ID 用の API を照会することが重要です。 - - - - -これを回避するには、バックアップ対象ファイルから登録 ID を除外します。 - - </li> -</ul> diff --git a/docs/html-intl/intl/ja/preview/behavior-changes.jd b/docs/html-intl/intl/ja/preview/behavior-changes.jd deleted file mode 100644 index a7950a1ad0d0..000000000000 --- a/docs/html-intl/intl/ja/preview/behavior-changes.jd +++ /dev/null @@ -1,402 +0,0 @@ -page.title=動作の変更点 -page.keywords=プレビュー,sdk,compatibility -sdk.platform.apiLevel=MNC -@jd:body - -<div id="qv-wrapper"> -<div id="qv"> - -<h2>本書の内容</h2> - -<ol id="toc44" class="hide-nested"> - <li><a href="#behavior-runtime-permissions">実行時パーミッション</a></li> - <li><a href="#behavior-power">省電力の最適化 </a> - <ol> - <li><a href="#behavior-doze">Doze</a></li> - <li><a href="#behavior-app-standby">App Standby</a></li> - </ol> - </li> - <li><a href="#behavior-adoptable-storage">追加可能なストレージ端末</a></li> - <li><a href="#behavior-apache-http-client">Apache HTTP Client の削除</a></li> - <li><a href="#behavior-audiomanager-Changes">AudioManager の変更点</a></li> - <li><a href="#behavior-test-selection">テキスト選択</a></li> - <li><a href="#behavior-keystore">Android キーストロークの変更点</a></li> - <li><a href="#behavior-network">Wi-Fi とネットワークの変更点</a></li> - <li><a href="#behavior-camera">カメラ サービスの変更点</a></li> - <li><a href="#behavior-art-runtime">ART ランタイム</a></li> - <li><a href="#behavior-apk-validation">APK の検証</a></li> - <li><a href="#behavior-afw">Android for Work の変更点</a></li> -</ol> - -<h2>API の変更点</h2> -<ol> -<li><a href="{@docRoot}preview/download.html">API レベル 22 から M Preview»</a> </li> -</ol> - - -<h2>関連ドキュメント</h2> -<ol> -<li><a href="{@docRoot}preview/api-overview.html">M Developer Preview API の概要</a> </li> -</ol> - -</div> -</div> - -<p>M Developer Preview には、新機能以外にもさまざまなシステムの変更点や API の動作の変更点が盛り込まれています。 -このドキュメントでは、アプリ開発において把握しておくべき主な変更点について説明します。 -</p> - -<p>過去に Android にアプリを公開したことがある場合は、アプリがこれらの変更による影響を受ける場合があることに注意してください。 -</p> - -<h2 id="behavior-runtime-permissions">実行時パーミッション</h1> -<p>このプレビューでは、アプリのパーミッションを実行時にユーザーが直接管理できる新しいパーミッション モデルが採用されました。 -このモデルによって、ユーザーに対するパーミッションの可視性と制御性が向上し、アプリ開発者にとってはアプリのインストールや自動アップデート プロセスの効率が上がります。ユーザーはインストール済みアプリのパーミッションを個別に付与したり取り消したりできます。 - - </p> - -<p>M Preview を対象としたアプリでは、必ずパーミッションを実行時に確認、要求するようにします。 -アプリにパーミッションが付与されているかどうかを確認するには、新しい {@code Context.checkSelfPermission()} メソッドを呼び出します。 -パーミッションを要求するには、新しい -{@code Activity.requestPermission()} メソッドを呼び出します。アプリが M を対象としていない場合でも、新しいパーミッション モデルでアプリをテストするようにしてください。 -</p> - -<p>アプリで新しいパーミッションをサポートする際の詳細については、Developer Preview ページの -<a href="{@docRoot}preview/features/runtime-permissions.html">Permissions</a> をご覧ください。 -アプリへの影響を評価する際のヒントについては、<a href="{@docRoot}preview/testing/guide.html#runtime-permissions">Testing Guide</a> をご覧ください。 -</p> - -<h2 id="behavior-power">省電力の最適化 </h2> -<p>このプレビューでは、アイドル中の端末やアプリに対する新しい省電力の最適化機能が採用されています。</p> - -<h3 id="behavior-doze">Doze</h3> -<p>端末が電源に接続されておらず、画面が一定時間オフ状態の場合は <em>Doze</em> モードに入り、システムをスリープ状態に保ちます。 -このモードでは、端末は定期的に通常の操作を短時間再開することで、アプリを同期したり、システムが保留中の操作を行ったりすることができます。 - -</p> - -<p>Doze 中は、アプリに次の制限が適用されます。</p> -<ul> -<li>アプリで優先度の高い Google Cloud Messaging の通知を受信する場合以外、ネットワーク アクセスは無効になります。 -</li> -<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Wake ロック</a> は無視されます。</li> -<li>{@link android.app.AlarmManager} クラスを使ってスケジュールされたアラームは無効になりますが、{@link android.app.AlarmManager#setAlarmClock setAlarmClock()} メソッドと {@code AlarmManager.setAndAllowWhileIdle()} を使って設定したアラームは除きます。 - -</li> -<li>WiFi スキャンは実行されません。</li> -<li>同期アダプタ と {@link android.app.job.JobScheduler} の同期とジョブは実行できません。 -</li> -</ul> -</p> -<p>端末が Doze モードでなくなると、保留中のすべての同期とジョブが実行されます。</p> -<p>この機能をテストするには、M Preview を実行する端末を開発マシンに接続して、次のコマンドを呼び出します。 - -</p> -<pre class="no-prettyprint"> -$ adb shell dumpsys battery unplug -$ adb shell dumpsys deviceidle step -$ adb shell dumpsys deviceidle -h -</pre> -<p class="note"><strong>注</strong>: -<a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud Messaging</a> の次期リリースでは、高優先度のメッセージを指定できます。 - -アプリが高優先度の GCM メッセージを受信する場合は、端末が Doze 中でも短時間のネットワーク アクセスが付与されます。 - -</p> - -<p>アプリで Doze をテストする方法のヒントについては、 -<a href="{@docRoot}preview/testing/guide.html#doze-standby">Testing Guide</a> をご覧ください。 - </p> - -<h3 id="behavior-app-standby">App Standby</h3> -<p>このプレビューでは、アクティブに使用されていないアプリをシステムがアイドル状態であるとみなす場合があります。 -システムが次の信号を検出しない場合、一定時間の経過後にアプリはアイドル状態であるとみなされます。 -</p> - -<ul> -<li>アプリがユーザーによって明示的に起動された。</li> -<li>アプリのプロセスが現在フォアグラウンドにある(アクティビティかフォアグラウンド サービスとしてか、他のアクティビティかフォアグラウンド サービスによって使用されている)。 -</li> -<li>アプリがロック画面や通知トレイに表示される通知を生成する。 -</li> -<li>ユーザーが、アプリに最適化が適用されないよう <strong>[設定]</strong> で明示的に指定する。 -</li> -</ul> - -<p>端末が電源に接続されていない場合、アイドル中のみなされたアプリのネットワーク アクセスは無効になり、同期とジョブは保留されます。 -端末が電源に接続されると、アプリのネットワーク アクセスは許可され、保留中のすべてのジョブと同期が実行されます。 -端末が長時間アイドル状態の場合、アイドル中のアプリは 1 日 1 回程度ネットワーク アクセスが許可されます。 -</p> - -<p>この機能をテストするには、M Preview を実行する端末を開発マシンに接続して、次のコマンドを呼び出します。 - -</p> -<pre class="no-prettyprint"> -$ adb shell dumpsys battery unplug -$ adb shell am set-idle <packageName> true -$ adb shell am set-idle <packageName> false -$ adb shell am get-idle <packageName> -</pre> - -<p class="note"><strong>注:</strong> -<a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud Messaging</a>(GCM)の次期リリースでは、高優先度のメッセージを指定できます。 - -アプリが高優先度の GCM メッセージを受信する場合は、アプリがアイドル 中でも短時間のネットワーク アクセスが付与されます。 - -</p> - -<p>アプリで App Standby をテストする方法のヒントについては、 -<a href="{@docRoot}preview/testing/guide.html#doze-standby">Testing Guide</a> をご覧ください。 - </p> - -<h2 id="behavior-adoptable-storage">追加可能なストレージ端末</h2> -<p> -このプレビューでは、SD カードなどの外部ストレージ端末を<em>追加</em>できます。外部ストレージ端末を追加すると、端末が内部ストレージのように動作するよう暗号化とフォーマットが行われます。 -この機能によって、アプリとアプリの個人データをストレージ端末間で移動できるようになります。 -アプリを移動する際、システムはマニフェストの -<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a> を遵守します。 - -</p> - -<p>アプリが次の API やフィールドにアクセスする場合は、アプリが内部ストレージ端末と外部ストレージ端末間で移動する際に返されるファイルパスが動的に変化することに注意してください。ファイルパスの構築時は、これらの API を動的に呼び出すことを強くお勧めします。ハードコードされたファイル パスを使用したり、過去にビルドした完全修飾ファイルパスをそのまま使用したりしないでください。 - - -</p> - -<ul> -<li>{@link android.content.Context} メソッド: - <ul> - <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li> - <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li> - <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li> - <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li> - <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li> - <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li> - <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li> - <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li> - <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li> - </ul> -</li> -<li>{@link android.content.pm.ApplicationInfo} フィールド: - <ul> - <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li> - <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li> - <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li> - <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li> - <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li> - <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li> - </ul> -</li> -</ul> - -<p>Developer Preview のこの機能をデバッグするには、USB On-The-Go(OTG)ケーブルで Android 端末に接続された USB ドライブの追加を有効にして、次のコマンドを実行します。 -</p> - -<pre class="no-prettyprint"> -$ adb shell sm set-force-adoptable true -</pre> - -<h2 id="behavior-apache-http-client">Apache HTTP Client の削除</h2> -<p>このプレビューでは、Apache HTTP クライアントのサポートが削除されました。アプリでこのクライアントを使用していて、Android 2.3(API レベル 9)以上を対象としている場合は、代わりに {@link java.net.HttpURLConnection} クラスを使用します。 - -この API は透過的データ圧縮と応答のキャッシュによってネットワーク使用を軽減し、電源の消費を最小化するため、効率性が向上します。 -Apache HTTP API を引き続き使用するには、まず {@code build.gradle} ファイルで次のコンパイル時の依存関係を宣言する必要があります。 - -</p> -<pre> -android { - useLibrary 'org.apache.http.legacy' -} -</pre> -<p>Android は、OpenSSL から -<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a> ライブラリに移行しています。 -アプリで Android NDK を使用している場合は、{@code libcrypto.so} や {@code libssl.so} など、NDK API の一部でない暗号化ライブラリにリンクしないでください。 -これらのライブラリは パブリック API ではなく、リリースや端末に対する通知なしで変更されたり、中断したりする可能性があります。また、セキュリティ上の脆弱性を露呈する場合もあります。 - -代わりに、ネイティブ コードを変更して JNI 経由で Java の暗号化 API を呼び出すか、希望の暗号化ライブラリに静的リンクします。 - -</p> - -<h2 id="behavior-audiomanager-Changes">AudioManager の変更点</h2> -<p>{@link android.media.AudioManager} クラスで音量を直接設定したり、特定のストリームをミュートにしたりする方法はサポートされなくなりました。 -{@link android.media.AudioManager#setStreamSolo(int,boolean) -setStreamSolo()} メソッドは廃止されたため、代わりに -{@code AudioManager.requestAudioFocus()} メソッドを呼び出す必要があります。同様に、 -{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} メソッドも廃止され、代わりに {@code AudioManager.adjustStreamVolume()} メソッドを呼び出して、値に {@code ADJUST_MUTE} か {@code ADJUST_UNMUTE} を渡します。 - -</p> - -<h2 id="behavior-test-selection">テキスト選択</h2> - -<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" /> - -<p>ユーザーがアプリ内でテキストを選択するとき、 -<em>切り取り</em>、<em>コピー</em>、<em>貼り付け</em>などのテキスト選択のアクションを -<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">フローティング ツール バー</a>に表示できるようになりました。 -<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">個別のビューに対してコンテキスト アクション モードを有効にする</a>にあるように、コンテキスト アクションバーに関するユーザー操作の実装も同様です。 - -</p> - -<p>テキスト選択にフローティング ツール バーを実装するには、既存のアプリに次の変更を加えます。 -</p> -<ol> -<li>{@link android.view.View} オブジェクトか {@link android.app.Activity} オブジェクトで、{@link android.view.ActionMode} の呼び出しを -{@code startActionMode(Callback)} から {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)} に変更します。 -</li> -<li>既存の {@code ActionMode.Callback} の実装を、{@code ActionMode.Callback2} に拡張します。 -</li> -<li>{@code Callback2.onGetContentRect()} メソッドをオーバーライドして、ビューのコンテンツの {@link android.graphics.Rect} オブジェクト)テキスト選択の四角形など)の座標を指定します。 -</li> -<li>四角形の位置が有効でなくなり、無効な要素がこれのみである場合は、{@code ActionMode.invalidateContentRect()} メソッドを呼び出します。 -</li> -</ol> - -<p><a href="{@docRoot}tools/support-library/index.html"> -Android Support Library</a> revision 22.2 を使用している場合、フローティング ツール バーに下方互換性はなく、デフォルトで appcompat が代わりに {@link android.view.ActionMode} オブジェクトを制御することに注意してください。 - -これにより、フローティング ツール バーは表示されなくなります。 -{@link android.support.v7.app.AppCompatActivity} で -{@link android.view.ActionMode} がサポートされるようにするには、 -{@code android.support.v7.app.AppCompatActivity.getDelegate()} を呼び出して、返された -{@link android.support.v7.app.AppCompatDelegate} オブジェクトで -{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} を呼び出し、 入力パラメータを {@code false} に設定します。 -この呼び出して、{@link android.view.ActionMode} オブジェクトの制御がフレームワークに戻ります。 -M Preview を実行する端末ではフレームワークによる -{@link android.support.v7.app.ActionBar} やフローティング ツール バー モードのサポートが可能ですが、M Preview 以前の端末では -{@link android.support.v7.app.ActionBar} モードのみがサポートされます。</p> - -<h2 id="behavior-keystore">Android キーストロークの変更点</h2> -<p>このプレビューでは、 -<a href="{@docRoot}training/articles/keystore.html">Android Keystore プロバイダ</a>による DSA のサポートがなくなります。 -ECDSA は引き続きサポートされます。</p> - -<p>停止時に暗号化を必要としないキーが、ロック画面の(ユーザーや端末の管理者などによる)無効時やリセット時に削除されなくなりました。 -停止時に暗号化を必要とするキーは、これらのイベント時に削除されます。 -</p> - -<h2 id="behavior-network">Wi-Fi とネットワークの変更点</h2> - -<p>このプレビューでは、Wi-Fi API とネットワーク API の動作に次のような変更点が追加されました。</p> -<ul> -<li>オブジェクトの作成者である場合のみ、アプリで{@link android.net.wifi.WifiConfiguration} オブジェクトの状態を変更できます。 -ユーザーや他のアプリによって作成された -{@link android.net.wifi.WifiConfiguration} オブジェクトは変更、削除できません。 -</li> -<li> -以前は、 -{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} で -{@code disableAllOthers=true} 設定を使ってアプリから端末を特定の Wi-Fi ネットワークに接続させた場合、端末はセルラー データなどの他のネットワークから切断されていました。 -このプレビューでは、端末が他のネットワークから切断されないようになりました。アプリの {@code targetSdkVersion} が {@code “20”} 以下の場合は、選択した Wi-Fi ネットワークに固定されます。 - -アプリの {@code targetSdkVersion} が {@code “21”} 以上の場合は、マルチネットワーク API( -{@link android.net.Network#openConnection(java.net.URL) openConnection()}メソッド、 -{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()}メソッド、新しい -{@code ConnectivityManager.bindProcessToNetwork()} メソッドなど)を使用してネットワーク トラフィックが選択したネットワークに送られるようにします。 - -</li> -</ul> - -<h2 id="behavior-camera">カメラ サービスの変更点</h2> -<p>このプレビューでは、カメラ サービスの共有リソースへのアクセスモデルが、以前の "先着順" モデルから、"優先度順" に変更されました。 - -この動作の変更には、次のようなものがあります。</p> -<ul> -<li>カメラ端末を開いて構成するなど、カメラのサブシステム リソースへのアクセスは、クライアント アプリケーション プロセスの "優先度" に基づいて与えられます。 -通常、ユーザーに表示されているアクティビティやフォアグラウンドにあるアクティビティのあるアプリケーション プロセスの優先度が最も高くなり、カメラ リソースの取得や使用の信頼性が高まります。 - -</li> -<li>優先度の低いアプリでアクティブなカメラ クライアントは、より優先度の高いアプリケーションがカメラを使おうとした際に使用が中断される場合があります。 -廃止された {@link android.hardware.Camera} API では、使用が中断されたクライアントに -{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()} が呼び出されます。 - -{@link android.hardware.camera2 Camera2} API では、使用が中断されたクライアントに -{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()} が呼び出されます。 -</li> -<li>適切なカメラ ハードウェア付きの端末では、別のアプリケーション プロセスを独立して開き、別のカメラ端末を同時に使用できます。 -ただし、同時アクセスによってパフォーマンスや開いているカメラ端末の性能が著しく低下するマルチプロセスの使用が検出可能になり、カメラ サービスでは許可されなくなりました。 - -この変更によって、同じカメラ端末にアクセスしようとしているアプリが他になくても、優先度の低いクライアントによる使用が中断される場合があります。 - - -</li> -<li> -現在のユーザーを変更すると、アプリ内で前のユーザー アカウントで所有していたアクティブなカメラ クライアントが中断させられることになります。 -カメラへのアクセスは、現在の端末ユーザーが所有するユーザー プロファイルのみに制限されます。つまり、ユーザーが別のアカウントに切り替えた場合、"ゲスト" アカウントはカメラのサブシステムを使用するプロセスを実行したまま去ることはできません。 - - -</li> -</ul> - -<h2 id="behavior-art-runtime">ART ランタイム</h2> -<p>ART ランタイムで、 -{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} メソッドに対するアクセスルールを正常に実装できるようになりました。この変更によって、以前のバージョンで Dalvik がアクセス ルールを正しく確認できなかった問題が解決しました。アプリで -{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} メソッドを使用していて、アクセス チェックをオーバーライドしたい場合は、 {@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} メソッドを使って入力パラメータを {@code true} に設定します。 - - - - -アプリで -<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7 appcompat ライブラリ</a>や -<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">v7 recyclerview ライブラリ</a>を使用する場合は、これらのライブラリの最新バージョンを使用するようアプリをアップデートする必要があります。 -アップデートしない場合は、XML から参照するカスタム クラスがアップデートされていて、クラス コンストラクタがアクセス可能であることを確認しておく必要があります。 -</p> - -<p>このプレビューでは、動的リンクの動作がアップデートされました。動的リンクでは、ライブラリの {@code soname} とそのパス(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link"> -public bug 6670</a>)の違いを認識でき、{@code soname} が実装されています。 - - -以前動作していたアプリで間違った {@code DT_NEEDED} エントリを持つもの(ビルドマシンのファイル システムの絶対パスなど)は、読み込み時に失敗する場合があります。 -</p> - -<p>{@code dlopen(3) RTLD_LOCAL} フラグは正常に実装されました。 -{@code RTLD_LOCAL} はデフォルトのため、 -{@code RTLD_LOCAL} を明示的に使用しない {@code dlopen(3)} への呼び出しは影響を受けます(アプリで明示的に {@code RTLD_GLOBAL} を使用している場合を除く)。 -{@code RTLD_LOCAL} では、後に -{@code dlopen(3)} への呼び出しで読み込まれたライブラリで記号は使用できません({@code DT_NEEDED} エントリによって参照された場合とは逆)。</p> -</p> - -<h2 id="behavior-apk-validation">APK の検証</h2> -<p>プラットフォームでより厳しい APK の検証が行われるようになりました。APK がマニフェスト ファイルで宣言されているにもかかわらず、APK 自体に存在しない場合、その APK は破損しているとみなされます。 -コンテンツが一部でも削除された場合は、APK の再署名が必要になります。 -</p> - -<h2 id="behavior-afw">Android for Work の変更点</h2> -<p>このプレビューには、次のような Android for Work に関する動作の変更点が含まれています。</p> -<ul> -<li><strong>個人のコンテキストでの仕事用の連絡先</strong>ユーザーが過去の通話履歴を表示したときに、Google Dialer -Call Log に仕事用の連絡先が表示されるようになりました。{@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} を {@code true} に設定すると、Google Dialer Call Log に仕事用プロファイルの連絡先は表示されなくなります。 - -{@code DevicePolicyManager.setBluetoothContactSharingDisabled()} を {@code false} に設定した場合のみ、Bluetooth 経由で端末に仕事用の連絡先と個人用の連絡先を表示できます。 - -デフォルトでは、{@code true} に設定されています。 - -</li> -<li><strong>WiFi 設定の削除:</strong>プロファイル オーナーによって追加された WiFi 設定(@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration) -addNetwork()} メソッドへの呼び出しなどを介して)は、その仕事用プロファイルが削除されると同時に削除されます。 - -</li> -<li><strong>WiFi 設定のロック:</strong>アクティブなデバイス オーナーによって作成された WiFi 設定は、ユーザーが修正したり削除したりできなくなりました。 -ユーザーに {@link android.os.UserManager} 定数 -{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} が設定されていない限り、ユーザー自身の WiFi 設定を作成、修正することはできます。 -</li> -<li><strong>Google アカウントの追加経由での Work Policy Controller のダウンロード:</strong>Work Policy Controller(WPC)アプリ経由で管理する必要のある Google アカウントがマネージド コンテキスト外で端末に追加されると、アカウントの追加フローでユーザーに適切な WPC をインストールするよう要求します。この動作は、初期の端末のセットアップ ウィザードでの -<strong>[設定]> [アカウント]</strong> で追加されるアカウントにも適用されます。 - - -</li> -<li><strong>特定の DevicePolicyManager API の動作の変更点: </strong> -{@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()} メソッドの呼び出しは、呼び出し元のユーザーのカメラにのみ影響を与えます。マネージド プロファイルから呼び出した場合は、プライマリ ユーザーで実行しているカメラ アプリに影響はありません。 - -さらに、 -{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()} メソッドは、デバイス オーナーに加えてプロファイル オーナーでも利用可能になりました。 -プロファイル オーナーは、これらのキーガード制限を設定できます: - -<ul> -<li>プロファイルの親ユーザーのキーガード設定に影響を与える {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} と {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}。 - -</li> -<li>マネージド プロファイルのアプリケーションで生成された通知のみに影響を与える {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}。 -</li> -</ul> -</li> -</ul> diff --git a/docs/html-intl/intl/ja/preview/download.jd b/docs/html-intl/intl/ja/preview/download.jd deleted file mode 100644 index 7f6f4990df8e..000000000000 --- a/docs/html-intl/intl/ja/preview/download.jd +++ /dev/null @@ -1,360 +0,0 @@ -page.title=ダウンロード -page.image=images/cards/card-download_16-9_2x.png - -@jd:body - -<div style="position:relative; min-height:600px"> - - <div class="wrap" id="tos" style="position:absolute;display:none;width:inherit;"> - - <p class="sdk-terms-intro">Android Preview SDK のコンポーネントをダウンロード、インストールする前に、次の利用規約に同意する必要があります。 -</p> - - <h2 class="norule">利用規約</h2> - - <div class="sdk-terms" onfocus="this.blur()" style="width:678px"> -以下は、Android SDK Preview の使用許諾契約です(以下「本契約」)。 - -1.はじめに - -1.1 Android SDK Preview(以下、本契約で「Preview」という。具体的には利用可能な場合には Android システム ファイル、パッケージ型 API、Preview ライブラリ ファイルを含む)は、本契約の規定に従ってライセンス許可されます。本契約では、デベロッパーの Preview の使用に関して、デベロッパーと Google の間で法的拘束力のある契約を結びます。 - -1.2 「Android」とは、Android オープン ソース プロジェクト(http://source.android.com/ にて随時更新)にて利用可能な、端末向けの Android ソフトウェア スタックを意味します。 - -1.3 「Google」とは、1600 Amphitheatre Parkway, Mountain View, CA 94043, United States に主たる事業所を有するデラウェア州法人である Google Inc. を意味します。 - -2.本契約の同意 - -2.1 Preview を使用するには、まず本契約に同意する必要があります。本契約に同意しない場合は Preview を使用できません。 - -2.2 同意するかまたは Preview を使用するためにクリックすると、本契約に同意したことになります。 - -2.3 米国またはその他の国(デベロッパーが居住している国かまたはデベロッパーが Preview を使用する国を含む)の法律により Preview の使用を禁止されている人である場合、Preview を使用することも、使用許諾契約に同意することもできません。 - -2.4 雇用主またはその他の事業体を代表または代理して本契約に拘束されることに同意し Preview を企業または組織の内部で使用する場合、担当者の雇用主またはその他の事業体を本契約に法的に拘束する完全な法的権限を有していることを表明および保証するものとします。担当者が必要な権限を有していない場合は、担当者の雇用主またはその他の事業体を代表または代理して、本契約に同意することも、Preview を使用することもできません。 - -3.Google Preview ライセンス - -3.1 本契約の規定に従い、Google は Android プラットフォーム上で実行するアプリケーションの開発に Preview を個人的にもしくは企業または組織の内部で使用するための、ロイヤリティ フリーな、譲渡不可で、非排他的な、サブライセンス不可の、限定された、取り消し可能なライセンスを付与するものとします。 - -3.2 Preview に関するすべての法的権利、所有権、利益(Preview に含まれる知的財産権を含む)は Google またはサードパーティが所有するものとします。「知的財産権」とは、特許法、著作権法、営業秘密法、商標法、不当競争防止法に基づいて発生するすべての権利、およびその他のすべての所有権を意味します。デベロッパーに明示的に付与されていない権利は、すべて Google が所有します。 - -3.3 本契約で明示的に許可されている目的以外においては、Preview を使用できません。当該のサードパーティのライセンスで必要とされる場合を除き、デベロッパーは、(a) Preview または Preview の一部をコピー(バックアップ目的を除く)、修正、改造、再配布、逆コンパイル、リバース エンジニアリング、逆アセンブルまたは派生物の作成、または(b)モバイル ハンドセットまたは個人用 PC 以外のハードウェア端末への Preview の読み込み、Preview と他のソフトウェアとの結合、または Preview の一部を組み込んだソフトウェアや端末の配布はできません。 - -3.4 デベロッパーは、Android の断片化につながるような行為をしないことに同意します。これには、Preview から派生したソフトウェア開発キットの配布、作成への参加、宣伝を含みます(ただし必ずしもこれらには限定されません)。 - -3.5 オープンソース ソフトウェア ライセンス下でライセンス付与された Preview のコンポーネントの使用、複製、配布は、本契約ではなく、そのオープンソース ソフトウェアのライセンスに準拠するものとします。デベロッパーは、許諾されるすべての権利下で、そのようなオープンソース ソフトウェア ライセンスに対して、優良ライセンシーのままでいることに同意し、そのような権利を終了、停止、または違反する可能性のあるいかなる行為も差し控えることに同意するものとします。 - -3.6 デベロッパーは、Google が提供する Preview の形式および性質は事前の通知なしに変更される場合があり、今後リリースされる Preview のバージョンでは、以前のバージョンの Preview で開発されたアプリケーションとの互換性がない可能性があることに同意します。デベロッパーは、Google が事前の通知なく、Google の単独の裁量でデベロッパーまたはユーザーへの Preview(または Preview 内の一部の機能)の提供を(恒久的または一時的に)停止する場合があることに同意します。 - -3.7 本契約のいかなる部分も、Google のいかなる商標名、商標、サービスマーク、ロゴ、ドメイン名、またはその他のブランド識別表示を使用する権利もデベロッパーに付与するものではありません。 - -3.8 デベロッパーは、Preview に添付または収録されているすべての知的財産権に関する通知(著作権および商標の通知を含む)の削除、隠ぺい、改ざんを行わないことに同意します。 - -4.デベロッパーによる Preview の使用 - -4.1 Google は、本契約に基づき Preview を使用してデベロッパーが開発したソフトウェア アプリケーションに関して、デベロッパー(またはデベロッパーのライセンサー)からいかなる権利、所有権、または利益(当該アプリケーションに含まれる知的財産権を含む)も取得するものではないことに同意します。 - -4.2 デベロッパーは、Preview を(a)本契約、および(b)該当する司法管轄区における適用される法律、規則、または一般に認められた慣行またはガイドライン(米国またはその他の該当国におけるデータまたはソフトウェアの輸出入に関する法律を含む)で認められている目的にのみ使用することに同意します。 - -4.3 Preview を使用してアプリケーションを開発する場合、デベロッパーはユーザーのプライバシーおよび法的権利を保護することに同意します。ユーザーからデベロッパーにユーザー名、パスワード、またはその他のログイン情報または個人情報が提供される場合、デベロッパーは、情報がデベロッパーのアプリケーションに提供されることをユーザーに認識させ、当該ユーザーについてプライバシーに関する法的に十分な通知および保護を行わなければなりません。デベロッパーのアプリケーションに個人情報または秘密情報が保存される場合、この保存は保護された方法で行われなければなりません。ユーザーからデベロッパーのアプリケーションに Google アカウントの情報が提供された場合、デベロッパーのアプリケーションでは、ユーザーが許可したタイミングで、かつユーザーが許可した限定された目的にのみ、当該情報を使用してユーザーの Google アカウントにアクセスすることが認められるものとします。 - -4.4 デベロッパーは、Preview に関して、第三者(Google、およびあらゆる携帯電話会社を含むが、これらに限定されない)のサーバー、ネットワーク、またはその他の財産またはサービスへの妨害、中断、損害、または許可されていない態様でのアクセスとなる行為(そのような行為に該当する対象製品の開発または販売 / 配布を含む)に関与しないことに同意します。 - -4.5 デベロッパーは、デベロッパーが Android および Android のアプリケーションを介して作成、送信、表示するデータ、コンテンツ、リソース、および自身の行為の結果(Google に発生する可能性のあるあらゆる損失および損害を含む)について、自身が単独で責任を負うこと(および Google がこれについてデベロッパーまたはいかなる第三者に対しても一切責任を負わないこと)に同意します。 - -4.6 デベロッパーは、本契約、適用される第三者の契約もしくは利用規約、または適用される法律もしくは規則に基づく自身の義務に違反したこと、および当該違反の結果(Google または第三者に発生したあらゆる損失および損害を含む)について、自身が単独で責任を負うこと(および Google がこれについてデベロッパーまたはいかなる第三者に対しても一切責任を負わないこと)に同意します。 - -4.7 Preview は開発中であり、デベロッパーによるテスティングやフィードバックは開発プロセスの重要な一部となります。デベロッパーは、Preview の使用により、一部の機能の実装が開発中であると認識し、Preview が安定したリリースの完全な機能性を持つことに依存すべきでないことを認識するものとします。本 Preview は、公式の Android SDK のリリース後はサポート対象でなくなるため、デベロッパーは、Preview を使用するいかなるアプリケーションも公然と配布または引き渡さないことに同意するものとします。 - -5.デベロッパーの資格情報 - -5.1 デベロッパーは、Google が発行した、またはデベロッパー自身で選択した、自身のデベロッパー用資格情報の秘密を保持する責任を負うこと、および自身のデベロッパー用資格情報のもとで開発されたすべてのアプリケーションについて単独で責任を負うことに同意します。 - -6.プライバシーおよび情報 - -6.1 Google は、Preview の継続的な技術革新と改良のために、ソフトウェアから特定の使用状況統計情報(一意識別子、関連する IP アドレス、ソフトウェアのバージョン番号、Preview のどのツール/サービスがどのように使用されているかに関する情報を含むが、これらに限定されない)を収集できます。この情報が収集される前に、Preview に通知が表示され、デベロッパーの同意が求められます。デベロッパーが同意しない場合は、情報は収集されません。 - -6.2 収集されるデータは、Preview の改良のために集約された形で精査され、Google のプライバシー ポリシー(http://www.google.com/policies/privacy/)に従って管理されます。 - -7.第三者のアプリケーション - -7.1 デベロッパーが、Preview を使用して第三者が開発したアプリケーションを実行する、あるいは第三者から提供されたデータ、コンテンツ、リソースにアクセスする場合、デベロッパーは、Google がそれらのアプリケーション、データ、コンテンツ、リソースについて責任を負わないことに同意します。デベロッパーは、そのような第三者のアプリケーションを介してアクセスするすべてのデータ、コンテンツ、リソースについては、それらを生成した者が単独で責任を負うものであり、Google はそれらの第三者のアプリケーション、データ、コンテンツ、またはリソースの使用もしくはアクセスによって生じたあらゆる損失および損害について一切責任を負わないことを理解します。 - -7.2 デベロッパーは、そのような第三者のアプリケーションを介して表示されるデータ、コンテンツ、リソースは、提供者(あるいは代理の第三者または事業体)が所有する知的財産権で保護されている場合があることを認識するものとします。デベロッパーは、当該所有者からの明確な許可がない限り、それらのデータ、コンテンツ、リソース(全体または一部)の変更、貸与、賃貸、担保、配布または派生物の作成を行うことはできません。 - -7.3 デベロッパーは、そのような第三者のアプリケーション、データ、コンテンツまたはリソースの使用が、デベロッパーと当該第三者間の別の規約に従うものであることを認識するものとします。 - -8.Google API の使用 - -8.1 Google API - -8.1.1 API を使用して Google からデータを取得する場合、デベロッパーは、そのデータは、Google またはデータを提供する事業体(あるいは代理の第三者または事業体)が所有する知的財産権で保護されている場合があることを認識するものとします。そのような API の使用は追加の利用規約に従うものとします。デベロッパーは、当該の利用規約による許可がない限り、そのデータ(全体または一部)の変更、貸与、賃貸、担保、配布または派生物の作成を行うことはできません。 - -8.1.2 デベロッパーは、API を使用して Google からユーザーのデータを取得する場合、ユーザーが明示的に同意した場合のみ、およびユーザーが許可したタイミングとその目的にのみ、データを取得できることを理解し、同意します。 - -9.本契約の終了 - -9.1 本契約は、下記の規定に従ってデベロッパーまたは Google のいずれかによって解約されるまで、継続して適用されるものとします。 - -9.2 デベロッパーが本契約の解約を希望する場合は、Preview および関連するデベロッパー資格情報の使用を停止することで、契約を終了するものとします。 - -9.3 Google は、理由の有無にかかわらず、書面で通知することでいつでもデベロッパーとの本契約を解約することができます。 - -9.4 本契約は事前の通知またはその他の措置なく、次のうち早い方に自動的に終了します。 -(A)Google が、デベロッパーが居住している国またはデベロッパーがサービスを使用する国での Preview または Preview の一部の配布を停止したとき。 -(B)Google が Android SDK の最終バージョンをリリースしたとき。 - -9.5 本契約が終了すると、本契約で付与されていたライセンスは終了し、デベロッパーは速やかに Preview のすべての使用を停止するものとし、第 10 条、第 11 条、第 12 条、第 14 条の規定は無期限に効力を有するものとします。 - -10.免責事項 - -10.1 デベロッパーは、デベロッパーによる Preview の使用はデベロッパー自身の責任において行うものであること、および Preview は「現状有姿」かつ「提供可能な限りにおいて」、Google からのいかなる種類の保証もなく提供されるものであることを明示的に理解し、これに同意します。 - -10.2 デベロッパーによる Preview および Preview の使用を通じてダウンロードまたはその他の方法で取得されたマテリアルの使用は、デベロッパー自身の裁量および責任において行うものであり、当該使用の結果として生じるデベロッパーのコンピュータ システムもしくはその他の端末への損害またはデータの喪失についての責任はデベロッパーが単独で負います。前述を制限することなく、Preview は安定したリリースではなく、コンピュータやその他の端末の利用の完全な回復不可能な損失を含む、重大な損害を引き起こす可能性のあるエラー、欠陥、およびセキュリティ上の脆弱性が含まれている可能性があることを理解します。 - -10.3 Google はまた、商品性、特定目的への適合性、および権利侵害がないことの黙示的な保証および条件を含む(ただしこれらに限定されない)、明示的か黙示的かを問わずあらゆる種類のすべての保証および条件を明示的に否定します。 - -11.責任の制限 - -11.1 デベロッパーは、Google、その子会社および関連会社、ならびにそのライセンサーが、デベロッパーに発生した直接損害、間接損害、偶発的損害、特別損害、結果的損害、または懲罰的損害(データの喪失を含む)について、Google またはその代表者が当該損失が発生する可能性について告知されていたかどうか、または知っていたはずであるかどうかにかかわらず、いかなる責任法理のもとでもデベロッパーに対して責任を負わないことを明示的に理解し、これに同意します。 - -12.補償 - -12.1 法律で認められる最大限の範囲内において、デベロッパーは、(a)デベロッパーが Preview を使用したこと、および(b)デベロッパーが Preview で開発したアプリケーションが他者のいかなる知的財産権を侵害していること、または他者の名誉を毀損している、もしくは他者のパブリシティ権もしくはプライバシー権を侵害していること、および(c)デベロッパーが本契約に違反したことから発生したあらゆる申し立て、普通法上の訴訟、衡平法上の訴訟、または法的手続き、ならびにあらゆる損失、責任、損害、費用、および経費(合理的な弁護士報酬を含む)について、Google、その関連会社、ならびに当該各社の取締役、役員、従業員、代理人を防御し、補償し、免責することに同意します。 - -13.契約の変更 - -13.1 Google は、Preview の新しいバージョンを配布することにより、いつでも本契約を変更することができます。変更が生じた場合、Google は、Preview の提供ウェブサイト上に使用許諾契約の改訂版を公開します。 - -14.法的一般条項 - -14.1 本契約は、デベロッパーと Google の間の法的な合意のすべてを表し、デベロッパーによる Preview の使用(別の契約下で Google が提供するサービスを除く)に適用され、Preview に関するデベロッパーと Google の間のあらゆる事前の合意に完全に取って代わるものです。 - -14.2 デベロッパーは、Google が本契約に定める(または適用される法律のもとで Google が享受できる)法的な権利または救済措置を行使または執行しなかった場合でも、Google の権利が正式に放棄されたとはみなされないこと、および Google が以後も引き続き当該権利および救済措置を行使または執行できることに同意します。 - -14.3 本件について判断を下す管轄権を有する司法裁判所によって、本契約のいずれかの条項が無効と判断された場合、当該条項は、本契約の残りの部分に影響を与えることなく本契約から削除されるものとします。本契約の残りの条項は、以後も引き続き有効かつ執行可能であるものとします。 - -14.4 デベロッパーは、Google が親会社となっている各グループ企業が、本契約の第三受益者となること、および当該企業が、当該企業に利益(または受益権)を付与する本契約の条項を直接執行する、また当該条項に依拠する権利を有することを了承し、これに同意します。上記以外のいかなる人または法人も、本契約の第三受益者とはならないものとします。 - -14.5 輸出規制。Preview は、米国輸出管理法令の対象です。デベロッパーは、Preview に適用されるすべての国内および国際の輸出管理法令に従わなければなりません。これらの法律には、仕向け地、ユーザー、および最終用途に関する制限が含まれます。 - -14.6 デベロッパーは、Google から事前に書面で承認を得ずに、本契約を譲渡または移転することはできません。また、そのような承認を得ずに計画された譲渡はすべて無効になります。デベロッパーは、Google から事前に書面で承認を得ずに、本契約に基づく自身の責任または義務を他者に委任してはなりません。 - -14.7 本契約あるいは本契約に基づくデベロッパーと Google の関係から発生または関連するすべての申し立ては、米国カリフォルニア州の抵触法を除いて、カリフォルニア州法に準拠するものとします。デベロッパーおよび Google は、本契約あるいは本契約に基づくデベロッパーと Google の関係から発生または関連する法的事項の解決について、米国カリフォルニア州サンタクララ郡に所在の連邦裁判所または州立裁判所が専属管轄権を有することに合意します。上記にかかわらず、デベロッパーは、Google が任意の司法管轄区において差し止め命令による救済(または同等の緊急法的救済)を求める申し立てを行うことが認められることに同意します。 - </div><!-- sdk terms --> - - - - <div id="sdk-terms-form"> - <p> - <input id="agree" type="checkbox" name="agree" value="1" onclick="onAgreeChecked()" /> - <label id="agreeLabel" for="agree">上記の利用規約を読み、同意します。</label> - </p> - <p><a href="" class="button disabled" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p> - </div> - - - </div><!-- end TOS --> - - - <div id="landing"> - -<div id="qv-wrapper"> - <div id="qv"> - <h2>本書の内容</h2> - <ol> - <li><a href="#sdk">Android 6.0 SDK</a></li> - <li><a href="#docs">デベロッパー ドキュメント</a></li> - <li><a href="#images">ハードウェアのシステム イメージ</a></li> - </ol> - - <h2>Legacy downloads</h2> - <ol> - <li><a href="{@docRoot}preview/download_mp1.html">Developer Preview 1</a></li> - <li><a href="{@docRoot}preview/download_mp2.html">Developer Preview 2</a></li> - </ol> - </div> -</div> - - -<p> - Android M Preview SDK には、アプリとプラットフォームの次期リリースで提供される新しい API とのテストに役立つ開発ツール、Android システム ファイル、ライブラリ ファイルが含まれています。 -このドキュメントでは、アプリのテスト用にダウンロードできる Preview のコンポーネントを入手する方法について説明します。 - -</p> - - -<h2 id="sdk">Android 6.0 SDK</h2> - -<p> - Preview SDK <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK マネージャー</a>経由でダウンロードできます。Preview SDK のダウンロードと設定の詳細については、<a href="{@docRoot}preview/setup-sdk.html#downloadSdk">Set Up the Preview SDK</a> をご覧ください。 - -</p> - - -<h2 id="docs">デベロッパー ドキュメント</h2> - -<p> - デベロッパー ドキュメントのダウンロード パッケージでは、詳細な Preview の API リファレンス情報や API の比較レポートが提供されます。 -</p> - -<table> - <tr> - <th scope="col">Description</th> - <th scope="col">Download / Checksums</th> - </tr> - <tr id="docs-dl"> - <td>Android M Preview 3<br>Developer Docs</td> - <td><a href="#top" onclick="onDownload(this)" - >m-preview-3-developer-docs.zip</a><br> - MD5: d99b14b0c06d31c8dfecb25072654ca3<br> - SHA-1: 9cefeeda07676130da606a1796e1c00fffc667c1 - </td> - </tr> -</table> - -<h2 id="images">ハードウェアのシステム イメージ</h2> - -<p> - これらのシステム イメージでは、テスト用に物理端末にプラットフォームのプレビュー バージョンをインストールできます。 -端末にこれらのイメージを 1 つ以上設定すると、アプリをインストールして、プラットフォームの次期バージョンでアプリがどのように動作するかをテストできます。 -端末にシステム イメージをインストールするプロセスでは、<em>端末からすべてのデータが削除</em>されるため、システム イメージのインストール前にデータをバックアップする必要があります。 - - -</p> - -<p class="warning"> - <b>警告:</b> 次の Android システム イメージはプレビュー版であり、今後変更される可能性があります。デベロッパーによるシステム イメージの使用は、Android SDK Preview 使用許諾契約に準拠するものとします。 -Android Preview システム イメージは安定したリリースではなく、お使いのコンピュータ システム、端末、データに影響を与える可能性のあるエラーや欠陥が含まれている場合があります。 - -プレビュー版の Android システム イメージは工場出荷版の OS と同等のテストを受けておらず、お使いの電話やインストールされているサービス、アンインストールの動作停止を引き起こす場合があります。 - - -</p> - -<table> - <tr> - <th scope="col">Device</th> - <th scope="col">Download / Checksums</th> - </tr> - <tr id="hammerhead"> - <td>Nexus 5 (GSM/LTE) <br>"hammerhead"</td> - <td><a href="#top" onclick="onDownload(this)" - >hammerhead-MPA44I-preview-2ebbc049.tgz</a><br> - MD5: 91a924fb0c9f8e716e3b4c9954fd0dbb<br> - SHA-1: 2ebbc049b68c4da8baeee3e42bb94d7a965ba4a3 - </td> - </tr> - <tr id="shamu"> - <td>Nexus 6 <br>"shamu"</td> - <td><a href="#top" onclick="onDownload(this)" - >shamu-MPA44I-preview-62b9c486.tgz</a><br> - MD5: ac6e58da86125073d9c395257fd42664<br> - SHA-1: 62b9c486fd7a5020e228d53ca5acd5c1857e48ff - </td> - </tr> - <tr id="volantis"> - <td>Nexus 9 <br>"volantis"</td> - <td><a href="#top" onclick="onDownload(this)" - >volantis-MPA44I-preview-5c30a6e2.tgz</a><br> - MD5: 7f83768757913d3fea945a661020d185<br> - SHA-1: 5c30a6e2acd11a81f4105b12d23ff654f534f699 - </td> - </tr> - - <tr id="fugu"> - <td>Nexus Player <br>"fugu"</td> - <td><a href="#top" onclick="onDownload(this)" - >fugu-MPA44I-preview-2860040a.tgz</a><br> - MD5: 438da8d37da9e341a69cfb16a4001ac5<br> - SHA-1: 2860040a326582f1ff5f702bf9a1ef002717fc98 - </td> - </tr> - -</table> - -<h3 id="install-image">端末にイメージをインストールする</h3> - -<p> - テスト用に端末イメージを使用するには、互換性のある端末にインストールする必要があります。次の手順に従って、システム イメージをインストールします。 - -</p> - -<ol> - <li>この一覧の中からいずれかのシステム イメージ パッケージをダウンロードして、解凍します。</li> - <li>保持するデータを端末からバックアップします。</li> - <li> -<a href="https://developers.google.com/android/nexus/images#instructions">developers.google.com/android</a> - の手順に従って端末にイメージをフラッシュします。</li> -</ol> - -<p class="note"> - <strong>注:</strong> 開発用端末に Preview のシステム イメージをフラッシュすると、OTA アップデートを通じて次のプレビュー リリースに自動的にアップグレードされます。 - -</p> - -<h3 id="revertDevice">端末を工場出荷時の仕様に戻す</h3> - -<p> - Preview をアンインストールして、工場出荷時の仕様に戻すには、 -<a href="http://developers.google.com/android/nexus/images">developers.google.com/android</a> にアクセス -して、端末にフラッシュするイメージをダウンロードします。同じページの手順に従って端末にイメージをフラッシュします。 - -</p> - - </div><!-- landing --> - -</div><!-- relative wrapper --> - - - -<script> - var urlRoot = "http://storage.googleapis.com/androiddevelopers/shareables/preview/"; - function onDownload(link) { - - $("#downloadForRealz").html("Download " + $(link).text()); - $("#downloadForRealz").attr('href', urlRoot + $(link).text()); - - $("#tos").fadeIn('fast'); - $("#landing").fadeOut('fast'); - - return true; - } - - - function onAgreeChecked() { - /* verify that the TOS is agreed */ - if ($("input#agree").is(":checked")) { - /* reveal the download button */ - $("a#downloadForRealz").removeClass('disabled'); - } else { - $("a#downloadForRealz").addClass('disabled'); - } - } - - function onDownloadForRealz(link) { - if ($("input#agree").is(':checked')) { - /* - $("#tos").fadeOut('fast'); - $("#landing").fadeIn('fast'); - */ - - ga('send', 'event', 'M Preview', 'System Image', $("#downloadForRealz").html()); - - /* - location.hash = ""; - */ - return true; - } else { - return false; - } - } - - $(window).hashchange( function(){ - if (location.hash == "") { - location.reload(); - } - }); - -</script> diff --git a/docs/html-intl/intl/ja/preview/features/app-linking.jd b/docs/html-intl/intl/ja/preview/features/app-linking.jd deleted file mode 100644 index 92da0b42ae82..000000000000 --- a/docs/html-intl/intl/ja/preview/features/app-linking.jd +++ /dev/null @@ -1,123 +0,0 @@ -page.title=App Links -page.image=images/cards/card-app-linking_2x.png -page.keywords=applinking,deeplinks,intents -@jd:body - -<div id="qv-wrapper"> - <div id="qv"> - <h2>本書の内容</h2> - <ol> - <li><a href="#web-assoc">ウェブサイトの関連を宣言する</a></li> - <li><a href="#verfy-links">App Link の検証を要求する</a></li> - <li><a href="#user-manage">App Link 設定を管理する</a></li> - </ol> - </div> -</div> - -<p> - Android インテント システムは、アプリでコンテンツや要求を処理できるようにする柔軟なメカニズムです。 - 複数のアプリが、それぞれのインテント フィルタに一致する URI パターンを宣言できます。デフォルトのローンチ ハンドラを持たないウェブリンクをユーザーがクリックしたとき、一致するインテント フィルタが宣言されているアプリの一覧から選択するダイアログがプラットフォームによってユーザーに表示されます。 - - -</p> - -<p> - Android M Developer Preview でサポートされる App Links では、既存のリンク処理が改善され、アプリ開発者が所有するウェブドメインとアプリを関連付けられるようになりました。 -デベロッパーがこの関連を作成すると、プラットフォームが特定のウェブリンクの処理に使用するデフォルトのアプリを自動的に決めることができ、ユーザーにアプリを選択させる操作をスキップできます。 - - -</p> - - -<h2 id="web-assoc">ウェブサイトの関連付けを宣言する</h2> - -<p> - ウェブサイトのオーナーは、アプリのリンクを設定するための関連を宣言する必要があります。サイトのオーナーは、ドメインのよく知られた場所で {@code statements.json} という名前の JSON ファイルをホストすることで、アプリとの関係を宣言します。 - - -</p> - -<pre>http://<domain>:<optional port>/.well-known/statements.json</pre> - -<p class="note"> - <strong>注:</strong> - M Developer Preview の間、JSON ファイルは http プロトコルを介して検証されます。プラットフォームの正式リリースでは、ファイルは暗号化された https プロトコルで検証されます。 - -</p> - -<p> - この JSON ファイルは、このドメイン下の URL のデフォルトのハンドラとして使用する必要のある Android アプリを示します。 -アプリは、次のフィールドに基づいて識別されます。 -</p> - -<ul> - <li>{@code package_name}:アプリのマニフェストで宣言されたパッケージ名。</li> - - <li>{@code sha256_cert_fingerprints}:アプリの署名証明書の SHA256 のフィンガープリント。 - Java Keytool を使用して、次のコマンドでフィンガープリントを生成できます。 - <pre>keytool -list -v -keystore my-release-key.keystore</pre> - </li> -</ul> - -<p> - 次のファイル一覧は、 -{@code statements.json} ファイルのコンテンツと形式の例を示しています。 -</p> - -<pre> -[{ - "relation": ["delegate_permission/common.handle_all_urls"], - "target": { - "namespace": "android_app", - "package_name": "<strong><package name></strong>", - "sha256_cert_fingerprints": ["<strong>6C:EC:C5:0E:34:AE....EB:0C:9B</strong>"] - } -}] -</pre> - - -<h2 id="verfy-links">App Link の検証を要求する</h2> - -<p> - アプリから、インテント フィルタのデータ エレメントのホスト名で定義されたアプリのリンクを、それぞれのウェブドメインでホストされる {@code statements.json} ファイルに対してプラットフォームが自動的に検証するよう要求できます。 - -アプリリンクの検証を要求するには、次のマニフェスト コード スニペットのように {@code android:autoVerify} - 属性をマニフェスト内の目的のインテント フィルタに追加します。 - -</p> - -<pre> -<activity ...> - <intent-filter <strong>android:autoVerify="true"</strong>> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.BROWSABLE" /> - <data android:scheme="http" android:host="www.android.com" /> - <data android:scheme="https" android:host="www.android.com" /> - </intent-filter> -</activity> -</pre> - -<p> - {@code android:autoVerify} 属性がアプリ マニフェストに存在する場合、プラットフォームはアプリのインストール時にアプリのリンクを検証しようとします。 -プラットフォームがアプリのリンクを正常に検証できない場合、アプリはウェブリンクの処理に適したアプリとして設定されません。 -次回ユーザーがいずれかのリンクを開いたとき、プラットフォームはユーザーに再度ダイアログを表示します。 - - -</p> - -<p class="note"> - <strong>注:</strong> テスト時に、ユーザーがシステムの設定アプリを使ってサポートされているリンクを開くアプリを明示的に有効にしていると、誤検出が原因で検証が失敗する場合があります。この場合、ダイアログは表示されず、リンクは直接アプリに送られますが、これは検証が成功したからではなく、ユーザーの設定に基づいて動作したからです。 - - - -</p> - - -<h2 id="user-manage">App Link 設定を管理する</h2> - -<p> - ユーザーが希望する方法で URL を処理するように、ユーザー側でアプリのリンク設定を変更できます。アプリのリンクは、システムの設定アプリの <strong>[設定] > [アプリ] > [アプリ情報] > [デフォルトでの起動]</strong> で確認、管理できます。 - - -</p> diff --git a/docs/html-intl/intl/ja/preview/features/runtime-permissions.jd b/docs/html-intl/intl/ja/preview/features/runtime-permissions.jd deleted file mode 100644 index f582756c816c..000000000000 --- a/docs/html-intl/intl/ja/preview/features/runtime-permissions.jd +++ /dev/null @@ -1,794 +0,0 @@ -page.title=パーミッション -page.tags=previewresources, androidm -page.keywords=パーミッション,実行時,プレビュー -page.image={@docRoot}preview/features/images/permissions_check.png -@jd:body - - -<div id="qv-wrapper"> - <div id="qv"> - <h2>クイックビュー</h2> - <ul> - <li>アプリのターゲットが M Preview SDK の場合、インストール時ではなく実行時に、パーミッションを付与するようユーザーに求めます。 -</li> - <li>ユーザーはいつでもアプリの [設定] 画面からパーミッションを取り消すことができます。 -</li> - <li>アプリは実行時に毎回、必要なパーミッションがあることを確認する必要があります。 -</li> - </ul> - - <h2>本書の内容</h2> - <ol> - <li><a href="#overview">概要</a></li> - <li><a href="#coding">実行時のパーミッションのコード</a></li> - <li><a href="#testing">実行時のパーミッションをテストする</a></li> - <li><a href="#best-practices">ベスト プラクティス</a></li> - </ol> - -<!-- - <h2>Related Samples</h2> - <ol> - <li></li> - </ol> ---> - -<!-- - <h2>See also</h2> - <ol> - <li></li> - </ol> ---> - </div> <!-- qv --> -</div> <!-- qv-wrapper --> - - -<p> - M Developer Preview では、アプリをインストールしてアップグレードするユーザーのプロセスを効率化する新しいアプリのパーミッション モデルが導入されました。 -M Preview で実行しているアプリで新しいパーミッション モデルがサポートされている場合、ユーザーはアプリをインストールまたはアップグレードするときにパーミッションを付与する必要はありません。その代わりに、アプリは必要になるとパーミッションを要求し、パーミッションを確認するよう求めるダイアログが表示されます。 - - - - -</p> - -<p> - アプリで新しいパーミッション モデルがサポートされている場合、以前のバージョンの Android を実行している端末で、以前のパーミッション モデルを使ってインストールして実行することもできます。 - - -</p> - -<h2 id="overview"> - 概要 -</h2> - -<p> - M Developer Preview とともに、プラットフォームでは新しいアプリのパーミッション モデルが導入されました。 -この新しいモデルの主要なコンポーネントの概要を次に示します。 -</p> - -<ul> - <li> - <strong>パーミッションを宣言する:</strong> アプリは、以前の Android プラットフォームと同様に、マニフェストで必要なすべてのパーミッションを宣言します。 - - </li> - - <li> - <strong>パーミッション グループ:</strong> パーミッションは、その機能に基づいて<em>パーミッション グループ</em>に分けられます。 -たとえば、<code>CONTACTS</code> パーミッション グループにはユーザーの連絡先とプロフィール情報を読み書きするパーミッションが含まれます。 - - - </li> - - <li> - <p><strong>インストール時に付与される制限付きのパーミッション:</strong> ユーザーがアプリをインストールまたはアップデートするとき、{@link - android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} に該当する、アプリが要求するすべてのパーミッションがアプリに付与されます。 - - - たとえば、目覚まし時計とインターネットのパーミッションは {@link - android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} に該当するため、インストール時に自動的にそれらのパーミッションが付与されます。 - - </p> - - <p>システムは、<a href="#system-apps">システムアプリと署名のパーミッション</a>に記載のとおり、アプリの署名とシステムのパーミッションも付与することがあります。 - -ユーザーは、インストール時にパーミッションを付与するように促すメッセージは表示<em>されません</em>。 -</p> - </li> - - <li> - <strong>実行時にユーザーがパーミッションを付与する:</strong> アプリがパーミッションを要求すると、ユーザーにダイアログが表示されます。その後、アプリのコールバック関数を呼び出して、パーミッションが付与されているかどうかを知らせます。 - -ユーザーがパーミッションを付与する場合、アプリ マニフェストで宣言されたパーミッションの機能領域にあるすべてのパーミッションがアプリに付与されます。 - - - </li> - -</ul> - -<p> - このパーミッション モデルにより、パーミッションを要求する機能に対するアプリの動作方法が変わります。 -このモデルに合わせるために、従う必要のある開発プラクティスの概要を次に示します。 - -</p> - -<ul> - - <li> - <strong>常にパーミッションを確認する:</strong> アプリがパーミッションを必要とするアクションを実行する必要があるとき、まずパーミッションが既にあるかどうかを確認する必要があります。 - -パーミッションがない場合、そのパーミッションを付与するよう要求します。 - - </li> - - <li> - <strong>パーミッションの不足をスムーズに処理する:</strong> アプリに適切なパーミッションが付与されていない場合、エラーが完全に処理される必要があります。 - - たとえば、追加機能に対してのみパーミッションが必要な場合、アプリはその機能を無効にできます。 -アプリが機能するためにパーミッションが必須である場合、アプリはすべての機能を無効にしてパーミッションを付与する必要があることをユーザーに知らせることがあります。 - - - </li> - - <div class="figure" style="width:220px" id="fig-perms-screen"> - <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220"> - <p class="img-caption"> - <strong>図 1.</strong>アプリの [設定] のパーミッション画面。 - </p> - </div> - - <li> - <strong>パーミッションは取り消し可能:</strong> ユーザーはいつでもアプリのパーミッションを取り消すことができます。 -アプリのパーミッションをオフにすると、アプリに通知<em>されません</em>。 -アプリは制限されたアクションを実行する前に、必要なパーミッションがあることを確認する必要があります。 - - </li> -</ul> - -<p class="note"> - <strong>注:</strong> アプリのターゲットが M Developer Preview の場合、新しいパーミッション モデルを使う<em>必要があります</em>。 - -</p> - -<p> - M Developer Preview のローンチ時点では、すべての Google アプリで新しいパーミッション モデルが完全に実装されているわけではありません。 -Google はこれらのアプリを M Developer Preview 中にアップデートして、パーミッションの切り替え設定を完全に実装します。 - - -</p> - -<p class="note"> - <strong>注:</strong> アプリに独自の API サーフェスがある場合、まず呼び出し側にそのデータへのアクセスに必要なパーミッションがあることを確認しないままパーミッションをプロキシしないでください。 - - -</p> - -<h3 id="system-apps"> - システムアプリと署名のパーミッション -</h3> - -<p> - 本来、ユーザーがアプリをインストールするとき、システムはアプリに - {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL - PROTECTION_NORMAL} のみを付与します。ただし、特定の環境では、アプリにより多くのパーミッションが付与されます。 - -</p> - -<ul> - <li>アプリがシステム イメージの一部である場合、そのマニフェストにリストされているすべてのパーミッションが自動的に付与されます。 - - </li> - - <li>アプリが {@link - android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE} に該当するマニフェストでパーミッションを要求し、アプリがこれらのパーミッションを宣言したアプリと同じ証明書で署名される場合、要求しているアプリに対してこれらのパーミッションがインストール時に付与されます。 - - - - </li> -</ul> - -<p> - - -どちらの場合でも、ユーザーはシステムの [<strong>設定</strong>] 画面に移動して [<strong>アプリ</strong>] > <i>[app_name]</i> > [<strong>パーミッション</strong>] を選ぶと、いつでもパーミッションを取り消すことができます。アプリは実行時にパーミッションを継続して確認し、必要に応じて要求する必要があります。 - - -</p> - -<h3 id="compatibility"> - 上方互換と下方互換 -</h3> - -<p> - アプリのターゲットが M Developer Preview 以外の場合、M Preview 端末でも以前のパーミッション モデルを引き続き使います。 -ユーザーがアプリをインストールするとき、ユーザーはアプリのマニフェストでリストされているすべてのパーミッションを付与するように要求されます。 - - -</p> - -<p class="note"> - <strong>注:</strong> M Developer Preview を実行している端末で、ユーザーはアプリの [設定] 画面から従来のアプリを含むすべてのアプリのパーミッションをオフにできます。 - -従来のアプリに対してパーミッションをオフにすると、適切な機能がサイレント状態で無効になります。 -アプリがそのパーミッションを必要とする操作を実行しようとするとき、その操作によって必ずしも例外が発生するとは限りません。 - -代わりに、空のデータセットを返す、エラーを示す、または予期しない動作を返すことがあります。 -たとえば、パーミッションなしでカレンダーを照会すると、メソッドは空のデータセットを返します。 - -</p> - -<p> - M Preview を実行していない端末で新しいパーミッション モデルを使ってアプリをインストールする場合、他のすべてのアプリと同様に扱われ、インストール時に、すべての宣言されたパーミッションを付与するようユーザーに求めます。 - - - -</p> - -<p class="note"> - <strong>注:</strong> Preview リリースの場合、M Preview SDK に SDK の最小バージョンを設定して Preview SDK でコンパイルする必要があります。 -つまり、Developer Preview 中は従来のプラットフォームでそのようなアプリをテストできません。 - - -</p> - -<h3 id="perms-vs-intents">パーミッションとインテント</h3> - -<p> - 多くの場合、アプリがタスクを実行するには 2 つの方法から選択できます。 -アプリ自体が操作を実行するパーミッションを要求できます。 -アプリでインテントを使うようにして、別のアプリがそのタスクを実行するようにすることもできます。 - -</p> - -<p> - たとえば、端末のカメラで写真を撮る機能がアプリに必要だとします。 -アプリは <code>android.permission.CAMERA</code> パーミッションをリクエストでき、それによりアプリが直接カメラにアクセスできるようになります。 - -そのとき、アプリはカメラの API を使ってカメラを制御し、写真を撮ります。 -このアプローチにより、アプリが写真のプロセスを完全に制御し、カメラの UI をアプリに組み込むことができます。 - - -</p> - -<p> - ただし、そのような制御が不要な場合は、{@link - android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} インテントを使うだけで画像を要求できます。 -インテントを開始すると、カメラアプリ(デフォルトのカメラアプリがない場合)を選んでアプリで写真を撮るよう求めるメッセージが表示されます。 - -カメラアプリはアプリの {@link - android.app.Activity#onActivityResult onActivityResult()} メソッドに写真を返します。 -</p> - -<p> - 同様に、ユーザーの連絡先にアクセスするなどして電話をかける必要がある場合、適切なインテントを作成するか、パーミッションを要求して適切なオブジェクトに直接アクセスできます。 - -各アプローチにはメリットとデメリットがあります。 - -</p> - -<p> - パーミッションを使う場合: -</p> - -<ul> - <li>操作を実行するとき、アプリによってユーザーの操作感が完全に制御されます。 -ただし、そのような幅広い制御により、適切な UI を設計する必要があるため、タスクが複雑化します。 - - </li> - - <li>操作を初めて実行するときに、ユーザーに一度だけパーミッションの付与を求めるメッセージが表示されます。 -その後、アプリはユーザーからの介入は必要とせずに操作を実行できます。 -ただし、ユーザーがパーミッションを付与しない(または後でパーミッションを取り消す)場合、アプリは操作を一切実行できなくなります。 - - - </li> -</ul> - -<p> - インテントを使う場合: -</p> - -<ul> - <li>操作用に UI を設計する必要はありません。インテントを処理するアプリでは UI が提供されますが、これはユーザーの操作感を制御できないことを意味します。 - -ユーザーはこれまでに見たことのないアプリと相互操作することになります。 - - </li> - - <li>操作に対してデフォルトのアプリを持たないユーザーの場合、ユーザーにアプリの選択を求めるメッセージが表示されます。ユーザーがデフォルトのハンドラを指定しない場合、操作のたびに別のダイアログで指定する必要があることがあります。 - - - - </li> -</ul> - -<h2 id="coding">実行時のパーミッションのコード</h2> - -<p> - アプリのターゲットが新しい M Developer Preview の場合、新しいパーミッション モデルを使う必要があります。 -つまり、マニフェストで必要なパーミッションを宣言する他に、実行時にパーミッションがあることを確認し、まだパーミッションがない場合にはパーミッションを要求します。 - - - -</p> - -<h3 id="enabling"> - 新しいパーミッション モデルを有効にする -</h3> - -<p> - 新しい M Developer Preview パーミッション モデルを有効にするには、アプリの <code>targetSdkVersion</code> 属性を <code>"MNC"</code> に、<code>compileSdkVersion</code> を <code>"android-MNC"</code> に設定します。 - -このように設定することで、新しいパーミッション機能すべてが有効になります。 - -</p> - -<p> - Preview リリースの場合、<code>minSdkVersion</code> を <code>"MNC"</code> に設定して Preview SDK でコンパイルする必要があります。 - -</p> - -<h3 id="m-only-perm"> - M Preview のみに対するパーミッションの設計 -</h3> - -<p> - アプリ マニフェストで新しい <code><uses-permission-sdk-m></code> 要素を使って、M Developer Preview のみで必要なパーミッションを表示できます。 -このようにしてパーミッションを宣言すると、アプリを以前の端末にインストールする場合はユーザーにメッセージが表示されないか、アプリにパーミッションが付与されません。<code><uses-permission-sdk-m></code> 要素を使うと、新しいパーミッションを追加してインストールをアップデートするときにパーミッションの付与を強制せずにアプリのバージョンがアップデートされます。 - - - - - - -</p> - -<p> - M Developer Preview を使ってアプリが端末で実行されている場合、<code><uses-permission-sdk-m></code> は <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> と同じように動作します。 - - - アプリをインストールするとき、パーミッションの付与を求めるメッセージは表示されず、アプリは必要なときにパーミッションを要求します。 - -</p> - -<h3 id="prompting"> - パーミッションについてのダイアログを表示する -</h3> - -<p> - アプリで新しい M Developer Preview パーミッション モデルが使われている場合、M Preview を実行している端末でアプリを初めて起動するとき、すべての権限を付与する必要はありません。 - -その代わりに、アプリは必要なときにパーミッションを要求します。 -アプリがパーミッションを要求すると、ユーザーにダイアログが表示されます。 - -</p> - -<p> - SDK 22 以降がインストールされた端末でアプリを実行する場合、アプリでは以前のパーミッション モデルが使われます。 -ユーザーがアプリをインストールすると、アプリがそのマニフェストで要求するすべてのパーミッションの付与を求めるメッセージが表示されます。ただし、<code><uses-permission-sdk-m></code> というラベルの付いたパーミッションは例外です。 - - -</p> - -<h4 id="check-platform">アプリが実行されているプラットフォームを確認する</h4> - -<p> - このパーミッション モデルは、M Developer Preview を実行している端末でのみサポートされます。 -これらのメソッドのいずれかを呼び出す前に、アプリは {@link android.os.Build.VERSION#CODENAME - Build.VERSION.CODENAME} の値を確認してどのプラットフォーム上で実行されているのかを確認する必要があります。 - -端末で M Developer Preview が実行されている場合、{@link android.os.Build.VERSION#CODENAME CODENAME} は <code>"MNC"</code> です。 - -</p> - -<h4 id="check-for-permission">アプリに必要なパーミッションがあるかどうかを確認する</h4> - -<p>ユーザーがパーミッションを要求する動作を行うと、アプリは現在この操作を実行するためのパーミッションがあるかどうかを確認します。 - - -確認するために、アプリは <code>Context.checkSelfPermission(<i>permission_name</i>)</code> を呼び出します。ユーザーが既にパーミッションを付与していることをアプリが認識している場合でも、ユーザーはいつでもアプリのパーミッションを取り消すことができるため、この確認が行われます。 - - -たとえば、ユーザーがアプリを使って写真を撮る場合、アプリは <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code> を呼び出します。 - -</p> - -<p class="table-caption" id="permission-groups"> - <strong>表 1.</strong>パーミッションとパーミッション グループ。</p> -<table> - <tr> - <th scope="col">パーミッション グループ</th> - <th scope="col">パーミッション</th> - </tr> - - <tr> - <td><code>android.permission-group.CALENDAR</code></td> - <td> - <ul> - <li> - <code>android.permission.READ_CALENDAR</code> - </li> - </ul> - <ul> - <li> - <code>android.permission.WRITE_CALENDAR</code> - </li> - </ul> - </td> - </tr> - - <tr> - <td><code>android.permission-group.CAMERA</code></td> - <td> - <ul> - <li> - <code>android.permission.CAMERA</code> - </li> - </ul> - </td> - </tr> - - <tr> - <td><code>android.permission-group.CONTACTS</code></td> - <td> - <ul> - <li> - <code>android.permission.READ_CONTACTS</code> - </li> - <li> - <code>android.permission.WRITE_CONTACTS</code> - </li> - <li> - <code>android.permission.READ_PROFILE</code> - </li> - <li> - <code>android.permission.WRITE_PROFILE</code> - </li> - </ul> - </td> - </tr> - - <tr> - <td><code>android.permission-group.LOCATION</code></td> - <td> - <ul> - <li> - <code>android.permission.ACCESS_FINE_LOCATION</code> - </li> - <li> - <code>android.permission.ACCESS_COARSE_LOCATION</code> - </li> - </ul> - </td> - </tr> - - <tr> - <td><code>android.permission-group.MICROPHONE</code></td> - <td> - <ul> - <li> - <code>android.permission.RECORD_AUDIO</code> - </li> - </ul> - </td> - </tr> - - <tr> - <td><code>android.permission-group.PHONE</code></td> - <td> - <ul> - <li> - <code>android.permission.READ_PHONE_STATE</code> - </li> - <li> - <code>android.permission.CALL_PHONE</code> - </li> - <li> - <code>android.permission.READ_CALL_LOG</code> - </li> - <li> - <code>android.permission.WRITE_CALL_LOG</code> - </li> - <li> - <code>com.android.voicemail.permission.ADD_VOICEMAIL</code> - </li> - <li> - <code>android.permission.USE_SIP</code> - </li> - <li> - <code>android.permission.PROCESS_OUTGOING_CALLS</code> - </li> - </ul> - </td> - </tr> - - <tr> - <td><code>android.permission-group.SENSORS</code></td> - <td> - <ul> - <li> - <code>android.permission.BODY_SENSORS</code> - </li> - </ul> - <ul> - <li> - <code>android.permission.USE_FINGERPRINT</code> - </li> - </ul> - </td> - </tr> - - <tr> - <td><code>android.permission-group.SMS</code></td> - <td> - <ul> - <li> - <code>android.permission.SEND_SMS</code> - </li> - <li> - <code>android.permission.RECEIVE_SMS</code> - </li> - <li> - <code>android.permission.READ_SMS</code> - </li> - <li> - <code>android.permission.RECEIVE_WAP_PUSH</code> - </li> - <li> - <code>android.permission.RECEIVE_MMS</code> - </li> - <li> - <code>android.permission.READ_CELL_BROADCASTS</code> - </li> - </ul> - </td> - </tr> - -</table> - -<h4 id="request-permissions">必要に応じてパーミッションを要求する</h4> - -<p>アプリに必要なパーミッションがない場合、アプリは <code>Activity.requestPermissions(String[], int)</code> メソッドを呼び出して適切なパーミッションを要求します。 - -アプリは必要なパーミッションと整数の「要求コード」を渡します。 - - このメソッドは非同期に機能します。このメソッドはすぐに返され、ユーザーがダイアログ ボックスに応答した後、システムはその結果と一緒にアプリのコールバック メソッドを呼び出し、アプリが <code>requestPermissions()</code> に渡すのと同じ「要求コード」を渡します。 - - -</p> - - <p>次のコードは、ユーザーの連絡先を読み込むパーミッションがアプリにあることを確認し、必要に応じてパーミッションを要求します。 -</p> - -<pre> -if (checkSelfPermission(Manifest.permission.READ_CONTACTS) - != PackageManager.PERMISSION_GRANTED) { - requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, - MY_PERMISSIONS_REQUEST_READ_CONTACTS); - - // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an - // app-defined int constant - - return; -} -</pre> - -<h4 id="handle-response">パーミッションの要求への応答を処理する</h4> - -<p> - アプリがパーミッションを要求すると、システムによってダイアログ ボックスが表示されます。 -ユーザーが応答すると、システムはアプリの <code>Activity.onRequestPermissionsResult(int, String[], int[])</code> を呼び出し、ユーザーの応答を渡します。 - -アプリはそのメソッドをオーバーライドする必要があります。コールバックには開発者が <code>requestPermissions()</code> に渡したのと同じ要求コードが渡されます。 - -たとえばアプリが <code>READ_CONTACTS</code> アクセスを要求する場合、次のコールバック メソッドが含まれる可能性があります。 - - -</p> - -<pre> -@Override -public void onRequestPermissionsResult(int requestCode, - String permissions[], int[] grantResults) { - switch (requestCode) { - case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - - // permission was granted, yay! do the - // calendar task you need to do. - - } else { - - // permission denied, boo! Disable the - // functionality that depends on this permission. - } - return; - } - - // other 'switch' lines to check for other - // permissions this app might request - } -} -</pre> - - <p>ユーザーがパーミッションを付与すると、システムは、機能領域のアプリ マニフェストがリストするすべてのパーミッションを付与します。 -ユーザーが要求を拒否する場合は、適切なアクションを取ってください。 -たとえば、このパーミッションに応じて、すべてのメニュー アクションを無効にできます。 - - </li> -</p> - -<p> - ユーザーにパーミッションの付与を確認するとき、ユーザーにそのパーミッションについて再度確認しないようにするオプションがあります。 -この場合、アプリが <code>requestPermissions()</code> を使ってパーミッションを確認すると、システムはその要求をすぐに拒否します。 - -この場合、システムはユーザーが要求を再度明示的に拒否する場合と同様に <code>onRequestPermissionsResult()</code> を呼び出します。 - -このため、アプリではユーザーとの直接的なやり取りが発生することが想定されません。 - -</p> - -<h2 id="testing">実行時のパーミッションをテストする</h2> - - -<p> - アプリのターゲットが M Developer Preview の場合、パーミッションが正しく処理されることをテストする必要があります。 -アプリ起動時に特定のパーミッションがアプリにあることは想定できません。 -アプリが初めて起動されるとき、パーミッションがない可能性が高く、ユーザーはいつでもパーミッションを取り消すまたは復元できます。 - - -</p> - -<p> - アプリがすべてのパーミッションの状況下で確実に正しく動作することをテストしてください。 -M Preview SDK とともに、新しい <a href="{@docRoot}tools/help/adb.html">Android デバッグ ブリッジ(adb)</a>コマンドが導入され、試す必要のあるあらゆるパーミッション設定でアプリをテストできます。 - - - -</p> - -<h3> - 新しい adb コマンドとオプション -</h3> - -<p> - M Preview SDK Platform-tools では、アプリがパーミッションをどう処理するかをテストするための、いくつかの新しいコマンドが導入されました - -</p> - -<h4> - パーミッション付きでインストールする -</h4> - -<p> - <a href="{@docRoot}tools/help/adb.html#move"><code>adb - install</code></a> コマンドの新しい <code>-g</code> オプションを使ってアプリをインストールし、そのマニフェストにリストされるすべてのパーミッションを付与できます。 - -</p> - -<pre class="no-pretty-print"> -$ adb install -g <path_to_apk> -</pre> - -<h4> - パーミッションの付与と取り消し -</h4> - -<p> - 新しい ADB <a href="{@docRoot}tools/help/adb.html#pm">Package Manager(pm)</a>コマンドを使って、インストールされているアプリにパーミッションを付与したり取り消したりできます。この機能は自動化されたテストに役立ちます。 - - -</p> - -<p> - パーミッションを付与するには、Package Manager の <code>grant</code> コマンドを使います。 -</p> - -<pre class="no-pretty-print"> -$ adb pm grant <package_name> <permission_name> -</pre> - -<p> - たとえば、com.example.myapp パッケージ パーミッションを付与してオーディオを録音するには、このコマンドを使います。 - -</p> - -<pre class="no-pretty-print"> -$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO -</pre> - -<p> - パーミッションを取り消すには、Package Manager の <code>revoke</code> コマンドを使います。 -</p> - -<pre class="no-pretty-print"> -$ adb pm revoke <package_name> <permission_name> -</pre> - -<h2 id="best-practices">ベスト プラクティス</h2> - -<p> - 新しいパーミッション モデルにより、ユーザーはよりスムーズな操作感を得られ、アプリを簡単にインストールできるようになり、アプリが実行している内容に満足します。 - -新しいモデルを最大限に活用するために、次のベスト プラクティスをお勧めします。 - -</p> - - -<h3 id="bp-what-you-need">必要なパーミッションのみを要求する</h3> - -<p> - パーミッションを要求するたびに、ユーザーに決定するよう強制します。 - ユーザーが要求を却下すると、アプリの機能が低下します。 - これらの要求回数は最小限にしてください。 -</p> - -<p> - たとえば、アプリがパーミッションを要求する代わりに、<a href="{@docRoot}guide/components/intents-filters.html">インテント</a>を使って必要な機能を取得できる場合がよくあります。 - -アプリが携帯電話のカメラで写真を撮る必要がある場合、そのアプリでは {@link - android.provider.MediaStore#ACTION_IMAGE_CAPTURE - MediaStore.ACTION_IMAGE_CAPTURE} インテントを使用できます。 -アプリがインテントを実行すると、写真を撮るためのインストール済みのカメラアプリを選ぶようユーザーに促します。 - - -</p> - -<h3 id="bp-dont-overwhelm"> - ユーザーを疲れさせない -</h3> - -<p> - ユーザーにパーミッションをたくさん要求すると、ユーザーを疲れさせてしまい、アプリが終了される原因になります。代わりに、ユーザーには必要なパーミッションのみを要求してください。 - - -</p> - -<p> - アプリ対して 1 つ以上のパーミッションが必須である場合もあります。その場合は、アプリの起動後すぐに、すべてのパーミッションを要求することが合理的である場合があります。 - -たとえば、カメラアプリを作成する場合、アプリは端末のカメラにアクセスする必要があります。 -アプリを初めて起動するときにカメラの使用についてのパーミッションを求められても驚かないはずです。 - -ただし、同じアプリにユーザーの連絡先と写真を共有する機能もある場合は、最初の起動時にパーミッションを要求<em>しない</em>方が無難です。 - -その代わりに、ユーザーが「共有」機能を使うまで待ち、そのときにパーミッションを要求します。 - -</p> - -<p> - アプリにチュートリアルが含まれる場合は、チュートリアルのシーケンスの最後で、アプリに必須のパーミッションを要求する方が合理的です。 - -</p> - -<h3 id="bp-explain"> - パーミッションが必要な理由を説明する -</h3> - -<p> - <code>requestPermissions()</code> を呼び出すとき、システムによって表示されるパーミッション ダイアログにはアプリが必要としているパーミッションは表示されますが、理由は表示されません。 - -これによりユーザーが困惑する場合もあります。 - <code>requestPermissions()</code> を呼び出す前に、アプリがパーミッションを必要としている理由をユーザーに説明するのはよい方法です。 - -</p> - -<p> - たとえば、カメラアプリでは、位置情報サービスを使って写真に位置情報タグを付けられるようにする場合があります。 -通常のユーザーは、写真に位置情報が含まれる場合があることを認識していない可能性があり、なぜカメラアプリで位置情報が必要なのか困惑する可能性があります。 - -この場合、アプリが <code>requestPermissions()</code> を呼び出す<em>前</em>に、この機能についてユーザーに知らせることをお勧めします。 - - -</p> - -<p> - その方法として、これらの要求をアプリのチュートリアルに組み込むこともできます。チュートリアルでは、アプリの各機能を順番に表示できるので、必要なパーミッションを説明できます。 - -たとえば、カメラアプリのチュートリアルでは、「連絡先と写真を共有する」機能について説明し、ユーザーの連絡先を参照するためにアプリにパーミッションが必要であることをユーザーに知らせることができます。 - - -その後、アプリは <code>requestPermissions()</code> を呼び出して、ユーザーにそのアクセスを求めることができます。 -もちろん、すべてのユーザーがチュートリアルに従うわけではないため、アプリの通常操作中にパーミッションを確認して要求することも必要です。 - - -</p> diff --git a/docs/html-intl/intl/ja/preview/index.jd b/docs/html-intl/intl/ja/preview/index.jd deleted file mode 100644 index 2e84aa3bbabc..000000000000 --- a/docs/html-intl/intl/ja/preview/index.jd +++ /dev/null @@ -1,71 +0,0 @@ -page.title=Android M Developer Preview -page.tags="preview", -meta.tags="preview, M preview", androidm -fullpage=true -section.landing=true -header.hide=1 -footer.hide=1 -@jd:body - -<section class="dac-expand dac-hero dac-light" > - <div class="wrap"> - <div class="cols dac-hero-content"> - <div class="col-9of16 col-push-7of16 dac-hero-figure"> - <img class="dac-hero-image" src="{@docRoot}images/home/devices-hero_620px_2x.png" srcset="{@docRoot}images/home/devices-hero_620px.png 1x, - {@docRoot}images/home/devices-hero_620px_2x.png 2x"> - </div> - <div class="col-7of16 col-pull-9of16"> - <h1 class="dac-hero-title">Android M Developer Preview</h1> - <p class="dac-hero-description"> - 次期バージョンの Android に向けて準備しましょう。Nexus 5、6、9、Nexus Player でアプリをテストします。 -<strong>実行時パーミッション</strong>、 <strong>Doze</strong>、<strong>App Standby</strong> 省電力機能、新しい <strong>サポート テクノロジー</strong>などの新機能をご覧ください。 - - - </p> - - <a class="dac-hero-cta" href="{@docRoot}preview/overview.html"> - <span class="dac-sprite dac-auto-chevron"></span> - スタートガイド - </a><br> - - <a class="dac-hero-cta" href="{@docRoot}preview/support.html"> - <span class="dac-sprite dac-auto-chevron"></span> - Developer Preview 3 (final SDK)</a> - </div> - </div> - <div class="dac-section dac-small"> - <div class="resource-widget resource-flow-layout col-16" - data-query="collection:preview/landing/resources" - data-cardSizes="6x2" - data-maxResults="6"></div> - </div> - </div> -</section> - -<section class="dac-section dac-gray"><div class="wrap"> - <h1 class="dac-section-title">リソース</h1> - <div class="dac-section-subtitle"> - Android M 向けにアプリを用意する際に役立つ必須情報をご提供します。 - </div> - - <div class="resource-widget resource-flow-layout col-16" - data-query="collection:preview/landing/more" - data-cardSizes="6x6" - data-maxResults="16"></div> - - <ul class="dac-section-links"> - <li class="dac-section-link"> - <a href="https://code.google.com/p/android-developer-preview/"> - <span class="dac-sprite dac-auto-chevron"></span> - 問題の報告 - </a> - </li> - <li class="dac-section-link"><a href="http://g.co/dev/AndroidMDevPreview"> - <span class="dac-sprite dac-auto-chevron"></span> - Join G+ コミュニティ - </a> - </li> - </ul> - </div> -</section> - diff --git a/docs/html-intl/intl/ja/preview/license.jd b/docs/html-intl/intl/ja/preview/license.jd deleted file mode 100644 index 1e29b524a0ca..000000000000 --- a/docs/html-intl/intl/ja/preview/license.jd +++ /dev/null @@ -1,143 +0,0 @@ -page.title=使用許諾契約 - -@jd:body - -<p> -Android SDK Preview をインストールする前に、次の利用規約に同意する必要があります。 -以下に記載するとおり、これは、Android SDK のプレビュー バージョンであり、変更される可能性があります。デベロッパーご自身の責任においてご使用ください。Android SDK Preview は安定したリリースではなく、お使いのコンピュータ システム、端末、データに深刻な影響を与える可能性のあるエラーまたは欠陥が含まれている場合があります。 -</p> - -<p> -以下は、Android SDK Preview の使用許諾契約です(以下「本契約」)。 -</p> -<div class="sdk-terms" style="height:auto;border:0;padding:0;width:700px"> -1.はじめに - -1.1 Android SDK Preview(以下、本契約で「Preview」という。具体的には利用可能な場合には Android システム ファイル、パッケージ型 API、Preview ライブラリ ファイルを含む)は、本契約の規定に従ってライセンス許可されます。本契約では、デベロッパーの Preview の使用に関して、デベロッパーと Google の間で法的拘束力のある契約を結びます。 - -1.2 「Android」とは、Android オープン ソース プロジェクト(http://source.android.com/ にて随時更新)にて利用可能な、端末向けの Android ソフトウェア スタックを意味します。 - -1.3 「Google」とは、1600 Amphitheatre Parkway, Mountain View, CA 94043, United States に主たる事業所を有するデラウェア州法人である Google Inc. を意味します。 - -2.本契約の同意 - -2.1 Preview を使用するには、まず本契約に同意する必要があります。本契約に同意しない場合は Preview を使用できません。 - -2.2 同意するかまたは Preview を使用するためにクリックすると、本契約に同意したことになります。 - -2.3 米国またはその他の国(デベロッパーが居住している国かまたはデベロッパーが Preview を使用する国を含む)の法律により Preview の使用を禁止されている人である場合、Preview を使用することも、使用許諾契約に同意することもできません。 - -2.4 雇用主またはその他の事業体を代表または代理して本契約に拘束されることに同意し Preview を企業または組織の内部で使用する場合、担当者の雇用主またはその他の事業体を本契約に法的に拘束する完全な法的権限を有していることを表明および保証するものとします。担当者が必要な権限を有していない場合は、担当者の雇用主またはその他の事業体を代表または代理して、本契約に同意することも、Preview を使用することもできません。 - -3.Google Preview ライセンス - -3.1 本契約の規定に従い、Google は Android プラットフォーム上で実行するアプリケーションの開発に Preview を個人的にもしくは企業または組織の内部で使用するための、ロイヤリティ フリーな、譲渡不可で、非排他的な、サブライセンス不可の、限定された、取り消し可能なライセンスを付与するものとします。 - -3.2 Preview に関するすべての法的権利、所有権、利益(Preview に含まれる知的財産権を含む)は Google またはサードパーティが所有するものとします。「知的財産権」とは、特許法、著作権法、営業秘密法、商標法、不当競争防止法に基づいて発生するすべての権利、およびその他のすべての所有権を意味します。デベロッパーに明示的に付与されていない権利は、すべて Google が所有します。 - -3.3 本契約で明示的に許可されている目的以外においては、Preview を使用できません。当該のサードパーティのライセンスで必要とされる場合を除き、デベロッパーは、(a) Preview または Preview の一部をコピー(バックアップ目的を除く)、修正、改造、再配布、逆コンパイル、リバース エンジニアリング、逆アセンブルまたは派生物の作成、または(b)モバイル ハンドセットまたは個人用 PC 以外のハードウェア端末への Preview の読み込み、Preview と他のソフトウェアとの結合、または Preview の一部を組み込んだソフトウェアや端末の配布はできません。 - -3.4 デベロッパーは、Android の断片化につながるような行為をしないことに同意します。これには、Preview から派生したソフトウェア開発キットの配布、作成への参加、宣伝を含みます(ただし必ずしもこれらには限定されません)。 - -3.5 オープンソース ソフトウェア ライセンス下でライセンス付与された Preview のコンポーネントの使用、複製、配布は、本契約ではなく、そのオープンソース ソフトウェアのライセンスに準拠するものとします。デベロッパーは、許諾されるすべての権利下で、そのようなオープンソース ソフトウェア ライセンスに対して、優良ライセンシーのままでいることに同意し、そのような権利を終了、停止、または違反する可能性のあるいかなる行為も差し控えることに同意するものとします。 - -3.6 デベロッパーは、Google が提供する Preview の形式および性質は事前の通知なしに変更される場合があり、今後リリースされる Preview のバージョンでは、以前のバージョンの Preview で開発されたアプリケーションとの互換性がない可能性があることに同意します。デベロッパーは、Google が事前の通知なく、Google の単独の裁量でデベロッパーまたはユーザーへの Preview(または Preview 内の一部の機能)の提供を(恒久的または一時的に)停止する場合があることに同意します。 - -3.7 本契約のいかなる部分も、Google のいかなる商標名、商標、サービスマーク、ロゴ、ドメイン名、またはその他のブランド識別表示を使用する権利もデベロッパーに付与するものではありません。 - -3.8 デベロッパーは、Preview に添付または収録されているすべての知的財産権に関する通知(著作権および商標の通知を含む)の削除、隠ぺい、改ざんを行わないことに同意します。 - -4.デベロッパーによる Preview の使用 - -4.1 Google は、本契約に基づき Preview を使用してデベロッパーが開発したソフトウェア アプリケーションに関して、デベロッパー(またはデベロッパーのライセンサー)からいかなる権利、所有権、または利益(当該アプリケーションに含まれる知的財産権を含む)も取得するものではないことに同意します。 - -4.2 デベロッパーは、Preview を(a)本契約、および(b)該当する司法管轄区における適用される法律、規則、または一般に認められた慣行またはガイドライン(米国またはその他の該当国におけるデータまたはソフトウェアの輸出入に関する法律を含む)で認められている目的にのみ使用することに同意します。 - -4.3 Preview を使用してアプリケーションを開発する場合、デベロッパーはユーザーのプライバシーおよび法的権利を保護することに同意します。ユーザーからデベロッパーにユーザー名、パスワード、またはその他のログイン情報または個人情報が提供される場合、デベロッパーは、情報がデベロッパーのアプリケーションに提供されることをユーザーに認識させ、当該ユーザーについてプライバシーに関する法的に十分な通知および保護を行わなければなりません。デベロッパーのアプリケーションに個人情報または秘密情報が保存される場合、この保存は保護された方法で行われなければなりません。ユーザーからデベロッパーのアプリケーションに Google アカウントの情報が提供された場合、デベロッパーのアプリケーションでは、ユーザーが許可したタイミングで、かつユーザーが許可した限定された目的にのみ、当該情報を使用してユーザーの Google アカウントにアクセスすることが認められるものとします。 - -4.4 デベロッパーは、Preview に関して、第三者(Google、およびあらゆる携帯電話会社を含むが、これらに限定されない)のサーバー、ネットワーク、またはその他の財産またはサービスへの妨害、中断、損害、または許可されていない態様でのアクセスとなる行為(そのような行為に該当する対象製品の開発または販売 / 配布を含む)に関与しないことに同意します。 - -4.5 デベロッパーは、デベロッパーが Android および Android のアプリケーションを介して作成、送信、表示するデータ、コンテンツ、リソース、および自身の行為の結果(Google に発生する可能性のあるあらゆる損失および損害を含む)について、自身が単独で責任を負うこと(および Google がこれについてデベロッパーまたはいかなる第三者に対しても一切責任を負わないこと)に同意します。 - -4.6 デベロッパーは、本契約、適用される第三者の契約もしくは利用規約、または適用される法律もしくは規則に基づく自身の義務に違反したこと、および当該違反の結果(Google または第三者に発生したあらゆる損失および損害を含む)について、自身が単独で責任を負うこと(および Google がこれについてデベロッパーまたはいかなる第三者に対しても一切責任を負わないこと)に同意します。 - -4.7 Preview は開発中であり、デベロッパーによるテスティングやフィードバックは開発プロセスの重要な一部となります。デベロッパーは、Preview の使用により、一部の機能の実装が開発中であると認識し、Preview が安定したリリースの完全な機能性を持つことに依存すべきでないことを認識するものとします。本 Preview は、公式の Android SDK のリリース後はサポート対象でなくなるため、デベロッパーは、Preview を使用するいかなるアプリケーションも公然と配布または引き渡さないことに同意するものとします。 - -5.デベロッパーの資格情報 - -5.1 デベロッパーは、Google が発行した、またはデベロッパー自身で選択した、自身のデベロッパー用資格情報の秘密を保持する責任を負うこと、および自身のデベロッパー用資格情報のもとで開発されたすべてのアプリケーションについて単独で責任を負うことに同意します。 - -6.プライバシーおよび情報 - -6.1 Google は、Preview の継続的な技術革新と改良のために、ソフトウェアから特定の使用状況統計情報(一意識別子、関連する IP アドレス、ソフトウェアのバージョン番号、Preview のどのツール/サービスがどのように使用されているかに関する情報を含むが、これらに限定されない)を収集できます。この情報が収集される前に、Preview に通知が表示され、デベロッパーの同意が求められます。デベロッパーが同意しない場合は、情報は収集されません。 - -6.2 収集されるデータは、Preview の改良のために集約された形で精査され、Google のプライバシー ポリシー(http://www.google.com/policies/privacy/)に従って管理されます。 - -7.第三者のアプリケーション - -7.1 デベロッパーが、Preview を使用して第三者が開発したアプリケーションを実行する、あるいは第三者から提供されたデータ、コンテンツ、リソースにアクセスする場合、デベロッパーは、Google がそれらのアプリケーション、データ、コンテンツ、リソースについて責任を負わないことに同意します。デベロッパーは、そのような第三者のアプリケーションを介してアクセスするすべてのデータ、コンテンツ、リソースについては、それらを生成した者が単独で責任を負うものであり、Google はそれらの第三者のアプリケーション、データ、コンテンツ、またはリソースの使用もしくはアクセスによって生じたあらゆる損失および損害について一切責任を負わないことを理解します。 - -7.2 デベロッパーは、そのような第三者のアプリケーションを介して表示されるデータ、コンテンツ、リソースは、提供者(あるいは代理の第三者または事業体)が所有する知的財産権で保護されている場合があることを認識するものとします。デベロッパーは、当該所有者からの明確な許可がない限り、それらのデータ、コンテンツ、リソース(全体または一部)の変更、貸与、賃貸、担保、配布または派生物の作成を行うことはできません。 - -7.3 デベロッパーは、そのような第三者のアプリケーション、データ、コンテンツまたはリソースの使用が、デベロッパーと当該第三者間の別の規約に従うものであることを認識するものとします。 - -8.Google API の使用 - -8.1 Google API - -8.1.1 API を使用して Google からデータを取得する場合、デベロッパーは、そのデータは、Google またはデータを提供する事業体(あるいは代理の第三者または事業体)が所有する知的財産権で保護されている場合があることを認識するものとします。そのような API の使用は追加の利用規約に従うものとします。デベロッパーは、当該の利用規約による許可がない限り、そのデータ(全体または一部)の変更、貸与、賃貸、担保、配布または派生物の作成を行うことはできません。 - -8.1.2 デベロッパーは、API を使用して Google からユーザーのデータを取得する場合、ユーザーが明示的に同意した場合のみ、およびユーザーが許可したタイミングとその目的にのみ、データを取得できることを理解し、同意します。 - -9.本契約の終了 - -9.1 本契約は、下記の規定に従ってデベロッパーまたは Google のいずれかによって解約されるまで、継続して適用されるものとします。 - -9.2 デベロッパーが本契約の解約を希望する場合は、Preview および関連するデベロッパー資格情報の使用を停止することで、契約を終了するものとします。 - -9.3 Google は、理由の有無にかかわらず、書面で通知することでいつでもデベロッパーとの本契約を解約することができます。 - -9.4 本契約は事前の通知またはその他の措置なく、次のうち早い方に自動的に終了します。 -(A)Google が、デベロッパーが居住している国またはデベロッパーがサービスを使用する国での Preview または Preview の一部の配布を停止したとき。 -(B)Google が Android SDK の最終バージョンをリリースしたとき。 - -9.5 本契約が終了すると、本契約で付与されていたライセンスは終了し、デベロッパーは速やかに Preview のすべての使用を停止するものとし、第 10 条、第 11 条、第 12 条、第 14 条の規定は無期限に効力を有するものとします。 - -10.免責事項 - -10.1 デベロッパーは、デベロッパーによる Preview の使用はデベロッパー自身の責任において行うものであること、および Preview は「現状有姿」かつ「提供可能な限りにおいて」、Google からのいかなる種類の保証もなく提供されるものであることを明示的に理解し、これに同意します。 - -10.2 デベロッパーによる Preview および Preview の使用を通じてダウンロードまたはその他の方法で取得されたマテリアルの使用は、デベロッパー自身の裁量および責任において行うものであり、当該使用の結果として生じるデベロッパーのコンピュータ システムもしくはその他の端末への損害またはデータの喪失についての責任はデベロッパーが単独で負います。前述を制限することなく、Preview は安定したリリースではなく、コンピュータやその他の端末の利用の完全な回復不可能な損失を含む、重大な損害を引き起こす可能性のあるエラー、欠陥、およびセキュリティ上の脆弱性が含まれている可能性があることを理解します。 - -10.3 Google はまた、商品性、特定目的への適合性、および権利侵害がないことの黙示的な保証および条件を含む(ただしこれらに限定されない)、明示的か黙示的かを問わずあらゆる種類のすべての保証および条件を明示的に否定します。 - -11.責任の制限 - -11.1 デベロッパーは、Google、その子会社および関連会社、ならびにそのライセンサーが、デベロッパーに発生した直接損害、間接損害、偶発的損害、特別損害、結果的損害、または懲罰的損害(データの喪失を含む)について、Google またはその代表者が当該損失が発生する可能性について告知されていたかどうか、または知っていたはずであるかどうかにかかわらず、いかなる責任法理のもとでもデベロッパーに対して責任を負わないことを明示的に理解し、これに同意します。 - -12.補償 - -12.1 法律で認められる最大限の範囲内において、デベロッパーは、(a)デベロッパーが Preview を使用したこと、および(b)デベロッパーが Preview で開発したアプリケーションが他者のいかなる知的財産権を侵害していること、または他者の名誉を毀損している、もしくは他者のパブリシティ権もしくはプライバシー権を侵害していること、および(c)デベロッパーが本契約に違反したことから発生したあらゆる申し立て、普通法上の訴訟、衡平法上の訴訟、または法的手続き、ならびにあらゆる損失、責任、損害、費用、および経費(合理的な弁護士報酬を含む)について、Google、その関連会社、ならびに当該各社の取締役、役員、従業員、代理人を防御し、補償し、免責することに同意します。 - -13.契約の変更 - -13.1 Google は、Preview の新しいバージョンを配布することにより、いつでも本契約を変更することができます。変更が生じた場合、Google は、Preview の提供ウェブサイト上に使用許諾契約の改訂版を公開します。 - -14.法的一般条項 - -14.1 本契約は、デベロッパーと Google の間の法的な合意のすべてを表し、デベロッパーによる Preview の使用(別の契約下で Google が提供するサービスを除く)に適用され、Preview に関するデベロッパーと Google の間のあらゆる事前の合意に完全に取って代わるものです。 - -14.2 デベロッパーは、Google が本契約に定める(または適用される法律のもとで Google が享受できる)法的な権利または救済措置を行使または執行しなかった場合でも、Google の権利が正式に放棄されたとはみなされないこと、および Google が以後も引き続き当該権利および救済措置を行使または執行できることに同意します。 - -14.3 本件について判断を下す管轄権を有する司法裁判所によって、本契約のいずれかの条項が無効と判断された場合、当該条項は、本契約の残りの部分に影響を与えることなく本契約から削除されるものとします。本契約の残りの条項は、以後も引き続き有効かつ執行可能であるものとします。 - -14.4 デベロッパーは、Google が親会社となっている各グループ企業が、本契約の第三受益者となること、および当該企業が、当該企業に利益(または受益権)を付与する本契約の条項を直接執行する、また当該条項に依拠する権利を有することを了承し、これに同意します。上記以外のいかなる人または法人も、本契約の第三受益者とはならないものとします。 - -14.5 輸出規制。Preview は、米国輸出管理法令の対象です。デベロッパーは、Preview に適用されるすべての国内および国際の輸出管理法令に従わなければなりません。これらの法律には、仕向け地、ユーザー、および最終用途に関する制限が含まれます。 - -14.6 デベロッパーは、Google から事前に書面で承認を得ずに、本契約を譲渡または移転することはできません。また、そのような承認を得ずに計画された譲渡はすべて無効になります。デベロッパーは、Google から事前に書面で承認を得ずに、本契約に基づく自身の責任または義務を他者に委任してはなりません。 - -14.7 本契約あるいは本契約に基づくデベロッパーと Google の関係から発生または関連するすべての申し立ては、米国カリフォルニア州の抵触法を除いて、カリフォルニア州法に準拠するものとします。デベロッパーおよび Google は、本契約あるいは本契約に基づくデベロッパーと Google の関係から発生または関連する法的事項の解決について、米国カリフォルニア州サンタクララ郡に所在の連邦裁判所または州立裁判所が専属管轄権を有することに合意します。上記にかかわらず、デベロッパーは、Google が任意の司法管轄区において差し止め命令による救済(または同等の緊急法的救済)を求める申し立てを行うことが認められることに同意します。 - - -</div>
\ No newline at end of file diff --git a/docs/html-intl/intl/ja/preview/overview.jd b/docs/html-intl/intl/ja/preview/overview.jd deleted file mode 100644 index c5390ef0ba70..000000000000 --- a/docs/html-intl/intl/ja/preview/overview.jd +++ /dev/null @@ -1,389 +0,0 @@ -page.title=プログラム概要 -page.metaDescription=Android M Developer Preview では、Android の次のバージョンでアプリをテストして最適化するためのすべてを備えています。 -page.image=images/cards/card-preview_16-9_2x.png -page.tags="preview", "developer", "android" - -@jd:body - -<div class="cols" style= -"background-color:#ffebc3; padding: 5px 0;margin-bottom:1em; text-align:center;"> -<h3> - Developer Preview 2 is now available - </h3> - - <ul class="dac-section-links"> - <li class="dac-section-link"> - <a href="{@docRoot}preview/support.html#preview2-notes"> - <span class="dac-sprite dac-auto-chevron"></span> - Read the Notes</a> - </li> - - <li class="dac-section-link"> - <a href="{@docRoot}preview/support.html#preview2-get"> - <span class="dac-sprite dac-auto-chevron"></span> - Get the Update</a> - </li> - - <li class="dac-section-link"> - <a href="https://code.google.com/p/android-developer-preview/"> - <span class="dac-sprite dac-auto-chevron"></span> - Report Issues</a> - </li> - </ul> -</div> - -<p> - <strong>Android M Developer Preview</strong> では、Android の次のバージョンでアプリをテストして最適化するためのすべてを備えています。 - -M Developer Preview ツールをダウンロードするだけで、無料ですぐにご利用いただけます。 - -</p> - -<div style="background-color:#eceff1;padding:1em;"> -<div class="wrap"> - <div class="cols"> - <div class="col-4of12"> - <h5> - ハードウェアとエミュレータのシステム イメージ - </h5> - - <p> - Nexus 5、6、9、Nexus Player(TV 向け)やエミュレータでアプリをテストしましょう。 - - </p> - </div> - - <div class="col-4of12"> - <h5> - 最新プラットフォーム コード - </h5> - - <p> - プレビューで複数のアップデートが提供されますので、最新プラットフォームの変更に応じてテストできます。 - - </p> - </div> - - <div class="col-4of12"> - <h5> - OTA でのアップデート - </h5> - - <p> - デバイスに初期プレビューをコピーしたら、無線経由でアップデートを入手できます。 - - </p> - </div> - </div> - - <div class="cols"> - - - <div class="col-4of12"> - <h5> - 新しい動作と機能 - </h5> - - <p> - 新しい実行時パーミッション モデルや省電力機能など、新しいプラットフォームの動作をあらかじめサポートする - - </p> - </div> - - <div class="col-4of12"> - <h5> - 開発者が報告した問題に対する優先度ウィンドウ - </h5> - - <p> - 最初の数週間で開発者から報告のあった問題について優先度を設定し、可能な限り早くテストを行いフィードバックを提供できるようにします。 - - </p> - </div> - - <div class="col-4of12"> - <h5> - フィードバックとサポート - </h5> - - <p> - <a href="https://code.google.com/p/android-developer-preview/">Issue Tracker</a> で問題を報告し、フィードバックをお送りください。 - <a href="http://g.co/dev/AndroidMDevPreview">M Developer コミュニティ</a> で他の開発者とつながりましょう。 - - </p> - </div> - </div> -</div> -</div> - -<!-- -<p> - With the M Developer Preview, you'll get an early start on testing your apps, - with enough time to make adjustments before the public platform release later - in the year. We'll provide several updates to the Preview tools in the weeks - ahead, so you can keep in sync with the latest changes as the platform moves - toward launch. -</p> -<img src="{@docRoot}preview/images/m-preview-timeline.png" alt= -"Preview program timeline" id="timeline"> -<p> - You can help us improve the platform by <a href= - "https://code.google.com/p/android-developer-preview/">reporting issues</a> - through our feedback channels. This is especially - critical in the first month of the preview, when we’ll be giving priority to - developer-reported issues and feedback. -</p> --> - - -<h2 id="timeline"> - タイムラインとアップデート -</h2> -<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline"> -<p> - M Developer Preview は 5 月 28 日から最終の Android M SDK まで実行されます。Android M SDK はまもなく、2015 年第三四半期に予定されている正式公開の前にリリースされます。 - - -</p> - -<p> - 開発の主なマイルストーンごとにテスト端末へアップデートを配信する予定としています。 - 暫定マイルストーンは以下のとおりです。 -</p> - -<ul> - <li> - <strong>Preview 1</strong>(初期プレビュー リリース、5 月下旬) - </li> - - <li> - <strong>Preview 2</strong>(6 月下旬/7 月上旬) - </li> - - <li> - <strong>Preview 3</strong>(最終近く、7 月下旬) - </li> -</ul> - -<p> - アップデートは第三四半期後半に予定されている<strong>最終 SDK</strong> で終了します。最終版では新しい Android に対する正式な API や最終的なシステム動作や機能が提供されます。 - - -</p> - -<p> - Android M でのテストや開発に際しては、Preview アップデートがリリースされるたびに<strong>開発環境を最新に保つ</strong>ことを強くお勧めします。 - - プロセスをより容易にするため、既に Preview ビルドがインストールされた端末に<strong>無線経由でアップデート(OTA)</strong>を配信します。また手動でダウンロードして展開できるシステム イメージもご提供します。 - - -</p> -<p class="note"> - <strong>注:</strong> 最終 SDK とシステム イメージは OTA では配信できません。代わりにテスト端末に<strong>手動でコピー</strong>する必要があります。</strong> - - -</p> - -<p> - Preview アップデートをご利用いただけるようになった際は <a href="http://android-developers.blogspot.com/">Android デベロッパー ブログ</a>、このサイト、<a href="http://g.co/dev/AndroidMDevPreview">Android M デベロッパー コミュニティ</a>でお知らせします。 - - -</p> - -<h2 id="preview_tools"> - Preview の内容 -</h2> - -<p> - M Developer Preview では、ご利用のアプリをさまざまな画面サイズ、ネットワーク、テクノロジー、CPU や GPU チップセット、ハードウェア設計でテストするために必要なあらゆるものを備えています。 - - -</p> - -<h4> - SDK ツール -</h4> - -<p> - 各コンポーネントは <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a> の SDK Manager でダウンロードできます。 -</p> - -<ul> - <li>M Developer Preview <strong>SDK ツール</strong> - </li> - - <li>M Developer Preview <strong>エミュレータ システム イメージ</strong>(32 ビット版と 64 ビット版) - - </li> - - <li>M Developer Preview <strong>Android TV 版エミュレータ システム イメージ</strong>(32 ビット版) - - </li> -</ul> - -<h4> - ハードウェアのシステム イメージ -</h4> - -<p> - Nexus 端末向けハードウェア システム イメージは、<a href="download.html">ダウンロード ページ</a>からダウンロードできます。 - -</p> - -<ul> - <li> - <strong>Nexus 5</strong>(GSM と LTE)“hammerhead” 端末システム イメージ - </li> - - <li> - <strong>Nexus 6</strong> “shamu” 端末システム イメージ - </li> - - <li> - <strong>Nexus 9</strong>(Wi-Fi)“volantis” 端末システム イメージ - </li> - - <li> - <strong>Nexus Player</strong>(AndroidTV)“fugu” 端末システム イメージ - </li> -</ul> - -<h4> - ドキュメントとサンプル コード -</h4> - -<p> - 次のドキュメント リソースで Preview についての詳細をご確認いただけます。 -</p> - -<ul> - <li> - <a href="setup-sdk.html">SDK のセットアップ</a>では、はじめの手順をステップ バイ ステップでご説明しています。 - - </li> - - <li> - <a href="{@docRoot}preview/testing/guide.html">Testing Guide</a> と <a href="behavior-changes.html">Behavior Changes</a> では、テストでカバーされる主な分野について示しています。 - </li> - - <li>新しい API のドキュメントである <a href="api-overview.html">API 概要</a>、ダウンロード可能な <a href="{@docRoot}preview/download.html#docs">API リファレンス</a>や、主な機能のデベロッパー ガイドである<a href="{@docRoot}preview/features/runtime-permissions.html">パーミッション</a>、<a href="{@docRoot}preview/backup/index.html">アプリのバックアップ</a>などをご提供しています。 - - - - - </li> - - <li> - パーミッションや他の新しい機能をサポートする方法について、<a href="{@docRoot}preview/samples.html">サンプル コード</a>でお試しいただけます。 - - </li> - - <li> - 現行バージョンの<a href="{@docRoot}preview/support.html#release-notes">リリース ノート</a>で M Developer Preview の変更メモや差分レポートなどをご覧いただけます。 - - </li> -</ul> - -<h4> - サポート リソース -</h4> - -<p> - M Developer Preview でのテストや開発について、次のサポート リソースをご確認いただけます。 - -</p> - -<ul> - <li><a href="https://code.google.com/p/android-developer-preview/">M Developer Preview Issue Tracker</a> は、<strong>主なフィードバック チャンネル</strong>としてご利用になれます。 - -バグやパフォーマンスの問題、一般的なフィードバックなど Issue Tracker からご連絡いただけます。 -また、<a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">既知の問題</a> -やその回避策をご確認いただけます。 - </li> - - <li><a href="http://g.co/dev/AndroidMDevPreview">Android M Developer コミュニティ</a>は Google+ のコミュニティで、Android M を使っている<strong>他のデベロッパーとつながる</strong>ことができます。Android M に関する現象や考えを共有したり、疑問点を解消したりできます。 - - - - </li> -</ul> - - -<h2 id="preview_apis_and_publishing"> - 対象、プレビュー API、公開 -</h2> - -<p> - Android M Developer Preview は開発リリースのみであり、<strong>標準 API レベルはありません</strong>。 -アプリのテストで互換性の問題は除外する場合(強く推奨します)、アプリの<code><a href= - "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code> を <code>“MNC”</code> に設定することで M Developer Preview を対象にできます。 - - - -</p> - -<p> - Android M Developer Preview では<strong>プレビュー API</strong> を配信しています。現在 2015 年度第三四半期に予定されている最終 SDK がリリースされるまで、API は正式版ではありません。 - -つまり、時間がたつにつれて <strong>API の細かな変更</strong>が見込まれます(特にプログラムの最初の数週間)。 - -Android M Developer Preview でアップデートがあればその都度変更の概要をご提供します。 - -</p> - -<p class="note"> - プレビュー API は変更される可能性がありますが、実行時パーミッションや省電力機能などのシステムの基幹にかかわる機能には変更はありませんので、すぐにテストしていただけます。 - - -</p> - -<p> - 公開に関して、Google Play では <strong>M Developer Preview 対象アプリは公開できません</strong>。 -Android M 最終 SDK が利用可能になれば正式な Android M API レベルを対象にして、Google Play でアプリを公開できるようになります。 - -それまでは、Android M 対象のアプリをテスターに配布する場合は電子メールで送付したりご自分のサイトから直接ダウンロードしてもらったりしてください。 - - -</p> - -<h2 id="get_started"> - 開始するには -</h2> - -<p> - アプリのテストをはじめるには: -</p> - -<ol> - <li><a href="{@docRoot}preview/api-overview.html">API 概要</a>や <a href="{@docRoot}preview/behavior-changes.html">Behavior Changes</a> で新しい機能やご自分のアプリへの影響についてご確認ください。 - -特に、<a href="{@docRoot}preview/features/runtime-permissions.html">実行時パーミッション</a> モデルや省電力機能、自動バックアップ機能についてお確かめください。 - - - </li> - - <li><a href="{@docRoot}preview/setup-sdk.html">Setting up the Preview SDK</a> の手順に従い、ご利用の環境をセットアップしてテスト端末を構成してください。 - - - </li> - - <li><a href="https://developers.google.com/android/nexus/images">コピー手順</a>に従い、最新の M Developer Preview システム イメージを Nexus 5、6、9、Nexus Player にコピーします。 - -1 度開発端末に Preview 環境をコピーすると、アップデートが無線経由(OTA)で配信されます。</a> - - </li> - - <li><a href="{@docRoot}preview/download.html#docs">M Preview API リファレンス</a>や<a href="{@docRoot}preview/samples.html">M Preview サンプル</a>をダウンロードして、新しい API の機能についてさらに学び、ご自分のアプリで活用する方法についてご確認ください。 - - - - </li> - - <li><a href="http://g.co/dev/AndroidMDevPreview">Android M Developer コミュニティ</a>に参加して最新のニュースを入手し、Preview に取り組んでいる他のデベロッパーとつながってください。 - - - </li> -</ol> - -<p> - Android M Developer Preview プログラムへのご参加ありがとうございます。 -</p> diff --git a/docs/html-intl/intl/ja/preview/samples.jd b/docs/html-intl/intl/ja/preview/samples.jd deleted file mode 100644 index 6c44f4dd2c81..000000000000 --- a/docs/html-intl/intl/ja/preview/samples.jd +++ /dev/null @@ -1,70 +0,0 @@ -page.title=サンプル -page.image=images/cards/samples-new_2x.png -@jd:body - -<p> - 以下のコードサンプルは、M Developer Preview 用に提供しています。サンプルを Android Studio でダウンロードするには、<b>[File] > [Import Samples]</b> メニュー オプションを選択します。 - -</p> - -<p class="note"> - <strong>注:</strong> 以下のダウンロード可能なプロジェクトは、Gradle と Android Studio でご利用いただくために提供しています。 - -</p> - - -<h3 id="RuntimePermissions">実行時パーミッション</h3> - -<p> - Android M では、システムのパーミッションの仕組みが変わります。ユーザーは、パーミッション要求の承認をインストール時ではなく、実行時に求められるようになります。 -このサンプルでは、このパーミッションの要求方法を紹介しています。 - -</p> - -<p><a href="https://github.com/googlesamples/android-RuntimePermissions">GitHub でサンプルを入手</a></p> - -<h3 id="ConfirmCredentials">資格情報の確認</h3> - -<p> - このサンプルでは、アプリで端末の資格情報を認証手段として使用する方法を紹介しています。 -</p> - -<p><a href="https://github.com/googlesamples/android-ConfirmCredential">GitHub でサンプルを入手</a> -</p> - -<h3 id="FingerprintDialog">指紋ダイアログ</h3> - -<p> - このサンプルでは、ユーザーを認証するために登録された指紋をアプリで識別する方法を紹介しています。 - -</p> - -<p><a href="https://github.com/googlesamples/android-FingerprintDialog">GitHub でサンプルを入手</a></p> - -<h3 id="AutomaticBackup">アプリの自動バックアップ</h3> - -<p> - Android M では、アプリの設定の自動バックアップが導入されました。このサンプルでは、設定のバックアップを管理するためにアプリにフィルタリング ルールを追加する方法を紹介しています。 - -</p> - -<p><a href="https://github.com/googlesamples/android-AutoBackupForApps">GitHub でサンプルを入手</a></p> - -<h3 id="CameraRaw">Camera 2 Raw</h3> - -<p> - このサンプルでは、<code>Camera2</code> API を使用して、RAW カメラバッファをキャプチャし、<code>DNG</code> ファイルとして保存する方法を紹介しています。 - -</p> - -<p><a href="https://github.com/googlesamples/android-Camera2Raw">GitHub でサンプルを入手</a></p> - -<h3 id="ActiveNotification">アクティブ通知</h3> - -<p> - このサンプルでは、その時点でアプリに表示されている通知の数を <a href="{@docRoot}reference/android/app/NotificationManager.html"><code>NotificationManager</code></a> を使って調べる方法を紹介しています。 - - -</p> - -<p><a href="https://github.com/googlesamples/android-ActiveNotifications">GitHub でサンプルを入手</a></p> diff --git a/docs/html-intl/intl/ja/preview/setup-sdk.jd b/docs/html-intl/intl/ja/preview/setup-sdk.jd deleted file mode 100644 index b4fe2e028c03..000000000000 --- a/docs/html-intl/intl/ja/preview/setup-sdk.jd +++ /dev/null @@ -1,207 +0,0 @@ -page.title=Preview SDK のセットアップ -page.image=images/cards/card-set-up_16-9_2x.png - -@jd:body - - -<div id="qv-wrapper"> - <div id="qv"> - <h2>本書の内容</h2> - <ol> - <li><a href="#get-as13">Android Studio 1.3 を入手する</a></li> - <li><a href="#get-sdk">Preview SDK を入手する</a></li> - <li><a href="#create-update">プロジェクトを作成または更新する</a></li> - <li><a href="#setup-test">テスト用にセットアップする</a></li> - </ol> - </div> -</div> - -<p>M Developer Preview SDK は、Android SDK Manager から入手できます。このドキュメントは、Android SDK Manager の使用方法やプロジェクトの作成方法などの Android アプリ開発についての知識をお持ちの方を対象にしています。 - -Android アプリを初めて開発する場合は、まず <a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a> のトレーニング レッスンをご覧ください。</a> - -</p> - -<h2 id="get-as13">Android Studio 1.3 を入手する</h2> - -<p>Developer Preview は、現在プレビュー段階にある Android Studio 1.3 に最適化されています。 -Preview SDK をご使用になる場合は、Android Studio 1.3 のプレビュー版をインストールすることをお勧めします。 -</p> - -<p class="caution"><strong>注意:</strong> Android Studio 1.3 の Canary プレビューは、現在も開発中です。 -メインの開発用マシンを Developer Preview のテストに使用する場合、テスト用に 2 つ目の Android Studio をインストールできます。 - -</p> - -<p>Android Studio 1.3 プレビューをインストールするには: </p> - -<ol> - <li><a href="{@docRoot}tools/studio/index.html">Android Studio</a> をダウンロードして起動します。 - - </li> - - <li>[<strong>Settings</strong>] ウィンドウを開きます(Windows では、 <strong>[File] > [Settings]</strong> を選択すると開くことができます)。 -<strong>[Appearance & Behavior] > [System Settings] > [Updates]</strong> を選択します。 - - - - <p class="aside">OSX では、Android Studio の [<strong>Preferences</strong>] ウィンドウで、[<strong>Appearance & Behavior</strong>] パネルを見つけることができます。 - -</p> - </li> - - <li> [<strong>Updates</strong>] パネルで、<strong>[Automatically check updates for:] に -[Canary Channel]</strong> を選択します。 - </li> - - <li>[<strong>Updates</strong>] パネルで、[<strong>Check Now</strong>] を選択して最新の Canary ビルドの有無を確認します。 -メッセージが表示されたら、最新の Canary ビルドをダウンロードしてインストールします。 - - </li> -</ol> - -<h2 id="get-sdk">Preview SDK を入手する</h2> - -<p>開発環境に Preview SDK コンポーネントを追加するには: </p> - -<ol> - <li>Android Studio 1.3 プレビューを起動します。 - </li> - - <li>[<strong>Settings</strong>] ウィンドウを開きます(Windows では、 <strong>[File] > [Settings]</strong> を選択すると開くことができます)。 -<strong>[Appearance & Behavior] > [System Settings] > [Updates]</strong> を選択します。 - - - - <p class="aside">OSX では、Android Studio の [<strong>Preferences</strong>] ウィンドウで、[<strong>Appearance & Behavior</strong>] パネルを見つけることができます。 - -</p> - </li> - - <li>[<strong>Updates</strong>] パネルで、<strong>[Automatically check updates for:] に -[Canary Channel]</strong> を、<strong>[Automatically check updates for Android SDK:] に -[Preview Channel]</strong> を選択します。 - </li> - - <li>[<strong>Android SDK Manager</strong>] を起動します。(Android Studio 1.3 では、SDK Manager はスタンドアロン アプリケーションではなくなり Android Studio に統合されました。) - - - </li> - - <li>[<strong>Platforms</strong>] セクションで、[<strong>Android MNC Preview</strong>] を選択します。 - - </li> - - <li>[<strong>Tools</strong>] セクションで、最新の Android [<strong>SDK Tools</strong>]、[<strong>Platform-tools</strong>]、[<strong>Build-tools</strong>] を選択します。 - - - </li> - - <li>[<strong>Install packages</strong>] をクリックし、すべてのパッケージの使用許諾契約に同意します。 - - </li> - - <li>[<strong>Settings</strong>] ウィンドウを開き、<strong>[Appearance & Behavior] > [System Settings] > [Android SDK]</strong> を選択し、M Developer Preview がインストールされていることを確認します。 - -</li> - - <li>[<strong>Android SDK</strong>] パネルで、[<strong>SDK Platforms</strong>] を選択します。 -[<strong>Android MNC Preview</strong>] が [<em>Installed</em>] と表示されているはずです。 -また、[<strong>SDK Tools</strong>] タブを開き、最新のツールがインストールされていることを確認します。 - - - </li> -</ol> -<p>上記の手順を完了すると、開発環境でプレビュー コンポーネントを利用できるようになります。 - </p> - - -<h2 id="create-update">プロジェクトを作成または更新する</h2> - -<p> - プレビュー API を使用するには、プレビュー コンポーネントを使用するために開発プロジェクトを作成または更新する必要があります。 - -</p> - - -<h3 id="create">新しいプロジェクトを作成する</h3> - -<p> - Preview SDK を使用してプロジェクトを作成するときには、Android Studio を使用することをお勧めします。<a href="{@docRoot}sdk/installing/create-project.html">Creating a Project</a> に記載されている手順に従い、プロジェクト ウィザードで [<em>Form Factors</em>] 画面が表示されるまで操作を進めます。 - -次に、以下の手順に従い、Preview SDK 用に構成されたプロジェクトを作成します。 - -</p> - -<ul> - <li>[<strong>Phone and Tablet</strong>] をチェックします。</li> - <li>[<strong>Minimum SDK</strong>] で、[<strong>MNC: Android M (Preview)</strong>] を選択します。 -</li> -</ul> - - -<h3 id="update">既存のプロジェクトを更新する</h3> - -<p> - 既存のプロジェクトを使用する場合は、プロジェクト構成を変更してプレビュー API を有効にする必要があります。開発環境で、モジュールの <code>build.gradle</code> ファイルを開き、次のように値を設定します。 - - -</p> - -<ul> - <li><code>compileSdkVersion</code> に <code>'android-MNC'</code> を設定します。</li> - <li><code>minSdkVersion</code> に <code>'MNC'</code> を設定します。</li> - <li><code>targetSdkVersion</code> に <code>'MNC'</code> を設定します。</li> -</ul> - - -<h2 id="setup-test">テスト用にセットアップする</h2> - -<p> - Preview SDK でアプリをテストするには、プレビュー版のプラットフォームを使用して構成した端末または仮想端末が必要です。 -互換端末をお持ちの場合、テスト用にプレビュー プラットフォームをインストールできます。 -互換端末をお持ちでない場合は、テスト用に仮想端末を構成できます。 -</p> - -<h3 id="setup-device">物理端末をセットアップする</h3> - -<p> - Nexus 5、Nexus 6、Nexus 9、Android TV をお持ちの場合は、アプリのテスト用にこれらの端末にプレビュー システム イメージをインストールできます。Android Virtual Device Manager ツールを使用すると、Android Studio 内から仮想端末をプレビュー版のプラットフォームでセットアップできます。 - - - -</p> - -<p class="caution"> - <strong>重要:</strong> 端末にプレビュー イメージをインストールすると、<em>端末からすべてのデータが削除されます</em>。そのため、プレビュー イメージをインストールする前にすべてのデータをバックアップする必要があります。 - -</p> - -<h3 id="setupAVD">仮想端末をセットアップする</h3> - -<p> - Android Virtual Device Manager ツールを使用すると、Android Studio 内からプレビュー版のプラットフォームで仮想端末をセットアップできます。 - -</p> - -<p>AVD マネージャーで AVD を作成するには: </p> - -<ol> - <li><a href="{@docRoot}preview/setup-sdk.html">Preview SDK のセットアップ</a>の説明に従って、開発環境に Preview SDK をインストールします。 - -</li> - <li><a href="{@docRoot}tools/devices/managing-avds.html">Managing AVDs with AVD Manager</a> の手順に従います。 - -以下の設定を使用します。 - <ul> - <li><strong>端末:</strong> Nexus 5、Nexus 6、Nexus 9、Android TV</li> - <li><strong>対象:</strong> - Android M (Preview) - API Level M</li> - <li><strong>ABI:</strong> x86</li> - </ul> - </li> -</ol> - -<p> - テスト用の仮想端末の作成についての詳細は、<a href="{@docRoot}tools/devices/index.html">Managing Virtual Devices</a> をご覧ください。 -</p> diff --git a/docs/html-intl/intl/ja/preview/testing/guide.jd b/docs/html-intl/intl/ja/preview/testing/guide.jd deleted file mode 100644 index b70e04d91a1b..000000000000 --- a/docs/html-intl/intl/ja/preview/testing/guide.jd +++ /dev/null @@ -1,187 +0,0 @@ -page.title=テストガイド -page.image=images/cards/card-build_16x9_2x.png -page.keywords=プレビュー リソース,Android M,テスト,パーミッション - -@jd:body - -<div id="qv-wrapper"> - <div id="qv"> - <h2>本書の内容</h2> - <ol> - <li><a href="#runtime-permissions">パーミッションをテストする</a></li> - <li><a href="#doze-standby">Doze と App Standby をテストする</a></li> - <li><a href="#ids">自動バックアップと端末識別子</a></li> - </ol> - </div> -</div> - -<p> - Android M Developer Preview を利用すると、次期バージョンのプラットフォームでアプリが動作するか確認できます。 -Android M Developer Preview には、<a href="{@docRoot}preview/api-overview.html">API の概要</a>と<a href="{@docRoot}preview/behavior-changes.html">動作の変更点</a>に記載されているように、アプリに影響を与える可能性のある多くの API と動作の変更が含まれています。 - -Android M Developer Preview でアプリをテストする時には、アプリの良好な使用感を確保するために、システムのいくつかの変更点に特に注意する必要があります。 - - -</p> - -<p> - このガイドでは、アプリで Android M Developer Preview の機能の何をどのようにテストすればよいか説明します。以下の機能は、アプリの動作に大きな影響を与える可能性があるので、優先してテストする必要があります。 - - -</p> - -<ul> - <li><a href="#runtime-permissions">パーミッション</a> - </li> - <li><a href="#doze-standby">Doze と App Standby</a> - </li> - <li><a href="#ids">自動バックアップと端末識別子</a></li> -</ul> - -<p> - テスト用のプレビュー システム イメージを使用した端末または仮想端末のセットアップ方法の詳細については、<a href="{@docRoot}preview/setup-sdk.html">Preview SDK のセットアップ</a>をご覧ください。 - -</p> - - -<h2 id="runtime-permissions">パーミッションをテストする</h2> - -<p> - <a href="{@docRoot}preview/features/runtime-permissions.html">パーミッション</a> モデルの変更により、ユーザーがアプリにパーミッションを付与する方法が変わりました。 -アプリでは、インストール時にすべてのパーミッションを要求するのではなく、実行時に個々のパーミッションをユーザーに要求する必要があります。 - -これにより、ユーザーは、各アプリのアクティビティをより細かくコントロールできるようになるだけではなく、アプリが各パーミッションを要求する理由をこれまでよりもよく理解できるようになります。 -ユーザーは、いつでもアプリに個別にパーミッションを付与したり、付与したパーミッションを個別に取り消したりできます。 -この機能は、アプリの動作に大きな影響を与える可能性があり、アプリの一部の機能が動作しなくなったり、限定された機能しか使えなくなったりする可能性もあります。 - - -</p> - -<p class="caution"> - この変更は、アプリがこの新しいバージョンを対象にしているかどうかにかかわらず、この新しいプラットフォーム上で実行されるすべてのアプリに影響します。 -このプラットフォームはレガシーアプリに限定的な互換動作を提供しますが、公式版のプラットフォームのリリースに合わせてアップデート版のアプリを公開できるように、新しいパーミッション モデルに対応させるためのアプリの移行を今から計画することを強くお勧めします。 - - -</p> - - -<h3 id="permission-test-tips">テストのヒント</h3> - -<p> - 以下のテストのヒントを活用して、アプリでの新しいパーミッション動作のテストを計画し、実行してください。 - -</p> - -<ul> - <li>アプリの現在のパーミッションと関連するコードパスを確認します。</li> - <li>パーミッションで保護されているサービスとデータ間のユーザーフローをテストします。</li> - <li>付与されたパーミッションと取り消されたパーミッションのさまざまな組み合わせをテストします。</li> - <li>{@code adb} ツールを使用して、コマンドラインからパーミッションを管理します。 - <ul> - <li>パーミッションとステータスをグループ化して表示します。 - <pre>adb shell pm list permissions -d -g</pre> - </li> - <li>以下の構文を使用して 1 つまたは複数のパーミッションを付与または取り消します。<br> - <pre>adb shell pm [grant|revoke] <permission.name> ...</pre> - </li> - </ul> - </li> - <li>アプリでパーミッションを使用しているサービスを分析します。</li> -</ul> - -<h3 id="permission-test-strategy">テスト方針</h3> - -<p> - このパーミッションの変化は、アプリの構造と設計、ユーザーが体験する使用感とフローに影響を与えます。 -アプリの現在のパーミッション利用の状況を調査し、新しいフローの検討を開始する必要があります。 -このプラットフォームの公式リリースは互換動作を提供しますが、互換動作に頼ることなくアプリのアップデートを計画することを強くお勧めします。 - - -</p> - -<p> - まずアプリが実際に必要とし使用しているパーミッションを特定してから、パーミッションで保護されたサービスを使用している各コードパスを探してください。 -これには、新しいプラットフォーム上でのテストと、コードの解析が必要です。 -テストでは、アプリの {@code targetSdkVersion} をこのプレビュー版に変えて、実行時パーミッションのオプトインに重点的にテストする必要があります。 -詳細については、<a href="{@docRoot}preview/setup-sdk.html#">Preview SDK のセットアップ</a>をご覧ください。 - -</p> - -<p> - パーミッションの取り消しと追加のさまざまな組み合わせをテストし、パーミッションに依存するユーザーフローを確認します。 -パーミッションへの依存性が明白または論理的ではない箇所では、依存性を取り除くため、またはパーミッションが必要な理由を明白にするために、フローのリファクタリングまたはコンパートメント化を検討する必要があります。 - - -</p> - -<p> - 実行時パーミッションの動作、テスト、ベスト プラクティスについては、Developer Preview ページの<a href="{@docRoot}preview/features/runtime-permissions.html">パーミッション</a>をご覧ください。 - - -</p> - - -<h2 id="doze-standby">Doze と App Standby をテストする</h2> - -<p> - 省電力機能である Doze と App Standby により、端末がアイドル状態のときやそのアプリにフォーカスがないときに、アプリが実行できるバックグラウンド処理の量が制限されます。 -システムによってアプリに加えられる可能性のある制限には、ネットワーク アクセスの制限や停止、バックグラウンド タスクの停止、通知の停止、ウェイク リクエストの無視、アラームなどがあります。 - -これらの省電力のための最適化が行われた状態で確実にアプリが適切に動作するように、これらの省電力状態をシミュレートしてアプリをテストする必要があります。 - - -</p> - -<h4 id="doze">アプリで Doze をテストする</h4> - -<p>アプリで Doze をテストするには: </p> - -<ol> -<li>M Preview のシステム イメージを使用して、ハードウェア端末または仮想端末を構成します。</li> -<li>端末を開発マシンに接続し、アプリをインストールします。</li> -<li>アプリを実行し、アクティブ状態のままにします。</li> -<li>以下のコマンドを実行して、端末の Doze モードへの移行をシミュレートします。 - -<pre> -$ adb shell dumpsys battery unplug -$ adb shell dumpsys deviceidle step -$ adb shell dumpsys deviceidle -h -</pre> - - </li> - <li>端末がアクティブ状態に戻ったときのアプリの動作を観察します。端末が Doze モードから抜けるときに、アプリがスムーズに復帰することを確認します。 -</li> -</ol> - - -<h4 id="standby">アプリで App Standby をテストする</h4> - -<p>アプリで App Standby モードをテストするには: </p> - -<ol> - <li>M Preview のシステム イメージを使用して、ハードウェア端末または仮想端末を構成します。</li> - <li>端末を開発マシンに接続し、アプリをインストールします。</li> - <li>アプリを実行し、アクティブ状態のままにします。</li> - <li>以下のコマンドを実行して、アプリのスタンバイ モードへの移行をシミュレートします。 - -<pre> -$ adb shell am broadcast -a android.os.action.DISCHARGING -$ adb shell am set-idle <packageName> true -</pre> - - </li> - <li>以下のコマンドを使用して、アプリのウェイクをシミュレートします。 - <pre>$ adb shell am set-idle <packageName> false</pre> - </li> - <li>アプリがウェイク状態に戻ったときのアプリの動作を観察します。アプリがスタンバイ モードからスムーズに復帰することを確認します。 -特に、アプリの通知とバックグラウンド ジョブが想定通りの動作を続けているかを確認する必要があります。 -</li> -</ol> - -<h2 id="ids">アプリの自動バックアップと端末固有識別子</h2> - -<p>アプリが、Google Cloud Messaging の登録 ID などの何らかの端末固有の識別子を内部ストレージに保持している場合、<a href="{@docRoot}preview/backup/index.html">アプリの自動バックアップ</a>の説明に従って、そのストレージのロケーションを自動バックアップの対象から除外してください。 - - - - </p> diff --git a/docs/html-intl/intl/ja/preview/testing/performance.jd b/docs/html-intl/intl/ja/preview/testing/performance.jd deleted file mode 100644 index 1c3ae02290f1..000000000000 --- a/docs/html-intl/intl/ja/preview/testing/performance.jd +++ /dev/null @@ -1,656 +0,0 @@ -page.title=表示パフォーマンスのテスト -page.image=images/cards/card-test-performance_2x.png -page.keywords=パフォーマンス,fps,ツール - -@jd:body - - -<div id="qv-wrapper"> - <div id="qv"> - <h2>本書の内容</h2> - <ol> - <li><a href="#measure">UI のパフォーマンスを測定する</a> - <ul> - <li><a href="#aggregate">フレームのデータを集計する</a></li> - <li><a href="#timing-info">正確なフレーム タイミング情報</a></li> - <li><a href="#timing-dump">簡易フレーム タイミング ダンプ</a></li> - <li><a href="#collection-window">データ収集用のウィンドウを制御する</a></li> - <li><a href="#diagnose">パフォーマンスの低下を診断する</a></li> - <li><a href="#resources">追加リソース</a></li> - </ul> - </li> - <li><a href="#automate">UI パフォーマンス テストを自動化する</a> - <ul> - <li><a href="#ui-tests">UI テストをセットアップする</a></li> - <li><a href="#automated-tests">自動化された UI テストをセットアップする</a></li> - <li><a href="#triage">見つけた問題を選別し解決する</a></li> - </ul> - </li> - </ol> - </div> -</div> - - -<p> - ユーザー インターフェース(UI)のパフォーマンスをテストすることで、アプリが機能面での要件に合うだけでなく、ユーザーがアプリをスムーズに操作でき、毎秒安定して 60 フレーム(<a href="https://www.youtube.com/watch?v=CaMTIgxCSqU&index=25&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">why 60fps?</a>)で、フレームのドロップや遅延なしで、言い換えれば<em>ジャンク</em>なしで実行されるようにします。 - - -このドキュメントでは、UI のパフォーマンスを測定することができるツールについて説明し、UI パフォーマンスの測定値をテストで活用する方法を提示します。 - - -</p> - - -<h2 id="measure">UI のパフォーマンスを測定する</h2> - -<p> - パフォーマンスを改善するには、まずシステムのパフォーマンスを測定し、次にパイプラインのさまざまな箇所で発生している問題を診断し識別する必要があります。 - - -</p> - -<p> - <em><a href="https://source.android.com/devices/tech/debug/dumpsys.html">dumpsys</a></em> は端末上で動作し、システム サービスの状態についての情報をダンプする Android ツールです。 - -<em>gfxinfo</em> コマンドを dumpsys に渡すと、記録中に実行されたアニメーションのフレームに関連するパフォーマンス情報が logcat に出力されます。 - - -</p> - -<pre> -> adb shell dumpsys gfxinfo <PACKAGE_NAME> -</pre> - -<p> - このコマンドは、フレーム タイミング データの複数の異なるバリアントを生成することがあります。 -</p> - -<h3 id="aggregate">フレームのデータを集計する</h3> - -<p> - M Preview では、このコマンドは、プロセスの生存期間全体を通して収集したフレームのデータの集計結果を logcat に出力します。 -次に例を示します。 -</p> - -<pre class="noprettyprint"> -Stats since: 752958278148ns -Total frames rendered: 82189 -Janky frames: 35335 (42.99%) -90th percentile: 34ms -95th percentile: 42ms -99th percentile: 69ms -Number Missed Vsync: 4706 -Number High input latency: 142 -Number Slow UI thread: 17270 -Number Slow bitmap uploads: 1542 -Number Slow draw: 23342 -</pre> - -<p> - これらのデータは、アプリのレンダリングのパフォーマンスと多くのフレームの全体での安定性を大まかに示します。 - -</p> - - -<h3 id="timing-info">正確なフレーム タイミング情報</h3> - -<p> - M Preview では、gfxinfo のための新しいコマンド、<em>framestats</em> が採用され、最新のフレームのフレーム タイミングのきわめて詳細な情報を提供します。そのため、より正確に問題を追跡しデバッグできるようになります。 - - -</p> - -<pre> ->adb shell dumpsys gfxinfo <PACKAGE_NAME> framestats -</pre> - -<p> - このコマンドは、アプリによって生成された最新 120 フレームのフレーム タイミング情報を、ナノ秒の精度を持つタイムスタンプを使用して出力します。以下は、adb dumpsys gfxinfo - <PACKAGE_NAME> framestats による未加工の出力例です。 - -</p> - -<pre class="noprettyprint"> -0,49762224585003,49762241251670,9223372036854775807,0,49762257627204,49762257646058,49762257969704,49762258002100,49762265541631,49762273951162,49762300914808,49762303675954, -0,49762445152142,49762445152142,9223372036854775807,0,49762446678818,49762446705589,49762447268818,49762447388037,49762453551527,49762457134131,49762474889027,49762476150120, -0,49762462118845,49762462118845,9223372036854775807,0,49762462595381,49762462619287,49762462919964,49762462968454,49762476194547,49762476483454,49762480214964,49762480911527, -0,49762479085548,49762479085548,9223372036854775807,0,49762480066370,49762480099339,49762481013089,49762481085850,49762482232152,49762482478350,49762485657620,49762486116683, -</pre> - -<p> - この出力の各行が、アプリによって生成される 1 つのフレームを示します。各ラインは、フレームを生成するパイプラインの各段階で費やされた時間を出力する固定された数の列を持ちます。 -次のセクションでは、各列が何を示しているかも含めて、フォーマットを詳細に説明します。 - -</p> - - -<h4 id="fs-data-format">Framestats データ形式</h4> - -<p> - データは CSV 形式で出力されるため、お好みのスプレッドシート ツールに簡単に貼り付けたり、スクリプトで簡単に集計して解析したりできます。 -以下のリストは、出力データ列のフォーマットを説明しています。 -すべてのタイムスタンプはナノ秒単位で出力されます。 -</p> - -<ul> - <li>FLAGS - <ul> - <li>FLAGS 列が「0」の行には、FRAME_COMPLETED 列から INTENDED_VSYNC 列を引いて計算されたフレームの総処理時間が示されます。 - - </li> - - <li>FLAGS 列が「0」以外の場合、そのフレームは通常のパフォーマンスからの外れ値であると定められているのでその行は無視する必要があります。この場合、レイアウトと描画に 16 ミリ秒よりも長くかかることが想定されています。 - -これは、以下の原因で起きることがあります。 - <ul> - <li>ウィンドウのレイアウトが変更された(アプリケーションの最初のフレームの場合や画面が回転された後など)。 - - </li> - - <li>フレームが省略された。この場合、いくつかの値には不適切なタイムスタンプが含まれます。 -たとえば 60 fps よりも速く実行されている場合や、画面上にダーティで終わったものが何もない場合など、フレームは省略することができます。これは必ずしもアプリに問題がある兆候ではありません。 - - - </li> - </ul> - </li> - </ul> - </li> - - <li>INTENDED_VSYNC - <ul> - <li>フレームの意図された開始ポイント。この値が VSYNC と異なる場合、vsync 信号にすぐに応答することを阻止する動作が UI スレッド上で発生していたことを意味します。 - - - </li> - </ul> - </li> - - <li>VSYNC - <ul> - <li>すべての vsync リスナーとフレームの描画(Choreographer フレーム コールバック、アニメーション、View.getDrawingTime() など)で使用された時間の値。 - - </li> - - <li>VSYNC と VSYNC のアプリケーションへの影響の詳細については、<a href="https://www.youtube.com/watch?v=1iaHxmfZGGc&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=23">Understanding VSYNC</a> のビデオをご覧ください。 - - - </li> - </ul> - </li> - - <li>OLDEST_INPUT_EVENT - <ul> - <li>入力キューの最も古い入力イベントのタイムスタンプ。フレームの入力イベントが存在しない場合は、Long.MAX_VALUE。 - - </li> - - <li>この値は、主にプラットフォームの動作のパフォーマンスを示すことを意図しており、アプリのデベロッパーが活用できる場面は限定されます。 - - </li> - </ul> - </li> - - <li>NEWEST_INPUT_EVENT - <ul> - <li>入力キューの最も新しい入力イベントのタイムスタンプ。フレームの入力イベントが存在しない場合は、0。 - - </li> - - <li>この値は、主にプラットフォームの動作のパフォーマンスを示すことを意図しており、アプリのデベロッパーが活用できる場面は限定されます。 - - </li> - - <li>ただし、FRAME_COMPLETED から NEWEST_INPUT_EVENT を引いた値を確認することによって、そのアプリが増やす待ち時間がどれくらいか大まかに知ることができます。 - - </li> - </ul> - </li> - - <li>HANDLE_INPUT_START - <ul> - <li>入力イベントがアプリケーションにディスパッチされるときのタイムスタンプ。 - </li> - - <li>この値と ANIMATION_START との間の時間を確認することで、アプリケーションが入力イベントを処理するために費やした時間を測定することができます。 - - </li> - - <li>この値が大きい(> 2 ミリ秒)の場合、View.onTouchEvent() などの入力イベントを処理するためにアプリが長い時間を費やしていることを意味します。これは、この動作の最適化または別のスレッドへの移行が必要なことを示している場合があります。 - -新しいアクティビティやそれに類するものを起動するクリック イベントなどの一部のシナリオでは、この値が大きいことは想定済みであり許容範囲内です。 - - - </li> - </ul> - </li> - - <li>ANIMATION_START - <ul> - <li>Choreographer を使用して登録されたアニメーションが実行されたときのタイムスタンプ。 - </li> - - <li>この値と PERFORM_TRANVERSALS_START の間の時間を確認することで、実行中のすべてのアニメーター(ObjectAnimator、ViewPropertyAnimator、共通の遷移となっている Transitions)を評価するのにかかった時間を確認することができます。 - - - </li> - - <li>この値が大きい(> 2 ミリ秒)の場合、アプリがカスタム アニメーターを記述していないか、また ObjectAnimators がアニメーション化しているのがどの項目かを確認して、それらがアニメーションに適しているかどうか確かめてください。 - - - </li> - - <li>Choreographer についての詳細は、<a href="https://developers.google.com/events/io/sessions/325418001">For Butter or Worse</a> のビデオをご覧ください。 - - </li> - </ul> - </li> - - <li>PERFORM_TRAVERSALS_START - <ul> - <li>この値から DRAW_START を引くと、レイアウトと測定のフェーズが完了するまでにかかる時間を知ることができます(スクロールまたはアニメーションの間は、この時間がゼロに近いことが望ましいことにご注意ください)。 - - - </li> - - <li>レンダリング パイプラインのレイアウトと測定のフェーズについての詳細は、<a href="https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27">Invalidations, Layouts and Performance</a> のビデオをご覧ください。 - - - </li> - </ul> - </li> - - <li>DRAW_START - <ul> - <li>performTraversals の描画のフェーズが開始された時間。これは、無効化されているビューのディスプレイ リストを記録する開始ポイントです。 - - </li> - - <li>この値と SYNC_START の間の時間は、ツリー内のすべての無効化されているビュー上で View.draw() を呼び出すのにかかった時間を示します。 - - </li> - - <li>描画モデルに関する詳細は、<a href="{@docRoot}guide/topics/graphics/hardware-accel.html#hardware-model">Hardware Acceleration</a> または <a href="https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27">Invalidations, Layouts and Performance</a> のビデオをご覧ください。 - - - </li> - </ul> - </li> - - <li>SYNC_START - <ul> - <li>描画の同期フェーズが開始された時間。 - </li> - - <li>この値と ISSUE_DRAW_COMMANDS_START の間の時間が非常に大きい場合(> 0.4 ミリ秒またはこれに近い値)、通常は、GPU にアップロードする必要がある多くの新しい Bitmaps が描画されたこと意味します。 - - - </li> - - <li>同期フェーズについての詳細は、<a href="https://www.youtube.com/watch?v=VzYkVL1n4M8&index=24&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu">Profile GPU Rendering</a> のビデオをご覧ください。 - - </li> - </ul> - </li> - - <li>ISSUE_DRAW_COMMANDS_START - <ul> - <li>ハードウェア レンダラーが、GPU への描画コマンドの発行を開始した時間。 - </li> - - <li>この値と FRAME_COMPLETED の間の時間により、そのアプリがどれくらいの量の GPU 作業を生じさせているのか大まかに知ることができます。 -オーバードローが多すぎたりまたはレンダリング効果が不十分だったりという問題がある場合は、この時間にあらわれます。 - - </li> - </ul> - </li> - - <li>SWAP_BUFFERS - <ul> - <li>eglSwapBuffers が呼び出された時間。プラットフォーム作業関連以外では、あまり重要ではない値です。 - - </li> - </ul> - </li> - - <li>FRAME_COMPLETED - <ul> - <li>すべてが完了した時間です。そのフレームを処理するのにかかった時間の合計は、FRAME_COMPLETED から INTENDED_VSYNC を引くと計算できます。 - - </li> - </ul> - </li> - -</ul> - -<p> - このデータは、別の方法でも使用できます。たとえば、さまざまな遅延バケットでのフレームの処理にかかった時間(FRAME_COMPLETED - INTENDED_VSYNC)の分布を示す下記のヒストグラムは、単純ですが役に立ちます。 - -このグラフを一目見るだけで、大部分のフレームは 16 ミリ秒の限界線(赤色の線)を大きく下回った良好な状態であるけれども、いくつかのフレームが限界線を著しく上回っていることがわかります。 - -ヒストグラムで時間の経過に伴う変化を確認することで、大規模な変化が起きているのか、新しい外れ値が作成されているのか知ることができます。 -また、データに含まれる多くのタイムスタンプに基づいて、入力待ち時間、レイアウトにかかった時間、その他のこれに類する興味を引く指標をグラフにできます。 - - -</p> - -<img src="{@docRoot}preview/images/perf-test-framestats.png"> - - -<h3 id="timing-dump">簡易フレーム タイミング ダンプ</h3> - -<p> - [開発者向けオプション] で [<strong>GPUレンダリングのプロフィール作成</strong>] を [<strong>adb shell dumpsys gfxinfo</strong>] に設定すると、<code>adb shell dumpsys gfxinfo</code> コマンドにより、最新の 120 フレームのタイミング情報が、いくつかの異なるカテゴリに分かれて、タブ区切りで出力されます。 - - -このデータは、描画パイプラインのどの部分の処理が遅いのかを大まかに知るのに役に立ちます。 - -</p> - -<p> - 上記の <a href="#fs-data-format">framestats</a> と同様に、お好みのスプレッドシート ツールに簡単に貼り付けたり、スクリプトで簡単に集計し解析したりできます。 - -以下のグラフは、アプリによって生成された多くのフレームが時間を費やした箇所の内訳を示しています。 - -</p> - -<img src="{@docRoot}preview/images/perf-test-frame-latency.png"> - -<p> - このグラフは、gfxinfo を実行し、出力結果をコピーし、スプレッドシート アプリケーションに貼り付け、データを積み上げ棒グラフにしたものです。 - -</p> - -<p> - 各縦棒は、アニメーションの 1 フレームを示し、その高さはそのフレームを処理するのにかかるミリ秒の数を示しています。 -また、縦棒の色分けされた各部分は、レンダリング パイプラインの各段階を示しています。これにより、ボトルネックを生んでいる可能性があるのはアプリケーションのどの箇所か確認できます。 - -レンダリング パイプラインとその最適化方法に関する詳細は、<a href="https://www.youtube.com/watch?v=we6poP0kw6E&index=27&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">Invalidations, Layouts and Performance</a> のビデオをご覧ください。 - - -</p> - - -<h3 id="collection-window">データ収集用のウィンドウを制御する</h3> - -<p> - Framestats と簡易フレーム タイミングの両方とも、非常に短いウィンドウを通じて、約 2 秒相当のレンダリングについてデータを収集しています。 -たとえば、収集するデータを特定のアニメーションだけに限定したい場合、このタイミング データ収集用ウィンドウを正確にコントロールするには、すべてのカウンタをリセットし収集したデータを集計します。 - - -</p> - -<pre> ->adb shell dumpsys gfxinfo <PACKAGE_NAME> reset -</pre> - -<p> - これは、ダンプ コマンドとあわせて使用することもでき、フレームの 2 秒未満のウィンドウを続けてキャプチャしながら、通常の流れで収集しリセットできます。 - - -</p> - - -<h3 id="diagnose">パフォーマンスの低下を診断する</h3> - -<p> - パフォーマンスの低下を見つけることは、問題を見つけだし、アプリケーションの状態を良好に維持するための最初のステップです。 -ただし、dumpsys は、ただ問題の存在とその相対的な深刻度を明らかにするだけです。 -さらに、パフォーマンスの問題の具体的な原因を突き止め、解決するための適切な方法を見つける必要があります。 -それには、<a href="{@docRoot}tools/help/systrace.html">systrace</a> ツールを利用することをお勧めします。 - -</p> - - -<h3 id="resources">追加リソース</h3> - -<p> - Android のレンダリング パイプラインの仕組み、一般的な問題、それらの問題の修正方法についての詳細は、以下の資料が役に立ちます。 - - -</p> - -<ul> - <li>Rendering Performance 101 - </li> - <li>Why 60fps? - </li> - <li>Android UI and the GPU - </li> - <li>Invalidations Layouts and performance - </li> - <li>Analyzing UI Performance with Systrace - </li> -</ul> - - -<h2 id="automate">UI パフォーマンス テストを自動化する</h2> - -<p> - UI パフォーマンスのテスト手法の 1 つに、対象のアプリ上で一連のユーザー操作を人間のテスターに実行してもらい、目視でジャンクを探すかツール主体の手法を使用して長い時間を費やしてジャンクを見つけるかのいずれかの方法をとるというものがあります。 - -ただし、この人の力による方法は危険を伴います。フレームレートの変化に気付く能力は、人によって大きく異なります。また、この方法は、多くの時間が必要で単調で退屈なものであり、ミスも起こりがちです。 - - -</p> - -<p> - より効率的な手法は、自動化された UI テストにより主要なパフォーマンス指標のログを取って解析することです。 -Android M Developer Preview には、アプリケーションのアニメーションに対するジャンクの量と深刻度を簡単に確認することができ、現在のパフォーマンスを確認し将来のパフォーマンス目標を実現するための適切なプロセスを構築するために使用できる新しいログ記録機能が含まれています。 - - - -</p> - -<p> - このドキュメントでは、この新しいログ機能によるデータを使用してパフォーマンス テストを自動化するための手法について紹介します。 - -</p> - -<p> - この手法には、鍵となるアクションが 2 つあります。何をどのようにテストするかということを明確にすることと、自動化されたテスト環境をセットアップし管理することです。 - - -</p> - - -<h3 id="ui-tests">UI テストをセットアップする</h3> - -<p> - 自動化されたテストを実行する前に、テストの仕様や必要になる可能性があるものを適切に把握するために、いくつかの大まかな決定をしておくことが重要です。 - -</p> - -<h4> - テストする重要なアニメーションやフローを明確にする -</h4> - -<p> - パフォーマンスの低さがユーザーの目に最も多く触れるのは、アニメーションのスムーズさが失われる場合です。 -そのため、どのタイプの UI アクションをテストするか決めるときに、ユーザーが最もよく見る重要なアニメーションまたはユーザーの使用感にとって最も重要なアニメーションにフォーカスすると効果があります。 - -以下にいくつかの一般的なシナリオをご紹介します。 -</p> - -<ul> - <li>プライマリ ListView または RecyclerView のスクロール - </li> - - <li>非同期処理待ちサイクル中のアニメーション - </li> - - <li>ビットマップを読み込んだり操作したりするアニメーション - </li> - - <li>アルファブレンドを含むアニメーション - </li> - - <li>キャンバスを使用して描画するカスタムビュー - </li> -</ul> - -<p> - チームのエンジニア、デザイナー、プロダクト マネージャーと連携して、テスト範囲のこれらの重要な製品アニメーションの優先順位を決めてください。 - -</p> - -<h4> - 将来の目標を決め、実現を目指す -</h4> - -<p> - 具体的なパフォーマンス目標を明確にし、その目標に合わせてテストを作成しデータを収集することが重要な場合もあります。 -次に例を示します。 -</p> - -<ul> - <li>詳細を知るために、初めて UI パフォーマンスの追跡を開始したいだけですか。 - </li> - - <li>将来発生する可能性のあるパフォーマンスの低下を防止したいですか。 - </li> - - <li>現在のフレームのスムーズ度合いは 90% で、今四半期中に 98 % にしたいと考えていますか。 - </li> - - <li>現在のフレームのスムーズ度合い 98% を低下させたくないと考えていますか。 - </li> - - <li>ローエンド端末でのパフォーマンスを改善することが目標ですか。 - </li> -</ul> - -<p> - 上記のすべての場合で、複数のバージョンのアプリケーションでのパフォーマンスを示すヒストリカル トラッキングが必要です。 - -</p> - -<h4> - テストする端末を明確にする -</h4> - -<p> - アプリケーションのパフォーマンスは、そのアプリケーションが実行される端末によって異なります。端末によっては、メモリが少なく、GPU のパワーが低く、CPU チップが遅いものもあります。 -つまり、あるハードウェアでスムーズに実行できるアニメーションが別のハードウェアではうまく実行できなかったり、さらに悪い場合は、パイプラインの別の箇所にボトルネックを生んだりすることになります。 - -そのため、このようなハードウェアの違いに対処するために、最新のハイエンド端末と、ローエンド端末、タブレットなどの幅広い端末を選んでテストを実行する必要があります。 - -さまざまな CPU 性能、RAM、画面密度、サイズ等の端末を用意してください。 -ハイエンド端末でうまくいったテストが、ローエンド端末では失敗することがあります。 - -</p> - -<h4> - UI のテストの基本的なフレームワーク -</h4> - -<p> - <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a> や <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso</a> といったツールが、ユーザーがアプリケーション内を移動する動作を自動処理にするために用意されています。 - -これらは、端末でのユーザーの操作を模倣するシンプルなフレームワークです。 -これらのフレームワークを使用するには、一連のユーザー アクションを実行する独自のスクリプトを作成して、端末上で実行します。 - - -</p> - -<p> - <code>dumpsys gfxinfo</code> と、これらの自動化されたテストを組み合わせることで、テストを実行できる再現可能なシステムを簡単に作成して、特定の条件でのパフォーマンス情報を測定できます。 - - -</p> - - -<h3 id="automated-tests">自動化された UI テストをセットアップする</h3> - -<p> - UI テストを実行する機能と、1 つのテストからデータを集めるためのパイプラインを用意したら、次の重要なステップは、複数の端末で、そのテストを複数回実行でき、開発チームの解析用にパフォーマンス データを集計できるフレームワークを用意することです。 - - - -</p> - -<h4> - テスト自動化のためのフレームワーク -</h4> - -<p> - UI テストのフレームワーク(<a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a> など)は、対象の端末やエミュレータ上で直接実行されます。 -<em>dumpsys gfxinfo</em> によるパフォーマンス情報の収集はホストマシンによって行われますが、コマンドの送信は ADB を通じて行われます。 -これらの別々に分かれている処理の自動化を橋渡しするために、<a href="{@docRoot}tools/help/monkeyrunner_concepts.html">MonkeyRunner</a> フレームワークは開発されました。このフレームワークは、ホストマシンで動作するスクリプティング システムで、接続されている端末にコマンドを発行できるとともに、それらの端末からデータを受け取ることもできます。 - - - -</p> - -<p> - UI パフォーマンス テストの適切な自動化のためのスクリプトを作成することで、少なくとも、以下のタスクを MonkeyRunner を利用して実行することが可能になります。 - -</p> - -<ul> - <li>対象の端末(1 台または複数台)またはエミュレータに任意の APK をロードして起動する - </li> - - <li>UI Automator UI テストを起動して、実行できるようにする - </li> - - <li><em>dumpsys gfxinfo</em>を通じて情報を収集する。<em></em> - </li> - - <li>情報を集計し、デベロッパーに役に立つ形で表示する。 - </li> -</ul> - - -<h3 id="triage">見つけた問題を選別し解決する</h3> - -<p> - 問題のパターンまたはパフォーマンスの低下を確認したら、次に必要なことは問題の解決方法を見つけその方法を実行することです。 -その自動化されたテスト フレームワークがフレームの正確なタイミングの内訳を保存している場合、最近行われたコードやレイアウトの疑わしい変更を調べたり(パフォーマンスが低下している場合)、手作業での調査に切り替えたときにシステムのどの箇所を解析するか絞り込んだりするのに役立ちます。 - - -手作業での調査は、まず <a href="{@docRoot}tools/help/systrace.html">systrace</a> から開始することをお勧めします。systrace は、システムのレンダリング パイプラインのすべての段階、すべてのスレッド、コア、およびテスト担当者が定義したカスタム イベントについての正確なタイミング情報を表示します。 - - -</p> - -<h4> - 一時的なタイミングを適切にプロファイリングする -</h4> - -<p> - レンダリング パフォーマンスのタイミングを取得し測定することには困難を伴います。 -これらの数値は、その本質として、決定的なものではなく、多くの場合、システムの状態、利用可能なメモリ量、サーマル・スロットリング、その地域に最後に日照があった時間などに応じて変動します。 - -つまり同じテストを 2 度実行した場合、近似するが完全に同じではない、わずかに異なる結果が出ることがあるということです。 - - -</p> - -<p> - この方法で適切にデータを集めプロファイリングするには、同じテストを複数回実行し、結果を平均値または中間値として集計します(以下では、この処理を「バッチ」と記載します)。これにより、テストのパフォーマンスの大まかな数字を、正確なタイミングを必要とすることなく取得できます。 - - - -</p> - -<p> - バッチは、コード変更の合間にも、それらの変更がパフォーマンスにもたらす相対的な影響を確認するために使用できます。 -変更前のバッチの平均フレームレートが変更後のバッチよりも大きい場合、通常、WRT パフォーマンスが全面的に改善したと言えます。 - - -</p> - -<p> - つまり、自動化された UI テストでは、この考え方を取り入れることと、テスト中に発生する可能性のある異常を把握しておくことが必要です。 -たとえば、アプリケーションのパフォーマンスが、そのアプリケーションではなく何らかの端末の問題により突然低下した場合、通常時のタイミングを取得するためにバッチを再度実行した方がよいことがあります。 - - - -</p> - -<p> - それでは、測定値を意味のあるものにするには、何回テストを実行すればよいでしょうか。少なくとも 10 回は必要であり、50 回や 100 回などのように回数が多いほど正確な結果が得られます(もちろん、時間と正確さはトレードオフの関係にあります)。 - - -</p> diff --git a/docs/html-intl/intl/ja/sdk/index.jd b/docs/html-intl/intl/ja/sdk/index.jd new file mode 100644 index 000000000000..f7454c0b8ed6 --- /dev/null +++ b/docs/html-intl/intl/ja/sdk/index.jd @@ -0,0 +1,432 @@ +page.title=Android Studio と SDK Tools のダウンロード +page.tags=sdk, android studio +page.template=sdk +page.image=images/cards/android-studio_2x.png +header.hide=1 +page.metaDescription=公式 Android IDE とデベロッパー ツールをダウンロードして、Android 版のモバイル端末、タブレット、ウェアラブル端末、TV などの端末向けのアプリをビルドする。 + +@jd:body + +<style type="text/css"> + .offline {display:none;} + h2.feature { + padding-top:30px; + margin-top:0; + clear:both; + } + .feature-blurb { + margin:0px; font-size:16px; font-weight:300; + padding-top:40px; + } + + .landing-button .small { + font-size: 12px; + font-weight: normal; + line-height: 12px; + display: block; + } + + h1.studio-logo { + width:226px; + height:78px; + display:block; + padding:0; + white-space: nowrap; + text-indent: -10000px; + font-size:0px; + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); + background-size: 226px 78px; + } + +</style> + + + + + +<div style="position:relative;"> + + +<div class="wrap" id="tos" style="display:none;width:inherit;height:650px"> +<div class="col-13" style="margin:0;"> </div><!-- provides top margin for content --> + +<h1 id="tos-header" style="margin-top:0">ダウンロード</h1> + +<p class="sdk-terms-intro">Android Studio またはスタンドアロンの SDK Tools をインストールする前に、次の利用規約に同意する必要があります。 +</p> + +<div class="sdk-terms" onfocus="this.blur()"> +<h2 class="norule">利用規約</h2> +以下は、Android Software Development Kit の使用許諾契約です。 + + +<h3>1. Introduction</h3> +1.1 The Android Software Development Kit (referred to in the License Agreement as the "SDK" and specifically including the Android system files, packaged APIs, and Google APIs add-ons) is licensed to you subject to the terms of the License Agreement. The License Agreement forms a legally binding contract between you and Google in relation to your use of the SDK. + +1.2 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL: http://source.android.com/, as updated from time to time. + +1.3 A "compatible implementation" means any Android device that (i) complies with the Android Compatibility Definition document, which can be found at the Android compatibility website (http://source.android.com/compatibility) and which may be updated from time to time; and (ii) successfully passes the Android Compatibility Test Suite (CTS). + +1.4 "Google" means Google Inc., a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States. + + +<h3>2. Accepting this License Agreement</h3> +2.1 In order to use the SDK, you must first agree to the License Agreement. You may not use the SDK if you do not accept the License Agreement. + +2.2 By clicking to accept, you hereby agree to the terms of the License Agreement. + +2.3 You may not use the SDK and may not accept the License Agreement if you are a person barred from receiving the SDK under the laws of the United States or other countries, including the country in which you are resident or from which you use the SDK. + +2.4 If you are agreeing to be bound by the License Agreement on behalf of your employer or other entity, you represent and warrant that you have full legal authority to bind your employer or such entity to the License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the SDK on behalf of your employer or other entity. + + +<h3>3. SDK License from Google</h3> +3.1 Subject to the terms of the License Agreement, Google grants you a limited, worldwide, royalty-free, non-assignable, non-exclusive, and non-sublicensable license to use the SDK solely to develop applications for compatible implementations of Android. + +3.2 You may not use this SDK to develop applications for other platforms (including non-compatible implementations of Android) or to develop another SDK. You are of course free to develop applications for other platforms, including non-compatible implementations of Android, provided that this SDK is not used for that purpose. + +3.3 You agree that Google or third parties own all legal right, title and interest in and to the SDK, including any Intellectual Property Rights that subsist in the SDK. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you. + +3.4 You may not use the SDK for any purpose not expressly permitted by the License Agreement. Except to the extent required by applicable third party licenses, you may not: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the SDK or any part of the SDK; or (b) load any part of the SDK onto a mobile handset or any other hardware device except a personal computer, combine any part of the SDK with other software, or distribute any software or device incorporating a part of the SDK. + +3.5 Use, reproduction and distribution of components of the SDK licensed under an open source software license are governed solely by the terms of that open source software license and not the License Agreement. + +3.6 You agree that the form and nature of the SDK that Google provides may change without prior notice to you and that future versions of the SDK may be incompatible with applications developed on previous versions of the SDK. You agree that Google may stop (permanently or temporarily) providing the SDK (or any features within the SDK) to you or to users generally at Google's sole discretion, without prior notice to you. + +3.7 Nothing in the License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features. + +3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the SDK. + + +<h3>4. Use of the SDK by You</h3> +4.1 Google agrees that it obtains no right, title or interest from you (or your licensors) under the License Agreement in or to any software applications that you develop using the SDK, including any intellectual property rights that subsist in those applications. + +4.2 You agree to use the SDK and write applications only for purposes that are permitted by (a) the License Agreement and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries). + +4.3 You agree that if you use the SDK to develop applications for general public users, you will protect the privacy and legal rights of those users. If the users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If the user provides your application with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, the user has given you permission to do so. + +4.4 You agree that you will not engage in any activity with the SDK, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of any third party including, but not limited to, Google or any mobile communications carrier. + +4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android and/or applications for Android, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so. + +4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under the License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach. + + +<h3>5. Your Developer Credentials</h3> +5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials. + + +<h3>6. Privacy and Information</h3> +6.1 In order to continually innovate and improve the SDK, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the SDK are being used and how they are being used. Before any of this information is collected, the SDK will notify you and seek your consent. If you withhold consent, the information will not be collected. + +6.2 The data collected is examined in the aggregate to improve the SDK and is maintained in accordance with Google's Privacy Policy. + + +<h3>7. Third Party Applications</h3> +7.1 If you use the SDK to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources. + +7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners. + +7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party. In that case, the License Agreement does not affect your legal relationship with these third parties. + + +<h3>8. Using Android APIs</h3> +8.1 Google Data APIs + +8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service. + +8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so. + + +<h3>9. Terminating this License Agreement</h3> +9.1 The License Agreement will continue to apply until terminated by either you or Google as set out below. + +9.2 If you want to terminate the License Agreement, you may do so by ceasing your use of the SDK and any relevant developer credentials. + +9.3 Google may at any time, terminate the License Agreement with you if: +(A) you have breached any provision of the License Agreement; or +(B) Google is required to do so by law; or +(C) the partner with whom Google offered certain parts of SDK (such as APIs) to you has terminated its relationship with Google or ceased to offer certain parts of the SDK to you; or +(D) Google decides to no longer provide the SDK or certain parts of the SDK to users in the country in which you are resident or from which you use the service, or the provision of the SDK or certain SDK services to you by Google is, in Google's sole discretion, no longer commercially viable. + +9.4 When the License Agreement comes to an end, all of the legal rights, obligations and liabilities that you and Google have benefited from, been subject to (or which have accrued over time whilst the License Agreement has been in force) or which are expressed to continue indefinitely, shall be unaffected by this cessation, and the provisions of paragraph 14.7 shall continue to apply to such rights, obligations and liabilities indefinitely. + + +<h3>10. DISCLAIMER OF WARRANTIES</h3> +10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SDK IS AT YOUR SOLE RISK AND THAT THE SDK IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE. + +10.2 YOUR USE OF THE SDK AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE SDK IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE. + +10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + + +<h3>11. LIMITATION OF LIABILITY</h3> +11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING. + + +<h3>12. Indemnification</h3> +12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys fees) arising out of or accruing from (a) your use of the SDK, (b) any application you develop on the SDK that infringes any copyright, trademark, trade secret, trade dress, patent or other intellectual property right of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you with the License Agreement. + + +<h3>13. Changes to the License Agreement</h3> +13.1 Google may make changes to the License Agreement as it distributes new versions of the SDK. When these changes are made, Google will make a new version of the License Agreement available on the website where the SDK is made available. + + +<h3>14. General Legal Terms</h3> +14.1 The License Agreement constitutes the whole legal agreement between you and Google and governs your use of the SDK (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the SDK. + +14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in the License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google. + +14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of the License Agreement is invalid, then that provision will be removed from the License Agreement without affecting the rest of the License Agreement. The remaining provisions of the License Agreement will continue to be valid and enforceable. + +14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to the License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to the License Agreement. + +14.5 EXPORT RESTRICTIONS. THE SDK IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE SDK. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE. + +14.6 The rights granted in the License Agreement may not be assigned or transferred by either you or Google without the prior written approval of the other party. Neither you nor Google shall be permitted to delegate their responsibilities or obligations under the License Agreement without the prior written approval of the other party. + +14.7 The License Agreement, and your relationship with Google under the License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from the License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction. + +<em>November 20, 2015</em> +</div> + + + + + +<div id="next-steps" style="display:none;position:absolute;width:inherit"> + <p>数ステップで、Android 向けアプリのビルドを開始できます。</p> + <p>まもなく、<a id="next-link" href="{@docRoot}sdk/installing/index.html">Installing the Android SDK</a>へリダイレクトします。 +</p> + +</div><!-- end next-steps --> + + + +<div id="sdk-terms-form"> +<p> +<input id="agree" type="checkbox" name="agree" value="1" onclick="onAgreeChecked()" /> +<label id="agreeLabel" for="agree">上記の利用規約を読み、同意します。</label> +</p> +<p><a href="" class="button disabled" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p> +</div> + + +</div><!-- end TOS --> + + + + + + +<div id="landing"> + +<div class="col-13"> </div><!-- provides top margin for content --> + +<img src="{@docRoot}images/tools/studio-hero.png" srcset="{@docRoot}images/tools/studio-hero_2x.png 2x, {@docRoot}images/tools/studio-hero.png 1x" width="760" height="400" /> + + +<div style="color: #fff; width:226px; height:0; overflow:visible; position:absolute; top:40px; left:25px"> + +<h1 class="studio-logo" style="margin:0 0 35px !important">Android Studio</h1> + +<p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; +width: 400px;text-align: center;">公式 Android IDE</p> + +<ul style="font-size:12px;line-height:19px;"> +<li>Android Studio IDE</li> +<li>Android SDK Tools</li> +<li>Android 6.0(Marshmallow)プラットフォーム</li> +<li>Google API を使用した Android 6.0 エミュレータのシステム イメージ</li> +</ul> + +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> + +<!-- this appears when viewing the offline docs --> +<p class="offline"> +Android Studio または スタンドアロンの SDK Tools を入手するには、<a href="http://developer.android.com/sdk/index.html">developer.android.com/sdk/</a> へアクセスしてください。 +</p> +</div> + +<ul> + <li><a href="#Requirements">システム要件</a></li> + <li><a href="#Other">他のダウンロード オプション</a></li> + <li><a href="{@docRoot}sdk/installing/migrate.html">Android Studio への移行</a></li> + <li><a href="https://docs.google.com/a/google.com/forms/d/1mjsyfzv3HAnDY-_Kfj-3QJKdpuksyMFs9e73CRwmT6Q/viewform" target="_blank">アンケートに回答する</a></li> +</ul> + + + + + +<div class="cols"> +<h2 class="feature norule col-13" >インテリジェント コード エディタ</h2> + +<div class="col-9"> + <img src="{@docRoot}images/tools/studio-hero-code.png" srcset="{@docRoot}images/tools/studio-hero-code_2x.png 2x, {@docRoot}images/tools/studio-hero-code.png 1x" width="520" /> +</div><!-- end col-9 (left column) --> + +<div class="col-4 feature-blurb"> + <p>Android Studio の中核であるインテリジェント コード エディタは、高度なコード補完機能、リファクタリング機能、解析機能を備えています。 +</p> + <p>このパワフルなコード エディタは、Android アプリ デベロッパーの生産性を高めます。</p> +</div> + + + + + +<h2 class="feature norule">コード テンプレートと GitHub との統合</h2> + +<div class="col-9"> + <img src="{@docRoot}images/tools/studio-hero-import.png" srcset="{@docRoot}images/tools/studio-hero-import_2x.png 2x, {@docRoot}images/tools/studio-hero-import.png 1x" width="520" /> +</div><!-- end col-9 (left column) --> + +<div class="col-4 feature-blurb"> + <p>新しいプロジェクト ウィザードでは、これまで以上に簡単に新規プロジェクトを開始できます。</p> + + <p>ナビゲーション ドロワーやビュー ページャーなどのパターンにテンプレート コードを使用してプロジェクトを開始できます。加えて GitHub から Google のコード サンプルをインポートできます。 +</p> +</div> + + + + +<h2 class="feature norule">マルチスクリーン アプリの開発</h2> + +<div class="col-9"> + <img src="{@docRoot}images/tools/studio-hero-screens.png" srcset="{@docRoot}images/tools/studio-hero-screens_2x.png 2x, {@docRoot}images/tools/studio-hero-screens.png 1x" width="520" /> +</div><!-- end col-9 (left column) --> + +<div class="col-4 feature-blurb"> + <p>Android 携帯電話、タブレット、Android Wear、Android TV、Android Auto、Google Glass 向けのアプリをビルドできます。 +</p> + <p>Android Studio の新しい Android プロジェクト ビューとモジュールのサポートによって、アプリのプロジェクト管理やリソース管理がさらに簡単になります。 + +</div> + + + + +<h2 class="feature norule">あらゆる形状の端末をサポートする仮想デバイス</h2> + +<div class="col-9"> + <img src="{@docRoot}images/tools/studio-hero-avds.png" srcset="{@docRoot}images/tools/studio-hero-avds_2x.png 2x, {@docRoot}images/tools/studio-hero-avds.png 1x" width="520" /> +</div><!-- end col-9 (left column) --> + +<div class="col-4 feature-blurb"> + <p>Android Studio には最適化されたエミュレータ イメージが事前構成されています。</p> + <p>アップデートされ合理化された仮想デバイス マネージャーには、一般的な Android 端末向けにあらかじめ定義されたプロファイルが用意されています。 +</p> +</div> + + + + +<h2 class="feature norule"> +Gradle で進化する Android のビルド</h2> + +<div class="col-9"> + <img src="{@docRoot}images/tools/studio-hero-gradle.png" srcset="{@docRoot}images/tools/studio-hero-gradle_2x.png 2x, {@docRoot}images/tools/studio-hero-gradle.png 1x" width="520" /> +</div><!-- end col-9 (left column) --> + +<div class="col-4 feature-blurb"> + <p>1 つのプロジェクトで、Android アプリのための、異なる機能を持つ複数の APK を作成できます。</p> + <p>Maven を使用してアプリの依存関係を管理します。</p> + <p>APK は Android Studio でもコマンドラインでもビルドできます。</p> +</div> + + + +<h2 class="feature norule">Android Studio のその他の特徴</h2> +<div style="background:#424242;padding:30px; color:#fff;margin:0 0 15px;"> + +<a class="online landing-button green download-bundle-button" style="margin:0 0 40px 60px;float:right" href="">Download</a> + + <ul> + <li>人気の高い JetBrains の Java IDE である IntelliJ IDEA Community Edition が基盤</li> + <li>Gradle ベースの柔軟なビルドシステム</li> + <li>ビルド バリアントと複数の APK 生成機能</li> + <li>Google サービスやさまざまな端末向けのテンプレート サポートの拡充</li> + <li>テーマの編集が可能なレイアウト エディタ</li> + <li>パフォーマンス、ユーザビリティ、バージョン互換性、その他の問題を検出する Lint ツール</li> + <li>ProGuard とアプリの署名機能</li> + <li>Google Cloud Messaging や App Engine との統合をサポートする Google Cloud プラットフォームの組み込みサポート +</li> + </ul> + +<p style="margin:0"> +Android Studio の機能の詳細については、「<a href="{@docRoot}tools/studio/index.html">Android Studio の基礎</a>」をご覧ください。 +</p> +</div> + + +<p>Eclipse で ADT を使用している場合、Android Studio が Android の公式 IDE になったため、Android Studio に移行して IDE の最新アップデートを入手する必要があります。 + +プロジェクトの移行については、「<a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android Studio</a>」をご覧ください。 + +</p> + + + + + + + +<h2 id="Requirements">システム要件</h2> + +<h3>Windows の場合</h3> + +<ul> +<li>Microsoft® Windows® 8/7/Vista/2003(32-bit 版または 64-bit 版)</li> +<li>2 GB 以上のシステム メモリ(RAM)、4 GB 以上を推奨</li> +<li>400 MB の空き容量のあるハードディスク</li> +<li>Android SDK、エミュレータのシステム イメージ、キャッシュ用には少なくとも 1 GB 以上</li> +<li>1280 x 800 以上の画面解像度</li> +<li>Java Development Kit (JDK) 7 </li> +<li>エミュレータ アクセラレータ向け(任意): Intel® VT-x、Intel® EM64T(Intel® 64)、Execute Disable(XD)ビット機能対応の Intel® プロセッサ +</li> +</ul> + + +<h3>Mac OS X の場合</h3> + +<ul> +<li>Mac ®OS X® 10.8.5 以降、10.9(Mavericks)まで</li> +<li>2 GB 以上のシステム メモリ(RAM)、4 GB 以上を推奨</li> +<li>400 MB の空き容量のあるハードディスク</li> +<li>Android SDK、エミュレータのシステム イメージ、キャッシュ用には少なくとも 1 GB 以上</li> +<li>1280 x 800 以上の画面解像度</li> +<li>Java Runtime Environment (JRE) 6</li> +<li>Java Development Kit (JDK) 7</li> +<li>エミュレータ アクセラレータ向け(任意): Intel® VT-x、Intel® EM64T(Intel® 64)、Execute Disable(XD)ビット機能対応の Intel® プロセッサ +</li> +</ul> + +<p>Mac OSで最適化されたフォントのレンダリングを使用するには、Android Studio を Java Runtime Environment (JRE) 6 と共に実行する必要があります。 +その後、Java Development Kit(JDK)6 または JDK 7 を使用するようプロジェクトを構成できます。</p> + + + +<h3>Linux の場合</h3> + +<ul> +<li>GNOME または KDE デスクトップ</li> +<li>GNU C Library (glibc) 2.15 以降</li> +<li>2 GB 以上のシステム メモリ(RAM)、4 GB 以上を推奨</li> +<li>400 MB の空き容量のあるハードディスク</li> +<li>Android SDK、エミュレータのシステム イメージ、キャッシュ用には少なくとも 1 GB 以上</li> +<li>1280 x 800 以上の画面解像度</li> +<li>Oracle® Java Development Kit (JDK) 7 </li> +</ul> +<p>Ubuntu® 14.04、Trusty Tahr(32-bit 版アプリケーションを実行可能な 64-bit 版)でテスト済み。 +</p> + + + + +<h2 id="Other" style="clear:left">他のダウンロード オプション</h2> + +<!-- alternative SDK options follows --> diff --git a/docs/html-intl/intl/ja/sdk/installing/adding-packages.jd b/docs/html-intl/intl/ja/sdk/installing/adding-packages.jd new file mode 100644 index 000000000000..af5dcd0a4989 --- /dev/null +++ b/docs/html-intl/intl/ja/sdk/installing/adding-packages.jd @@ -0,0 +1,227 @@ +page.title=SDK パッケージの追加 + +page.tags=sdk manager +helpoutsWidget=true + +@jd:body + +<style> +ol.large { + margin-left:0; +} +ol.large > li { + list-style-position: inside; + list-style-type:none; + margin:30px 0 0 0; + padding:30px 20px; + background:#eee; +} +ol.large > li:nth-child(odd) { +} +ol.large > li:before { + display:inline; + left:-40px; + float:left; + width:20px; + font-size:20px; + line-height:20px; +} +ol.large > li > h2 { + font-size:20px; + line-height:20px; + padding:0 0 0 20px; + margin:0 0 20px 0; + display:inline; + font-weight:normal; +} +ol.large > li:nth-child(1):before { + content:"1. "; +} +ol.large > li:nth-child(2):before { + content:"2. "; +} +ol.large > li:nth-child(3):before { + content:"3. "; +} +ol.large > li:nth-child(4):before { + content:"4. "; +} +ol.large > li:nth-child(5):before { + content:"5. "; +} +ol.large > li:nth-child(6):before { + content:"6. "; +} +</style> + + +<p> +Android SDK では、デフォルトの状態で、開発の開始に必要なすべてのものが用意されているわけではありません。 +Android SDK では、ツール、プラットフォーム、その他のコンポーネントがパッケージに分けられており、<a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a> を使って必要に応じてダウンロードできます。 + + +そのため、開始前に、Android SDK にいくつかのパッケージを追加する必要があります。</p> + +<p>パッケージの追加を開始するには、次のいずれかの方法で Android SDK Manager を起動します。</p> +<ul> + <li>Android Studio で、ツールバーの [<strong>SDK Manager</strong>] <img src="{@docRoot}images/tools/sdk-manager-studio.png" style="vertical-align:bottom;margin:0;height:17px" /> をクリックします。 +</li> + <li>Android Studio を使用しない場合: + <ul> + <li>Windows の場合: Android SDK のルート ディレクトリにある <code>SDK Manager.exe</code> ファイルをダブルクリックします。 +</li> + <li>Mac または Linux の場合: ターミナルを開いて Android SDK がインストールされているロケーションの <code>tools/</code> ディレクトリに移動し、<code>android sdk</code> を実行します。 +</li> + </ul> + </li> +</ul> + +<p>SDK Manager を初めて開く場合、いくつかのパッケージがデフォルトで選択されています。 +この選択はそのままにしますが、開始に必要なすべてのものが揃っているか、次の手順でご確認ください。 +</p> + + +<ol class="large"> +<li> + <h2 id="GetTools" class="norule">最新の SDK Tools を入手する</h2> + +<img src="/images/sdk_manager_packages.png" alt="" width="350" style="float:right;margin-left:20px" /> + + <p>Android SDK をセットアップする場合、少なくとも最新の SDK Tools と Android プラットフォームのダウンロードが必要です。 +</p> + <ol> + <li>[Tools] ディレクトリを開き、以下のツールを選択します。 + <ul> + <li><strong>Android SDK Tools</strong></li> + <li><strong>Android SDK Platform-tools</strong></li> + <li><strong>Android SDK Build-tools</strong>(最新バージョンのもの)</li> + </ul> + </li> + <li>1 番上の [Android X.X] フォルダ(最新バージョンのフォルダ)を開き、以下を選択します。 + <ul> + <li><strong>SDK Platform</strong></li> + <li>「<strong>ARM EABI v7a System Image</strong>」などのエミュレータ用のシステム イメージ<br> +</li> + </ul> + </li> + </ol> +</li> + +<li> + <h2 id="GetSupportLib" class="norule">追加 API 用のサポート ライブラリを取得する</h2> + + <div class="sidebox"> + <p>以下を使用するには、サポート ライブラリが必要です。</p> + <ul> + <li><a href="{@docRoot}wear/index.html">Android Wear</a></li> + <li><a href="{@docRoot}tv/index.html">Android TV</a></li> + <li><a href="{@docRoot}google/play-services/cast.html">Google Cast</a></li> + </ul> + + <p>サポート ライブラリは、以下の人気の API も提供しています。</p> + <ul> + <li><a href="{@docRoot}reference/android/support/v4/widget/DrawerLayout.html">ナビゲーション ドロワー</a> +</li> + <li><a href="{@docRoot}reference/android/support/v4/view/ViewPager.html">スワイプビュー</a></li> + <li><a href="{@docRoot}reference/android/support/v7/app/ActionBar.html">下位互換のアクションバー</a> +</li> + </ul> + </div> + + <p><a href="{@docRoot}tools/support-library/features.html">Android サポート ライブラリ</a> は、大部分のバージョンの Android に対応する API の拡張セットを提供しています。 +</p> + + <p>[<strong>Extras</strong>] ディレクトリを開き、以下を選択します。</p> + <ul> + <li><strong>Android Support Repository</strong></li> + <li><strong>Android Support Library</strong></li> + </ul> + + <p> </p> + <p> </p> + +</li> + + +<li> + <h2 id="GetGoogle" class="norule">その他の API 用の Google Play サービスを入手する</h2> + + <div class="sidebox"> + + <p>Google Play services API は、Android アプリのための次のようなバラエティに富んだ機能やサービスを提供しています。 +</p> + <ul> + <li><a href="{@docRoot}google/play-services/plus.html">ユーザー認証</a></li> + <li><a href="{@docRoot}google/play-services/maps.html">Google マップ</a></li> + <li><a href="{@docRoot}google/play-services/cast.html">Google Cast</a></li> + <li><a href="{@docRoot}google/play-services/games.html">ゲームの実績とリーダーボード</a> +</li> + <li><a href="{@docRoot}google/play-services/index.html">その他多数の機能</a></li> + </ul> + </div> + + <p>Google API を利用して開発を行うには、Google Play サービス パッケージが必要です。</p> + <p>[<strong>Extras</strong>] ディレクトリを開き、以下を選択します。</p> + <ul> + <li><strong>Google Repository</strong></li> + <li><strong>Google Play サービス</strong></li> + </ul> + + <p class="note"><strong>注:</strong> Google Play services API は、Android が搭載されたすべての端末で利用できるわけではありませんが、Google Play ストアを使用するとすべての端末で利用できます。 +これらの API を Android エミュレータで使用するには、SDK Manager の最新の [Android X.X] ディレクトリから <strong>Google API</strong> のシステム イメージもインストールする必要があります。 + +</p> +</li> + + +<li> + <h2 id="Install" class="norule">パッケージをインストールする</h2> + <p>必要なパッケージをすべて選択したら、インストールを続行します。</p> + <ol> + <li>[<strong>Install X packages</strong>] をクリックします。</li> + <li>次のウィンドウで、左側のパッケージ名を 1 つずつダブルクリックし、各パッケージの使用許諾契約に同意します。 +</li> + <li>[<strong>Install</strong>] をクリックします。</li> + </ol> + <p>SDK Manager のウィンドウの 1 番下に、ダウンロードの進捗状況が表示されます。 + <strong>SDK Manager を終了しないでください</strong>。SDK Manager を終了すると、ダウンロードはキャンセルされます。</p> +</li> + +<li> + <h2 id="Build" class="norule">アプリを作成する</h2> + +<p>Android SDK にインストールしたパッケージを使用して、アプリを作成できるようになりました。 +新しいツールとその他の API を入手できるようになった場合は、SDK Manager を起動して SDK に新しいパッケージをダウンロードしてください。 +</p> + +<p>必要に応じて以下を参考にしてください。</p> + +<div class="cols" style="padding:10px 0"> +<div class="col-4"> +<h3>スタートガイド</h3> +<p>Android 開発が初めての場合は、Android アプリの基本を<strong><a href="{@docRoot}training/basics/firstapp/index.html">初めてのアプリ作成</a></strong>に関するガイドに従って学習してください。 +</p> + +</div> +<div class="col-4 box"> +<h3>ウェアラブル端末向けにアプリを作成する</h3> +<p>Android ウェアラブル端末向けにアプリを開発するには、「<strong><a href="{@docRoot}wear/preview/start.html">Android Wear アプリの作成</a></strong>」のガイドをご覧ください。 +</p> + +</div> +<div class="col-4 box"> +<h3>Google API を使用する</h3> +<p>マップや Play ゲーム サービスなどの Google API の使用を開始するには、「<strong><a href="{@docRoot}google/play-services/setup.html">Setting Up Google Play Services</a></strong>」のガイドをご覧ください。 + + +</p> + +</div> +</div><!-- end cols --> + + +</li> + +</ol> + + diff --git a/docs/html-intl/intl/ja/training/material/animations.jd b/docs/html-intl/intl/ja/training/material/animations.jd new file mode 100644 index 000000000000..460147cb6260 --- /dev/null +++ b/docs/html-intl/intl/ja/training/material/animations.jd @@ -0,0 +1,550 @@ +page.title=カスタム アニメーションの定義 + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#Touch">タッチ フィードバックをカスタマイズする</a></li> + <li><a href="#Reveal">出現エフェクトを使用する</a></li> + <li><a href="#Transitions">アクティビティ遷移をカスタマイズする</a></li> + <li><a href="#ViewState">ビューの状態遷移にアニメーションを付ける</a></li> + <li><a href="#AnimVector">ベクター型ドローアブルにアニメーションを付ける</a></li> +</ol> +<h2>関連ドキュメント</h2> +<ul> + <li><a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a></li> + <li><a href="{@docRoot}design/material/index.html">Android でのマテリアル デザイン</a></li> +</ul> +</div> +</div> + + +<p>マテリアル デザインのアニメーションは、ユーザーの操作に応じて反応し、アプリの操作にともない連続した動きを見せます。 +マテリアル テーマでは、ボタンやアクティビティの遷移にデフォルトのアニメーションが用意されており、Android 5.0(API レベル 21)以降では次のようなアニメーションをカスタマイズして新しいアニメーションを作成できます。 + +</p> + +<ul> +<li>タッチ フィードバック</li> +<li>円形状の出現</li> +<li>アクティビティ遷移</li> +<li>曲線モーション</li> +<li>ビューの状態遷移</li> +</ul> + + +<h2 id="Touch">タッチ フィードバックをカスタマイズする</h2> + +<p>マテリアル デザインのタッチ フィードバックは、ユーザーが UI 要素に触れて操作した時点で、視覚的な反応を瞬時に表します。 +ボタンに対するデフォルトのタッチ フィードバック アニメーションでは、新しい {@link android.graphics.drawable.RippleDrawable} クラスを使用して、状態の切り替わりをリップル(波紋)効果で表現しています。 + +</p> + +<p>ほとんどの場合、次のようにビューの背景を指定することでビュー XML にこの機能を適用できます。 +</p> + +<ul> +<li>範囲が限定された波紋: <code>?android:attr/selectableItemBackground</code>。</li> +<li>ビューの範囲外まで広がる波紋: <code>?android:attr/selectableItemBackgroundBorderless</code>。 +これは、背景が null ではない最も近くにある親ビュー上に表示されますが、その外側にはみ出ることはありません。 +</li> +</ul> + +<p class="note"><strong>注:</strong> <code>selectableItemBackgroundBorderless</code> は API レベル 21 で導入された新しい属性です。 +</p> + + +<p>または、<code>ripple</code> 要素を使って {@link android.graphics.drawable.RippleDrawable} +を XML リソースとしても定義できます。</p> + +<p>{@link android.graphics.drawable.RippleDrawable} オブジェクトには、色を割り当てることができます。タッチ フィードバックのデフォルトの色を変更するには、テーマの <code>android:colorControlHighlight</code> +属性を使用します。 +</p> + +<p>詳細については、API リファレンスの {@link +android.graphics.drawable.RippleDrawable} クラスをご覧ください。</p> + + +<h2 id="Reveal">出現エフェクトを使用する</h2> + +<p>Reveal(出現)アニメーションを使用すると、UI 要素のグループを表示したり非表示にしたりするときに連続した印象をユーザーに与えます。 +{@link android.view.ViewAnimationUtils#createCircularReveal +ViewAnimationUtils.createCircularReveal()} メソッドでは、ビューを表示したり非表示にしたりする際に円形のアニメーションを付けることができます。 +</p> + +<p>この効果を使って、非表示のビューを表示するには:</p> + +<pre> +// previously invisible view +View myView = findViewById(R.id.my_view); + +// get the center for the clipping circle +int cx = (myView.getLeft() + myView.getRight()) / 2; +int cy = (myView.getTop() + myView.getBottom()) / 2; + +// get the final radius for the clipping circle +int finalRadius = Math.max(myView.getWidth(), myView.getHeight()); + +// create the animator for this view (the start radius is zero) +Animator anim = + ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius); + +// make the view visible and start the animation +myView.setVisibility(View.VISIBLE); +anim.start(); +</pre> + +<p>この効果を使って、表示されているビューを非表示にするには: </p> + +<pre> +// previously visible view +final View myView = findViewById(R.id.my_view); + +// get the center for the clipping circle +int cx = (myView.getLeft() + myView.getRight()) / 2; +int cy = (myView.getTop() + myView.getBottom()) / 2; + +// get the initial radius for the clipping circle +int initialRadius = myView.getWidth(); + +// create the animation (the final radius is zero) +Animator anim = + ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); + +// make the view invisible when the animation is done +anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + myView.setVisibility(View.INVISIBLE); + } +}); + +// start the animation +anim.start(); +</pre> + + +<h2 id="Transitions">アクティビティ遷移をカスタマイズする</h2> + +<!-- shared transition video --> +<div style="width:290px;margin-left:35px;float:right"> + <div class="framed-nexus5-port-span-5"> + <video class="play-on-hover" autoplay=""> + <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"> + <source src="{@docRoot}design/material/videos/ContactsAnim.webm"> + <source src="{@docRoot}design/material/videos/ContactsAnim.ogv"> + </video> + </div> + <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> + <p class="img-caption" style="margin-top:3px;margin-bottom:10px"><strong>図 1</strong> - 共有要素を使った画面遷移。 +</p> + <em>端末の画像をクリックすると動画を再生できます</em> + </div> +</div> + +<p>マテリアル デザイン アプリの Activity transitions (アクティビティ遷移)では、共通する要素の間での動作や変化を通じて、状態の切り替えに視覚的なつながりを持たせます。 +Enter と Exit の遷移や、アクティビティ間での Shared elements 遷移にカスタム アニメーションを指定できます。 +</p> + +<ul> +<li><strong>Enter</strong>(入口)遷移は、アクティビティのビューがどのように画面に入ってくるかを決定します。 +たとえば <em>Explode</em> の Enter 遷移の場合、ビューが画面外から画面の中心に向かって飛び込むように現れます。 +</li> + +<li><strong>Exit</strong> 遷移は、アクティビティのビューがどのように画面から出ていくかを決定します。同じく <em>Explode</em> の Exit 遷移の場合、画面の中心から外側に向かってビューが出ていきます。 + +</li> + +<li><strong>Shared Elements</strong> 遷移は、2 つのアクティビティで共有されているビューが、各アクティビティの間でどのように遷移するかを決定します。 +たとえば、2 つのアクティビティで同じ画像を異なる位置とサイズで使用している場合、<em>changeImageTransform</em> 共有要素の遷移によって、2 つのアクティビティの間でスムーズに画像が変換されスケーリングされます。 + +</li> +</ul> + +<p>Android 5.0(API レベル 21)では、次の Enter 遷移と Exit 遷移がサポートされています。</p> + +<ul> +<li><em>explode</em> (爆発状) - ビューをシーン中心から外側へ移動したり外側から中心へ移動したりします。</li> +<li><em>slide</em> (スライド) - ビューをシーンの端から移動したり端へ移動したりします。</li> +<li><em>fade</em> (フェード) - 不透明度を変化させながらビューをシーンに追加したりシーンから削除したりします。</li> +</ul> + +<p>{@link android.transition.Visibility} クラスを拡張する Transition はすべて、EnterTransition または ExitTransition としてサポートされます。 +詳細については、API リファレンスの +{@link android.transition.Transition} クラスをご覧ください。</p> + +<p>Android 5.0(API レベル 21)では、次の共有要素遷移もサポートしています。</p> + +<ul> +<li><em>changeBounds</em> - 対象ビューのレイアウト範囲での変化にアニメーションを付けます。</li> +<li><em>changeClipBounds</em> - 対象ビューのクリップ範囲での変化にアニメーションを付けます。</li> +<li><em>changeTransform</em> - 対象ビューのスケールや向きの変化にアニメーションを付けます。</li> +<li><em>changeImageTransform</em> - 対象画像のサイズやスケールの変化にアニメーションを付けます。</li> +</ul> + +<p>アプリにアクティビティ遷移を適用すると、アクティビティの開始と終了の間でデフォルトのクロス フェーディング遷移が有効になります。 +</p> + +<img src="{@docRoot}training/material/images/SceneTransition.png" alt="" width="600" height="405" style="margin-top:20px" /> +<p class="img-caption"> + <strong>図 2</strong> - 1 つの共有要素とシーンの遷移。 +</p> + +<h3>カスタム遷移を指定する</h3> + +<p>まず、マテリアル テーマから継承したスタイルを定義するときに、<code>android:windowContentTransitions</code> + 属性で windowContentTransitions を有効にします。また、次のように Enter、Exit、Shared Element の Transitions をスタイルの定義で指定できます。 +</p> + +<pre> +<style name="BaseAppTheme" parent="android:Theme.Material"> + <!-- enable window content transitions --> + <item name="android:windowContentTransitions">true</item> + + <!-- specify enter and exit transitions --> + <item name="android:windowEnterTransition">@transition/explode</item> + <item name="android:windowExitTransition">@transition/explode</item> + + <!-- specify shared element transitions --> + <item name="android:windowSharedElementEnterTransition"> + @transition/change_image_transform</item> + <item name="android:windowSharedElementExitTransition"> + @transition/change_image_transform</item> +</style> +</pre> + +<p>この例の <code>change_image_transform</code> 遷移は、次のように定義されています。</p> + +<pre> +<!-- res/transition/change_image_transform.xml --> +<!-- (see also Shared Transitions below) --> +<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> + <changeImageTransform/> +</transitionSet> +</pre> + +<p><code>changeImageTransform</code> 要素は +{@link android.transition.ChangeImageTransform} クラスに対応します。詳細については、API リファレンスの {@link android.transition.Transition} をご覧ください。 +</p> + +<p>代わりに、コードで windowContentTransitions を有効にするには、 +{@link android.view.Window#requestFeature Window.requestFeature()} メソッドを呼び出します。</p> + +<pre> +// inside your activity (if you did not enable transitions in your theme) +getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); + +// set an exit transition +getWindow().setExitTransition(new Explode()); +</pre> + +<p>コードで遷移を指定するには、{@link +android.transition.Transition} オブジェクトで次のメソッドを呼び出します。</p> + +<ul> + <li>{@link android.view.Window#setEnterTransition Window.setEnterTransition()}</li> + <li>{@link android.view.Window#setExitTransition Window.setExitTransition()}</li> + <li>{@link android.view.Window#setSharedElementEnterTransition + Window.setSharedElementEnterTransition()}</li> + <li>{@link android.view.Window#setSharedElementExitTransition + Window.setSharedElementExitTransition()}</li> +</ul> + +<p>{@link android.view.Window#setExitTransition setExitTransition()} と {@link +android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} メソッドは、呼び出し元のアクティビティの ExitTransition を定義します。 +{@link android.view.Window#setEnterTransition +setEnterTransition()} と {@link android.view.Window#setSharedElementEnterTransition +setSharedElementEnterTransition()} メソッドは、呼び出し先のアクティビティの EnterTransition を定義します。</p> + +<p>遷移の効果を完全に表すには、呼び出し元と呼び出し先のアクティビティ双方で windowContentTransitions を有効にする必要があります。 +有効にしていないと、呼び出し元のアクティビティが Exit 遷移を開始したあと、window 遷移(スケールやフェードなど)が起きます。 +</p> + +<p>Enter 遷移をできるだけ早く開始するには、呼び出し先のアクティビティで +{@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()} + メソッドを使用します。これにより、さらに印象的な Enter 遷移になります。</p> + +<h3>遷移を使ってアクティビティを開始する</h3> + +<p>遷移を有効にしてアクティビティで ExitTransition を設定した場合、次のように別のアクティビティを開始したときに Exit 遷移がアクティベートされます。 +</p> + +<pre> +startActivity(intent, + ActivityOptions.makeSceneTransitionAnimation(this).toBundle()); +</pre> + +<p>2 つ目のアクティビティに EnterTransition を設定している場合は、そのアクティビティの開始時に Enter 遷移も発生します。 +別のアクティビティ開始時の遷移を無効にするには、<code>null</code> のオプション バンドルを付与します。 +</p> + +<h3>共有要素を使ってアクティビティを開始する</h3> + +<p>共有要素を持つ 2 つのアクティビティの間で画面遷移のアニメーションを作成するには: </p> + +<ol> +<li>テーマで windowContentTransitions を有効にします。</li> +<li>スタイルで SharedElementsTransition を指定します。</li> +<li>遷移を XML リソースとして定義します。</li> +<li> +<code>android:transitionName</code> 属性を用いて、双方のレイアウトで共有要素に同じ名前を割り当てます。</li> +<li>{@link android.app.ActivityOptions#makeSceneTransitionAnimation +ActivityOptions.makeSceneTransitionAnimation()} メソッドを使用します。</li> +</ol> + +<pre> +// get the element that receives the click event +final View imgContainerView = findViewById(R.id.img_container); + +// get the common element for the transition in this activity +final View androidRobotView = findViewById(R.id.image_small); + +// define a click listener +imgContainerView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(this, Activity2.class); + // create the transition animation - the images in the layouts + // of both activities are defined with android:transitionName="robot" + ActivityOptions options = ActivityOptions + .makeSceneTransitionAnimation(this, androidRobotView, "robot"); + // start the new activity + startActivity(intent, options.toBundle()); + } +}); +</pre> + +<p>コードで生成した共有の動的ビューでは、 +{@link android.view.View#setTransitionName View.setTransitionName()} メソッドを使用して両方のアクティビティに共通の要素名を指定します。 +</p> + +<p>2 つ目のアクティビティが終了したときにシーンの切り替えアニメーションを逆回転させるには、{@link android.app.Activity#finish Activity.finish()} の代わりに +{@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()} + メソッドを呼び出します。</p> + +<h3>複数の共有要素を使ってアクティビティを開始する</h3> + +<p>複数の共有要素を持つ 2 つのアクティビティの間にシーンの切り替えアニメーションを付けるには、双方のレイアウトで <code>android:transitionName</code> +属性を使用(または双方のアクティビティで {@link android.view.View#setTransitionName View.setTransitionName()} メソッドを使用)して共有要素を定義して、次のように {@link android.app.ActivityOptions} オブジェクトを作成します。 + +</p> + +<pre> +ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, + Pair.create(view1, "agreedName1"), + Pair.create(view2, "agreedName2")); +</pre> + + +<h2 id="CurvedMotion">曲線モーションを使用する</h2> + +<p>マテリアル デザインのアニメーションは、時間的な間を補ったり立体的な動作パターンを表現するために曲線を多く用いています。 +Android 5.0(API レベル 21)以降では、カスタムのタイミングで描かれる曲線や曲線モーションのパターンをアニメーションで定義できます。 +</p> + +<p>{@link android.view.animation.PathInterpolator} クラスはベジェ曲線や {@link android.graphics.Path} オブジェクトに基づく新しい Interpolator(補間)です。 +この Interpolator は 1x1 の正方形に動作曲線を指定します。アンカー ポイントは(0,0)と(1,1)、制御点はコンストラクタ引数を使用して指定します。 + +または、PathInterpolator を XML リソースとしても定義できます。</p> + +<pre> +<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:controlX1="0.4" + android:controlY1="0" + android:controlX2="1" + android:controlY2="1"/> +</pre> + +<p>マテリアル デザインの仕様では、次の 3 つの基本的な曲線を XML リソースとして提供しています。 +</p> + +<ul> + <li><code>@interpolator/fast_out_linear_in.xml</code></li> + <li><code>@interpolator/fast_out_slow_in.xml</code></li> + <li><code>@interpolator/linear_out_slow_in.xml</code></li> +</ul> + +<p>{@link android.view.animation.PathInterpolator} オブジェクトは {@link +android.animation.Animator#setInterpolator Animator.setInterpolator()} メソッドに渡すことができます。</p> + +<p>{@link android.animation.ObjectAnimator} クラスには新しいコンストラクタがあり、一度に 2 つ以上のプロパティを使用して経路に沿ったアニメーションを作ることができます。 +たとえば、次の animator では {@link android.graphics.Path} オブジェクトを使ってビューの X と Y プロパティを指定しています。 +</p> + +<pre> +ObjectAnimator mAnimator; +mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); +... +mAnimator.start(); +</pre> + + +<h2 id="ViewState">ビューの状態遷移にアニメーションを付ける</h2> + +<p>{@link android.animation.StateListAnimator} クラスを使って、ビューの状態が変化したときに実行されるアニメーションを定義できます。 +次の例は、{@link +android.animation.StateListAnimator} を XML リソースとして定義する方法を示しています。</p> + +<pre> +<!-- animate the translationZ property of a view when pressed --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true"> + <set> + <objectAnimator android:propertyName="translationZ" + android:duration="@android:integer/config_shortAnimTime" + android:valueTo="2dp" + android:valueType="floatType"/> + <!-- you could have other objectAnimator elements + here for "x" and "y", or other properties --> + </set> + </item> + <item android:state_enabled="true" + android:state_pressed="false" + android:state_focused="true"> + <set> + <objectAnimator android:propertyName="translationZ" + android:duration="100" + android:valueTo="0" + android:valueType="floatType"/> + </set> + </item> +</selector> +</pre> + +<p>ビューの状態についてのカスタム アニメーションをビューに付与するには、この例のように XML リソース ファイルの +<code>selector</code> 要素を使用して animator を定義し、それを <code>android:stateListAnimator</code> 属性でビューに割り当てます。 +コードで StateListAnimator をビューに割り当てるには、{@link android.animation.AnimatorInflater#loadStateListAnimator +AnimationInflater.loadStateListAnimator()} メソッドを使用して +{@link android.view.View#setStateListAnimator View.setStateListAnimator()} メソッドでビューに animator を割り当てます。 +</p> + +<p>テーマがマテリアル テーマに拡張されると、ボタンにはデフォルトで Z アニメーションが設定されます。これを避けるためには、<code>android:stateListAnimator</code> 属性を +<code>@null</code> に設定します。 +</p> + +<p>{@link android.graphics.drawable.AnimatedStateListDrawable} クラスを使用すると、関連するビューの状態遷移にアニメーションを表示するドローアブルを作成できます。 +Android 5.0 の一部のシステム ウィジェットでは、デフォルトでこれらのアニメーションを使用しています。 +次の例は、{@link android.graphics.drawable.AnimatedStateListDrawable} を XML リソースとして定義する方法を示しています。 +</p> + +<pre> +<!-- res/drawable/myanimstatedrawable.xml --> +<animated-selector + xmlns:android="http://schemas.android.com/apk/res/android"> + + <!-- provide a different drawable for each state--> + <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" + android:state_pressed="true"/> + <item android:id="@+id/focused" android:drawable="@drawable/drawableF" + android:state_focused="true"/> + <item android:id="@id/default" + android:drawable="@drawable/drawableD"/> + + <!-- specify a transition --> + <transition android:fromId="@+id/default" android:toId="@+id/pressed"> + <animation-list> + <item android:duration="15" android:drawable="@drawable/dt1"/> + <item android:duration="15" android:drawable="@drawable/dt2"/> + ... + </animation-list> + </transition> + ... +</animated-selector> +</pre> + + +<h2 id="AnimVector">ベクター型ドローアブルにアニメーションを付ける</h2> + +<p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">ベクター型ドローアブル</a>は定義を失わずにスケールできます。 +{@link android.graphics.drawable.AnimatedVectorDrawable} +クラスを使うと、ベクター型ドローアブルのプロパティを指定してアニメーションを付けられます。</p> + +<p>通常は、次に示す 3 つの XML ファイルで AnimatedVectorDrawable を定義します。</p> + +<ul> +<li><code>res/drawable/</code> の +<code><vector></code> 要素を持つ vectordrawable の xml ファイル</li> +<li><code>res/drawable/</code> の +<code><animated-vector></code> 要素を持つ AnimatedVectorDrawable の xml ファイル</li> +<li><code>res/anim/</code> の +<code><objectAnimator></code> 要素を持つ 1 つ以上の ObjectAnimator の xml ファイル</li> +</ul> + +<p>AnimatedVectorDrawable では、<code><group></code> 要素と +<code><path></code> 要素の属性にアニメーションを付けることができます。<code><group></code> 要素は一連の経路やサブグループを定義し、<code><path></code> 要素は描く経路を定義します。 +</p> + +<p>アニメーションを付けたいベクター型ドローアブルを定義するときは、<code>android:name</code> +属性を使用してグループや経路に一意の名前を割り当てれば animator の定義からそれらを参照できるようになります。 +以下に例を示します。</p> + +<pre> +<!-- res/drawable/vectordrawable.xml --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="64dp" + android:width="64dp" + android:viewportHeight="600" + android:viewportWidth="600"> + <group + <strong>android:name="rotationGroup"</strong> + android:pivotX="300.0" + android:pivotY="300.0" + android:rotation="45.0" > + <path + <strong>android:name="v"</strong> + android:fillColor="#000000" + android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> + </group> +</vector> +</pre> + +<p>AnimatedVectorDrawable の定義では、次のようにベクター型ドローアブルのグループや経路をその名前で参照します。 +</p> + +<pre> +<!-- res/drawable/animvectordrawable.xml --> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@drawable/vectordrawable" > + <target + android:name="rotationGroup" + android:animation="@anim/rotation" /> + <target + android:name="v" + android:animation="@anim/path_morph" /> +</animated-vector> +</pre> + +<p>アニメーションの定義は {@link android.animation.ObjectAnimator} オブジェクトか {@link +android.animation.AnimatorSet} オブジェクトを示します。この例の最初の animator は、次のように対象グループを 360 度回転させています。 +</p> + +<pre> +<!-- res/anim/rotation.xml --> +<objectAnimator + android:duration="6000" + android:propertyName="rotation" + android:valueFrom="0" + android:valueTo="360" /> +</pre> + +<p>この例の 2 つ目の animator は、ベクター型ドローアブルの経路をある形から別の形へと変化させています。 +両方の経路が形の変化に対応できる必要があります。つまり同じ数のコマンドと、各コマンドで同じ数のパラメーターを保持している必要があります。 +</p> + +<pre> +<!-- res/anim/path_morph.xml --> +<set xmlns:android="http://schemas.android.com/apk/res/android"> + <objectAnimator + android:duration="3000" + android:propertyName="pathData" + android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" + android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" + android:valueType="pathType" /> +</set> +</pre> + +<p>詳細については、API リファレンスの {@link +android.graphics.drawable.AnimatedVectorDrawable} をご覧ください。</p> diff --git a/docs/html-intl/intl/ja/training/material/compatibility.jd b/docs/html-intl/intl/ja/training/material/compatibility.jd new file mode 100644 index 000000000000..0f8922fec4a3 --- /dev/null +++ b/docs/html-intl/intl/ja/training/material/compatibility.jd @@ -0,0 +1,168 @@ +page.title=互換性の維持 + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#Theme">別のスタイルを定義する</a></li> + <li><a href="#Layouts">別のレイアウトを提供する</a></li> + <li><a href="#SupportLib">サポート ライブラリを使用する</a></li> + <li><a href="#CheckVersion">システム バージョンを確認する</a></li> +</ol> +<h2>関連ドキュメント</h2> +<ul> + <li><a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a></li> + <li><a href="{@docRoot}design/material/index.html">Android でのマテリアル デザイン</a></li> +</ul> +</div> +</div> + + +<p>マテリアル テーマやカスタムのアクティビティ遷移など、マテリアル デザインの一部の機能は Android5.0(API レベル21)以降のみで利用できます。 +ただし、マテリアル デザインをサポートし、以前のバージョンの Android を実行している端末と互換性がある端末でこれらの機能が実行されている場合は、機能を使用できるようにアプリを設計することが可能です。 + +</p> + + +<h2 id="Theme">別のスタイルを定義する</h2> + +<p>マテリアル テーマをサポートしている端末ではマテリアル テーマを使用するようにアプリを構成できますが、同時に次のようにして以前のバージョンの Android を実行する端末向けに以前のテーマに戻すことができます。 +</p> + +<ol> +<li> +<code>res/values/styles.xml</code> で、以前のテーマ(Holo など)から継承するテーマを定義します。</li> +<li> +<code>res/values-v21/styles.xml</code> で、マテリアル テーマから継承するテーマを上記と同じ名前で定義します。</li> +<li>マニフェスト ファイルでこのテーマをアプリのテーマとして設定します。</li> +</ol> + +<p class="note"><strong>注:</strong> この方法で別のテーマを用意せずマテリアル テーマだけを使う場合、そのアプリは 5.0 よりも前のバージョンの Android では実行できません。 + + +</p> + + +<h2 id="Layouts">別のレイアウトを提供する</h2> + +<p>マテリアル デザインのガイドラインに沿って設計したレイアウトでも、Android 5.0(API レベル 21)で導入された新しい XML 属性を一切使用していない場合は、以前のバージョンの Android でも問題なく表示されます。 + +新しい XML 属性を使用している場合は、別のレイアウトを用意できます。以前のバージョンの Android でアプリが表示される方法をカスタマイズする目的で別のレイアウトを用意することも可能です。 +</p> + +<p>Android 5.0(API レベル 21)向けのレイアウト ファイルを <code>res/layout-v21/</code> に作成し、以前のバージョンの Android 向けの別のレイアウト ファイルを +<code>res/layout/</code> に作成します。 +たとえば、<code>res/layout/my_activity.xml</code> は <code>res/layout-v21/my_activity.xml</code> の代替レイアウトになります。 +</p> + +<p>コードの重複を避けるには、<code>res/values/</code> でスタイルを定義して <code>res/values-v21/</code> で新しい API 用にスタイルを修正します。それからスタイル継承を用いて、基本スタイルを <code>res/values/</code> で定義して、そのスタイルを <code>res/values-v21/</code> で継承します。 + +</p> + + +<h2 id="SupportLib">サポート ライブラリを使用する</h2> + +<p><a href="{@docRoot}tools/support-library/features.html#v7">v7 サポート ライブラリ</a> r21 以降には、次のマテリアル デザイン機能が含まれています。 +</p> + +<ul> +<li><code>Theme.AppCompat</code> テーマのいずれかを適用した場合の、システム ウィジェット用の<a href="{@docRoot}training/material/theme.html">マテリアル デザインのスタイル</a>。 +</li> +<li><code>Theme.AppCompat</code> テーマの<a href="{@docRoot}training/material/theme.html#ColorPalette">カラーパレット テーマ属性</a>。 +</li> +<li><a href="{@docRoot}training/material/lists-cards.html#RecyclerView">データ コレクションを表示する</a> {@link android.support.v7.widget.RecyclerView} ウィジェット。 +</li> +<li><a href="{@docRoot}training/material/lists-cards.html#CardView">カードを作成する</a> {@link android.support.v7.widget.CardView} ウィジェット。</li> +<li><a href="{@docRoot}training/material/drawables.html#ColorExtract">画像から代表色を抽出する</a> {@link android.support.v7.graphics.Palette} クラス。 +</li> +</ul> + +<h3>システム ウィジェット</h3> + +<p><code>Theme.AppCompat</code> テーマでは、次のウィジェット向けにマテリアル デザインのスタイルが提供されています。</p> + +<ul> + <li>{@link android.widget.EditText}</li> + <li>{@link android.widget.Spinner}</li> + <li>{@link android.widget.CheckBox}</li> + <li>{@link android.widget.RadioButton}</li> + <li>{@link android.support.v7.widget.SwitchCompat}</li> + <li>{@link android.widget.CheckedTextView}</li> +</ul> + +<h3>カラーパレット</h3> + +<p>Android v7 サポート ライブラリでマテリアル デザインのスタイルを入手し、カラーパレットをカスタマイズするには、次のように <code>Theme.AppCompat</code> テーマのいずれかを適用します。 +</p> + +<pre> +<!-- extend one of the Theme.AppCompat themes --> +<style name="Theme.MyTheme" parent="Theme.AppCompat.Light"> + <!-- customize the color palette --> + <item name="colorPrimary">@color/material_blue_500</item> + <item name="colorPrimaryDark">@color/material_blue_700</item> + <item name="colorAccent">@color/material_green_A200</item> +</style> +</pre> + +<h3>リストとカード</h3> + +<p>{@link android.support.v7.widget.RecyclerView} ウィジェットや {@link +android.support.v7.widget.CardView} ウィジェットは Android v7 サポート ライブラリを通じて以前のバージョンの Android でも使用できますが、次のような制限があります。 +</p> +<ul> +<li>{@link android.support.v7.widget.CardView} は、付加的なパディングを使い、プログラムでシャドウを実装するものになります。 +</li> +<li>{@link android.support.v7.widget.CardView} によって、丸い角と交差する子ビューがクリップされることはありません。 +</li> +</ul> + + +<h3>依存関係</h3> + +<p>5.0(API レベル 21)より前のバージョンの Android でこれらの機能を使用するには、Android v7 サポート ライブラリを <a href="{@docRoot}/sdk/installing/studio-build.html#dependencies">Gradle 依存関係</a>としてプロジェクトに含めます。 +</p> + +<pre> +dependencies { + compile 'com.android.support:appcompat-v7:21.0.+' + compile 'com.android.support:cardview-v7:21.0.+' + compile 'com.android.support:recyclerview-v7:21.0.+' +} +</pre> + + +<h2 id="CheckVersion">システム バージョンを確認する</h2> + +<p>次の機能は、Android 5.0(API レベル 21)以降でのみ使用できます。</p> + +<ul> +<li>アクティビティ遷移</li> +<li>タッチ フィードバック</li> +<li>出現アニメーション</li> +<li>経路ベースのアニメーション</li> +<li>ベクター型ドローアブル</li> +<li>ドローアブルによる着色</li> +</ul> + +<p>以前のバージョンの Android との互換性を維持するには、上記の機能に対する API を起動する前に、システム {@link +android.os.Build.VERSION#SDK_INT version} を実行時に確認します。 +</p> + +<pre> +// Check if we're running on Android 5.0 or higher +if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + // Call some material design APIs here +} else { + // Implement this feature without material design +} +</pre> + +<p class="note"><strong>注: </strong>アプリがサポートする Android のバージョンを指定するには、マニフェスト ファイルで <code>android:minSdkVersion</code> 属性と <code>android:targetSdkVersion</code> +属性を使用します。 +Android 5.0 でマテリアル デザインの機能を使用するには、<code>android:targetSdkVersion</code> 属性を <code>21</code> に設定します。 +詳細については、<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><uses-sdk> API ガイド</a>をご覧ください。 + +</p> diff --git a/docs/html-intl/intl/ja/training/material/drawables.jd b/docs/html-intl/intl/ja/training/material/drawables.jd new file mode 100644 index 000000000000..adb7279b2107 --- /dev/null +++ b/docs/html-intl/intl/ja/training/material/drawables.jd @@ -0,0 +1,126 @@ +page.title=ドローアブルの使用 + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#DrawableTint">ドローアブル リソースに色を付ける</a></li> + <li><a href="#ColorExtract">画像から代表色を抽出する</a></li> + <li><a href="#VectorDrawables">ベクター型ドローアブルを作成する</a></li> +</ol> +<h2>関連ドキュメント</h2> +<ul> + <li><a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a></li> + <li><a href="{@docRoot}design/material/index.html">Android でのマテリアル デザイン</a></li> +</ul> +</div> +</div> + +<p>アプリにマテリアル デザインを実装する際は、Drawable (ドローアブル)の次の機能を活用できます。</p> + +<ul> +<li>ドローアブルによる着色</li> +<li>代表色の抽出</li> +<li>ベクター型ドローアブル</li> +</ul> + +<p>このレッスンでは、アプリでのこれらの機能を使用する方法について説明します。</p> + + +<h2 id="DrawableTint">ドローアブル リソースに色を付ける</h2> + +<p>Android 5.0(API レベル 21)以降では、アルファ マスクとして定義されたビットマップや 9-patch に色を付けることができます。 +着色には、カラーリソースまたはカラーリソースに変換されるテーマ属性を使用できます(<code>?android:attr/colorPrimary</code> など)。 +通常は、これらのアセットを一度作成するだけで、テーマに合うように自動的に着色されます。 +</p> + +<p>{@code setTint()} メソッドを使用して {@link android.graphics.drawable.BitmapDrawable} オブジェクトか {@link +android.graphics.drawable.NinePatchDrawable} オブジェクトに色を適用できます。また、<code>android:tint</code> 属性や +<code>android:tintMode</code> 属性を使ってレイアウトで色やモードを設定できます。 +</p> + + +<h2 id="ColorExtract">画像から代表色を抽出する</h2> + +<p>Android サポート ライブラリ r21 以降には、画像から代表色を抽出できる {@link +android.support.v7.graphics.Palette} クラスが含まれています。 +</p> + +<ul> +<li>Vibrant (鮮やか)</li> +<li>Vibrant dark (鮮やかな暗色)</li> +<li>Vibrant light (鮮やかな明色)</li> +<li>Muted (控えめ)</li> +<li>Muted dark (控えめな暗色)</li> +<li>Muted light (控えめな明色)</li> +</ul> + +<p>これらの色を抽出するには、画像を読み込むバックグラウンド スレッドで {@link android.graphics.Bitmap} オブジェクトを +{@link android.support.v7.graphics.Palette#generate Palette.generate()} の静的メソッドに渡します。 +スレッドを使用できない場合は、代わりに +{@link android.support.v7.graphics.Palette#generateAsync Palette.generateAsync()} メソッドを呼び出してリスナーを提供します。 +</p> + +<p> +<code>Palette</code> クラスで、<code>Palette.getVibrantColor</code> などの getter メソッドを使って画像から代表色を取得できます。</p> + +<p>プロジェクトで {@link android.support.v7.graphics.Palette} クラスを使用するには、アプリのモジュールに次の +<a href="{@docRoot}sdk/installing/studio-build.html#dependencies">Gradle 依存関係</a>を追加します。 +</p> + +<pre> +dependencies { + ... + compile 'com.android.support:palette-v7:21.0.0' +} +</pre> + +<p>詳細については、API リファレンスの {@link android.support.v7.graphics.Palette} クラスをご覧ください。 +</p> + + +<h2 id="VectorDrawables">ベクター型ドローアブルを作成する</h2> + +<!-- video box --> +<a class="notice-developers-video" href="https://www.youtube.com/watch?v=wlFVIIstKmA" style="margin-top:18px"> +<div> + <h3>ビデオ</h3> + <p>Android ベクター グラフィック</p> +</div> +</a> + +<p>Android 5.0(API レベル 21)以降では、ベクター型ドローアブルを定義できます。このドローアブルは定義を失わずに拡張できます。 +ビットマップ画像では画面密度ごとにアセット ファイルが必要ですが、ベクター画像で必要なアセット ファイルは 1 つのみです。 +ベクター画像を作成するには、<code><vector></code> XML 要素で図形の詳細を定義します。 +</p> + +<p>次の例では、ハート型のベクター画像を定義しています。</p> + +<pre> +<!-- res/drawable/heart.xml --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + <!-- intrinsic size of the drawable --> + android:height="256dp" + android:width="256dp" + <!-- size of the virtual canvas --> + android:viewportWidth="32" + android:viewportHeight="32"> + + <!-- draw a path --> + <path android:fillColor="#8fff" + android:pathData="M20.5,9.5 + c-1.955,0,-3.83,1.268,-4.5,3 + c-0.67,-1.732,-2.547,-3,-4.5,-3 + C8.957,9.5,7,11.432,7,14 + c0,3.53,3.793,6.257,9,11.5 + c5.207,-5.242,9,-7.97,9,-11.5 + C25,11.432,23.043,9.5,20.5,9.5z" /> +</vector> +</pre> + +<p>Android ではベクター画像は {@link android.graphics.drawable.VectorDrawable} + オブジェクトとして表示されます。<code>pathData</code> 構文の詳細については、<a href="http://www.w3.org/TR/SVG11/paths.html#PathData">SVG パス リファレンス</a>をご覧ください。ベクター型ドローアブルのアニメーションの詳細については、 +<a href="{@docRoot}training/material/animations.html#AnimVector">ベクター ドローアブルのアニメーション</a>をご覧ください。 +</p> diff --git a/docs/html-intl/intl/ja/training/material/get-started.jd b/docs/html-intl/intl/ja/training/material/get-started.jd new file mode 100644 index 000000000000..2de674434537 --- /dev/null +++ b/docs/html-intl/intl/ja/training/material/get-started.jd @@ -0,0 +1,171 @@ +page.title=スタートガイド + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#ApplyTheme">マテリアル テーマを適用する</a></li> + <li><a href="#Layouts">レイアウトを設計する</a></li> + <li><a href="#Depth">ビューでエレベーションを指定する</a></li> + <li><a href="#ListsCards">リストとカードを作成する</a></li> + <li><a href="#Animations">アニメーションをカスタマイズする</a></li> +</ol> +<h2>関連ドキュメント</h2> +<ul> + <li><a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a></li> + <li><a href="{@docRoot}design/material/index.html">Android でのマテリアル デザイン</a></li> +</ul> +</div> +</div> + + +<p>マテリアル デザインでアプリを作成するには: </p> + +<ol> + <li style="margin-bottom:10px"> + <a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a>を確認します。</li> + <li style="margin-bottom:10px"> + マテリアル <strong>テーマ</strong>をアプリに適用します。</li> + <li style="margin-bottom:10px"> + マテリアル デザインのガイドラインに沿って<strong>レイアウト</strong>を作成します。</li> + <li style="margin-bottom:10px"> + ビューの<strong>エレベーション</strong>を設定してシャドウを付与します。</li> + <li style="margin-bottom:10px"> + リストやカードにシステム<strong>ウィジェット</strong>を使用します。</li> + <li style="margin-bottom:10px"> + アプリで<strong>アニメーション</strong>をカスタマイズします。</li> +</ol> + +<h3>下方互換性を維持する</h3> + +<p>Android 5.0 より前のバージョンとの互換性を維持しながら、マテリアル デザインのさまざまな機能をアプリに追加できます。 +詳細については、 +<a href="{@docRoot}training/material/compatibility.html">互換性の維持</a>をご覧ください。</p> + +<h3>マテリアル デザインでアプリをアップデートする</h3> + +<p>既存のアプリをアップデートしてマテリアル デザインを組み込むには、マテリアル デザインのガイドラインに沿ってレイアウトをアップデートします。 +深度、タッチ フィードバック、アニメーションを組み込んでいることも確認してください。 +</p> + +<h3>マテリアル デザインで新しいアプリを作成する</h3> + +<p>マテリアル デザインの機能を使って新しいアプリを作成すると、<a href="http://www.google.com/design/spec">マテリアル デザインのガイドライン</a>から凝縮したデザイン フレームワークが得られます。 +ガイドラインに従い、Android フレームワークの新しい機能を使ってアプリを設計、開発してください。 +</p> + + +<h2 id="ApplyTheme">マテリアル テーマを適用する</h2> + +<p>アプリでマテリアル テーマを適用するには、次のように +<code>android:Theme.Material</code> から継承したスタイルを指定します。</p> + +<pre> +<!-- res/values/styles.xml --> +<resources> + <!-- your theme inherits from the material theme --> + <style name="AppTheme" parent="android:Theme.Material"> + <!-- theme customizations --> + </style> +</resources> +</pre> + +<p>マテリアル テーマはアップデートされたシステム ウィジェットを提供しています。これにより、タッチ フィードバックやアクティビティ遷移のためのカラーパレットやデフォルトのアニメーションを指定できます。 +詳細については、 +<a href="{@docRoot}training/material/theme.html">マテリアル テーマの使用</a>をご覧ください。</p> + + +<h2 id="Layouts">レイアウトを設計する</h2> + +<p>マテリアル テーマを適用したり、カスタマイズしたりすることに加えて、レイアウトが<a href="http://www.google.com/design/spec">マテリアル デザインのガイドライン</a>に準拠している必要があります。 +レイアウトを設計するときは、次の項目に特に注意してください。 +</p> + +<ul> +<li>ベースライン グリッド</li> +<li>キーライン</li> +<li>空白スペース</li> +<li>タッチ ターゲット サイズ</li> +<li>レイアウト構成</li> +</ul> + + +<h2 id="Depth">ビューでエレベーションを指定する</h2> + +<p>ビューにはシャドウを付与できます。ビューのエレベーションの値によって、付与されるシャドウのサイズと表示される順序が決まります。 +ビューのエレベーションを設定するには、次のようにレイアウトの +<code>android:elevation</code> 属性を使用します。</p> + +<pre> +<TextView + android:id="@+id/my_textview" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/next" + android:background="@color/white" + android:elevation="5dp" /> +</pre> + +<p>新しい <code>translationZ</code> プロパティを使用すると、ビューのエレベーションの一時的な変更が反映されるアニメーションを作成できます。 +エレベーションの変更は、 +<a href="{@docRoot}training/material/animations.html#ViewState">タッチ操作に応答</a>するときに便利です。 +</p> + +<p>詳細については、<a href="{@docRoot}training/material/shadows-clipping.html">シャドウとクリッピング ビューの定義</a>をご覧ください。 +</p> + + +<h2 id="ListsCards">リストとカードを作成する</h2> + +<p>{@link android.support.v7.widget.RecyclerView} は {@link +android.widget.ListView} のさらに柔軟なバージョンで、異なるレイアウト タイプをサポートしてパフォーマンスを向上します。 +{@link android.support.v7.widget.CardView} を使用すると、あらゆるアプリで一貫した外観でカードの中に情報を表示できます。 +次のコードは、レイアウトに +{@link android.support.v7.widget.CardView} を含める方法の一例です。</p> + +<pre> +<android.support.v7.widget.CardView + android:id="@+id/card_view" + android:layout_width="200dp" + android:layout_height="200dp" + card_view:cardCornerRadius="3dp"> + ... +</android.support.v7.widget.CardView> +</pre> + +<p>詳細については、<a href="{@docRoot}training/material/lists-cards.html">リストとカードの作成</a>をご覧ください。 +</p> + + +<h2 id="Animations">アニメーションをカスタマイズする</h2> + +<p>Android 5.0(API レベル 21)には、アプリでカスタム アニメーションを作成する新たな API が含まれています。 +たとえば次のように、アクティビティ遷移を有効にしてアクティビティ内部で ExitTransition を定義できます。 +</p> + +<pre> +public class MyActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // enable transitions + getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); + setContentView(R.layout.activity_my); + } + + public void onSomeButtonClicked(View view) { + getWindow().setExitTransition(new Explode()); + Intent intent = new Intent(this, MyOtherActivity.class); + startActivity(intent, + ActivityOptions + .makeSceneTransitionAnimation(this).toBundle()); + } +} +</pre> + +<p>このアクティビティから別のアクティビティを開始するときに Exit 遷移がアクティベートされます。</p> + +<p>新しいアニメーション API の詳細については、<a href="{@docRoot}training/material/animations.html">カスタム アニメーションの定義</a>をご覧ください。</p> diff --git a/docs/html-intl/intl/ja/training/material/index.jd b/docs/html-intl/intl/ja/training/material/index.jd new file mode 100644 index 000000000000..9f6d18701417 --- /dev/null +++ b/docs/html-intl/intl/ja/training/material/index.jd @@ -0,0 +1,61 @@ +page.title=デベロッパーのためのマテリアル デザイン +page.type=デザイン +page.image=images/cards/material_2x.png +page.metaDescription=アプリにマテリアル デザインを適用する方法を学習する + + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2>必要な知識と前提条件</h2> + <ul> + <li>Android 5.0(API レベル 21)</li> + </ul> +</div> +</div> + +<p>マテリアル デザインは、複数のプラットフォームや端末の視覚、モーション、インタラクション デザインの包括的な指針です。 +Android アプリでマテリアル デザインを使うには、 +<a href="http://www.google.com/design/spec/material-design/introduction.html">マテリアル デザインの仕様</a>で説明されているガイドラインに従い、Android 5.0(API レベル 21)の新しいコンポーネントや機能を使用します。 + + +</p> + +<p>ここでは、次の要素を用いてマテリアル デザイン アプリを作成する方法について説明します。</p> + +<ul> +<li>マテリアル テーマ</li> +<li>カードやリストのウィジェット</li> +<li>カスタム シャドウとビューのクリッピング</li> +<li>ベクター型ドローアブル</li> +<li>カスタム アニメーション</li> +</ul> + +<p>さらに、アプリでマテリアル デザインの機能を使うときに Android 5.0(API レベル 21)より前のバージョンとの互換性を維持する方法についても説明します。 +</p> + +<h2>レッスン</h2> + +<dl> + <dt><a href="{@docRoot}training/material/get-started.html">スタートガイド</a></dt> + <dd>マテリアル デザインの機能でアプリを更新する方法について学習します。</dd> + + <dt><a href="{@docRoot}training/material/theme.html">マテリアル テーマの使用</a></dt> + <dd>マテリアル デザインのスタイルをアプリに適用する方法について学習します。</dd> + + <dt><a href="{@docRoot}training/material/lists-cards.html">リストとカードの作成</a></dt> + <dd>システム ウィジェットを使って、一貫した外観や使用感のリストやカードを作成する方法について学習します。</dd> + + <dt><a href="{@docRoot}training/material/shadows-clipping.html">シャドウとクリッピング ビューの定義</a></dt> + <dd>ビューのエレベーションを設定してカスタム シャドウを作成する方法やビューをクリップする方法について学習します。</dd> + + <dt><a href="{@docRoot}training/material/drawables.html">ドローアブルの使用</a></dt> + <dd>ベクター型ドローアブルを作成する方法やドローアブル リソースに色を付ける方法について学習します。</dd> + + <dt><a href="{@docRoot}training/material/animations.html">カスタム アニメーションの定義</a></dt> + <dd>ビューのカスタム アニメーションや共有要素とアクティビティ遷移を作成する方法について学習します。</dd> + + <dt><a href="{@docRoot}training/material/compatibility.html">互換性の維持</a></dt> + <dd>Android 5.0 より前のバージョンのプラットフォームとの互換性を維持する方法について学習します。</dd> +</dl> diff --git a/docs/html-intl/intl/ja/training/material/lists-cards.jd b/docs/html-intl/intl/ja/training/material/lists-cards.jd new file mode 100644 index 000000000000..3d84d5ded3ea --- /dev/null +++ b/docs/html-intl/intl/ja/training/material/lists-cards.jd @@ -0,0 +1,266 @@ +page.title=リストとカードの作成 + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#RecyclerView">リストを作成する</a></li> + <li><a href="#CardView">カードを作成する</a></li> + <li><a href="#Dependencies">依存関係を追加する</a></li> +</ol> +<h2>関連ドキュメント</h2> +<ul> + <li><a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a></li> + <li><a href="{@docRoot}design/material/index.html">Android でのマテリアル デザイン</a></li> +</ul> +</div> +</div> + + +<p>マテリアル デザインのスタイルを適用した複雑なリストやカードをアプリで作成するには、 +{@link android.support.v7.widget.RecyclerView} ウィジェットや {@link android.support.v7.widget.CardView} + ウィジェットを使用します。</p> + + +<h2 id="RecyclerView">リストを作成する</h2> + +<p>{@link android.support.v7.widget.RecyclerView} ウィジェットは、{@link android.widget.ListView} をさらに進化させて柔軟にしたものです。 +このウィジェットは、大きなデータセットを表示するためのコンテナであり、限られたビューを維持することで非常に効率的にスクロールできます。 +ユーザーのアクションやネットワークのイベントに基づいて、実行時に要素が変わるデータ コレクションを持つ場合には、 +{@link android.support.v7.widget.RecyclerView} ウィジェットを使用してください。 +</p> + +<p>{@link android.support.v7.widget.RecyclerView} クラスは次の機能を提供することで、簡単に大きなデータセットを表示したり処理したりできます。 +</p> + +<ul> + <li>アイテムの位置調整を行うレイアウト マネージャー</li> + <li>アイテムの削除や追加のような一般的な操作のデフォルト アニメーション</li> +</ul> + +<p>また、{@link +android.support.v7.widget.RecyclerView} ウィジェットのカスタム レイアウト マネージャーやアニメーションも柔軟に定義できます。</p> + +<img src="{@docRoot}training/material/images/RecyclerView.png" alt="" width="550" height="106" /> +<p class="img-caption"> +<strong>図 1</strong> <code>RecyclerView</code> ウィジェット。 +</p> + +<p>{@link android.support.v7.widget.RecyclerView} ウィジェットを使用するには、アダプターとレイアウト マネージャーを指定する必要があります。 +アダプターを作成するには、{@link +android.support.v7.widget.RecyclerView.Adapter RecyclerView.Adapter} クラスを拡張します。具体的な実装方法は、データセットの詳細やビューの種類によって異なります。 +詳細については、下記の<a href="#RVExamples">例</a>をご覧ください。 +</p> + +<div style="float:right"> +<img src="{@docRoot}design/material/images/list_mail.png" alt="" width="250" height="426" /> +<p class="img-caption" style="margin-left:8px"> +<strong>図 2</strong> - <code>RecyclerView</code> を使ったリスト。 +</p> +</div> + +<p><strong>レイアウト マネージャー</strong>は、{@link +android.support.v7.widget.RecyclerView} 内でアイテムビューを位置付けし、ユーザーから見えなくなったアイテムビューを再利用するタイミングを決定します。 +ビューを再利用(または<em>リサイクル</em>)するために、レイアウト マネージャーからアダプターにデータセットの異なる要素でビューの内容を入れ替えるよう求められることがあります。 +このようにビューをリサイクルすることで、不要なビューを作成したりコストのかかる {@link android.app.Activity#findViewById findViewById()} のルックアップをしたりせずに済み、パフォーマンスが向上します。 + +</p> + +<p>{@link android.support.v7.widget.RecyclerView} には、次のレイアウト マネージャーが組み込まれています。</p> + +<ul> +<li>{@link android.support.v7.widget.LinearLayoutManager} は、アイテムを縦方向か横方向のスクロール リストに表示します。 +</li> +<li>{@link android.support.v7.widget.GridLayoutManager} は、アイテムをグリッドに表示します。</li> +<li>{@link android.support.v7.widget.StaggeredGridLayoutManager} は、アイテムをスタッガード グリッドに表示します。</li> +</ul> + +<p>カスタム レイアウト マネージャーを作成するには、{@link +android.support.v7.widget.RecyclerView.LayoutManager RecyclerView.LayoutManager} クラスを拡張します。</p> + +<h3>アニメーション</h3> + +<p>{@link +android.support.v7.widget.RecyclerView} では、アイテムの追加や削除のアニメーションがデフォルトで有効になっています。これらのアニメーションをカスタマイズするには、 +{@link android.support.v7.widget.RecyclerView.ItemAnimator RecyclerView.ItemAnimator} クラスを拡張し、{@link android.support.v7.widget.RecyclerView#setItemAnimator RecyclerView.setItemAnimator()} + メソッドを使用します。 +</p> + +<h3 id="RVExamples">例</h3> + +<p>次のコードは、レイアウトに +{@link android.support.v7.widget.RecyclerView} を追加する方法の一例です。</p> + +<pre> +<!-- A RecyclerView with some commonly used attributes --> +<android.support.v7.widget.RecyclerView + android:id="@+id/my_recycler_view" + android:scrollbars="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"/> +</pre> + +<p>レイアウトに {@link android.support.v7.widget.RecyclerView} ウィジェットを追加したら、オブジェクトのハンドルを取得してレイアウト マネージャーに接続し、表示するデータのアダプターを添付します。 + +</p> + +<pre> +public class MyActivity extends Activity { + private RecyclerView mRecyclerView; + private RecyclerView.Adapter mAdapter; + private RecyclerView.LayoutManager mLayoutManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.my_activity); + mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); + + // use this setting to improve performance if you know that changes + // in content do not change the layout size of the RecyclerView + mRecyclerView.setHasFixedSize(true); + + // use a linear layout manager + mLayoutManager = new LinearLayoutManager(this); + mRecyclerView.setLayoutManager(mLayoutManager); + + // specify an adapter (see also next example) + mAdapter = new MyAdapter(myDataset); + mRecyclerView.setAdapter(mAdapter); + } + ... +} +</pre> + +<p>アダプターによって、データセット内の各項目にアクセスしたり、アイテムのビューを作成したり、元のアイテムが見えなくなったときにビューのコンテンツの一部を新しいデータアイテムと入れ替えたりできます。 + +次のコードはデータセットを実装する簡易な例です。このデータセットは、{@link android.widget.TextView} ウィジェットを使用して表示した文字列の配列で構成されています。 +</p> + +<pre> +public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { + private String[] mDataset; + + // Provide a reference to the views for each data item + // Complex data items may need more than one view per item, and + // you provide access to all the views for a data item in a view holder + public static class ViewHolder extends RecyclerView.ViewHolder { + // each data item is just a string in this case + public TextView mTextView; + public ViewHolder(TextView v) { + super(v); + mTextView = v; + } + } + + // Provide a suitable constructor (depends on the kind of dataset) + public MyAdapter(String[] myDataset) { + mDataset = myDataset; + } + + // Create new views (invoked by the layout manager) + @Override + public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, + int viewType) { + // create a new view + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.my_text_view, parent, false); + // set the view's size, margins, paddings and layout parameters + ... + ViewHolder vh = new ViewHolder(v); + return vh; + } + + // Replace the contents of a view (invoked by the layout manager) + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + // - get element from your dataset at this position + // - replace the contents of the view with that element + holder.mTextView.setText(mDataset[position]); + + } + + // Return the size of your dataset (invoked by the layout manager) + @Override + public int getItemCount() { + return mDataset.length; + } +} +</pre> + + +<div style="float:right;margin-top:15px;margin-left:30px"> +<img src="{@docRoot}design/material/images/card_travel.png" alt="" width="225" height="383"> +<p class="img-caption" style="margin-left:12px"> +<strong>図 3</strong> カードの例。 +</p> +</div> + +<h2 id="CardView">カードを作成する</h2> + +<p>{@link android.support.v7.widget.CardView} は {@link android.widget.FrameLayout} クラスを拡張して、あらゆるプラットフォームで統一された外観のカード内に情報を表示できます。 +{@link +android.support.v7.widget.CardView} ウィジェットは、シャドウを付けたり角を丸くしたりできます。</p> + +<p>シャドウ付きのカードを作成するには、<code>card_view:cardElevation</code> 属性を使用します。 +{@link android.support.v7.widget.CardView} は Android 5.0(API レベル 21)以降ではリアルなエレベーションや動きのあるシャドウを使用し、それより前のバージョンではプログラム的なシャドウを使用します。 + +詳細については、<a href="{@docRoot}training/material/compatibility.html">互換性の維持</a>をご覧ください。 +</p> + +<p> +{@link android.support.v7.widget.CardView} ウィジェットの外観をカスタマイズするには、次のプロパティを使用します。</p> + +<ul> + <li>レイアウトで角の丸みを設定するには、<code>card_view:cardCornerRadius</code> 属性を使用します。 +</li> + <li>コードで角の丸みを設定するには、<code>CardView.setRadius</code> メソッドを使用します。</li> + <li>カードの背景色を設定するには、<code>card_view:cardBackgroundColor</code> 属性を使用します。 +</li> +</ul> + +<p>次のコードは、レイアウトに {@link android.support.v7.widget.CardView} + ウィジェットを含める方法の一例です。</p> + +<pre> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + xmlns:card_view="http://schemas.android.com/apk/res-auto" + ... > + <!-- A CardView that contains a TextView --> + <android.support.v7.widget.CardView + xmlns:card_view="http://schemas.android.com/apk/res-auto" + android:id="@+id/card_view" + android:layout_gravity="center" + android:layout_width="200dp" + android:layout_height="200dp" + card_view:cardCornerRadius="4dp"> + + <TextView + android:id="@+id/info_text" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + </android.support.v7.widget.CardView> +</LinearLayout> +</pre> + +<p>詳細については、API リファレンスの {@link android.support.v7.widget.CardView} をご覧ください。</p> + + +<h2 id="Dependencies">依存関係を追加する</h2> + +<p>{@link android.support.v7.widget.RecyclerView} ウィジェットと {@link android.support.v7.widget.CardView} ウィジェットは、<a href="{@docRoot}tools/support-library/features.html#v7">v7 サポート ライブラリ</a>の一部です。 + +プロジェクトでこれらのウィジェットを使うには、次のようにアプリのモジュールに +<a href="{@docRoot}sdk/installing/studio-build.html#dependencies">Gradle 依存関係</a>を追加します。 +</p> + +<pre> +dependencies { + ... + compile 'com.android.support:cardview-v7:21.0.+' + compile 'com.android.support:recyclerview-v7:21.0.+' +} +</pre> diff --git a/docs/html-intl/intl/ja/training/material/shadows-clipping.jd b/docs/html-intl/intl/ja/training/material/shadows-clipping.jd new file mode 100644 index 000000000000..981a4d1c872a --- /dev/null +++ b/docs/html-intl/intl/ja/training/material/shadows-clipping.jd @@ -0,0 +1,133 @@ +page.title=シャドウとクリッピング ビューの定義 + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#Elevation">ビューにエレベーションを割り当てる</a></li> + <li><a href="#Shadows">ビューシャドウとアウトラインをカスタマイズする</a></li> + <li><a href="#Clip">ビューをクリップする</a></li> +</ol> +<h2>関連ドキュメント</h2> +<ul> + <li><a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a></li> + <li><a href="{@docRoot}design/material/index.html">Android でのマテリアル デザイン</a></li> +</ul> +</div> +</div> + +<p>マテリアル デザインでは、UI 要素に Elevation(エレベーション、高度)を導入しています。エレベーションによって、ユーザーは 1 つの要素が他の要素と比べて重要であることを理解でき、目前の作業に集中できるようになります。 +</p> + +<p>ビューのエレベーションは Z プロパティで表され、シャドウビューの見た目を決定します。Z 値が高くなればシャドウも大きく、滑らかになります。 +Z 値が高いビューは Z 値が低いビューを覆い隠しますが、Z 値がビューのサイズに影響することはありません。 +</p> + +<p>シャドウは、エレベーションが設定された親ビューによって描かれ、標準的なビュー クリッピングの対象になります。デフォルトでは親ビューによってクリップされます。 +</p> + +<p>エレベーションは、何らかのアクションでビューの平面上にウィジェットが浮き上がるようなアニメーションを作成する際にも役立ちます。 +</p> + +<p>マテリアル デザインのエレベーションの詳細については、 +<a href="http://www.google.com/design/spec/what-is-material/objects-in-3d-space.html">3D スペースのオブジェクト</a>をご覧ください。 +</p> + + +<h2 id="Elevation">ビューにエレベーションを割り当てる</h2> + +<p>ビューの Z 値には次の 2 つのコンポーネントがあります。 + +<ul> +<li>Elevation (エレベーション): 静的なコンポーネントです。</li> +<li>Translation (トランスレーション): アニメーションに使われる動的なコンポーネントです。</li> +</ul> + +<p><code>Z = elevation + translationZ</code></p> + +<img src="{@docRoot}training/material/images/shadows-depth.png" width="580" height="261" alt="" /> +<p class="img-caption"><strong>図 1</strong> - 異なるビュー エレベーションのシャドウ。</p> + +<p>レイアウトの定義でビューのエレベーションを設定するには、<code>android:elevation</code> + 属性を使用します。アクティビティのコードでビューのエレベーションを設定するには、 +{@link android.view.View#setElevation View.setElevation()} メソッドを使用します。</p> + +<p>ビューのトランスレーションを設定するには、{@link android.view.View#setTranslationZ +View.setTranslationZ()} メソッドを使用します。</p> + +<p>新しい {@link android.view.ViewPropertyAnimator#z ViewPropertyAnimator.z()} メソッドや {@link +android.view.ViewPropertyAnimator#translationZ ViewPropertyAnimator.translationZ()} メソッドを使用すると、ビューのエレベーションに簡単にアニメーションを付けられます。 +詳細については、API リファレンスの +{@link android.view.ViewPropertyAnimator} と、デベロッパー ガイドの<a href="{@docRoot}guide/topics/graphics/prop-animation.html">プロパティ アニメーション</a>をご覧ください。 +</p> + +<p>また、{@link android.animation.StateListAnimator} を使用してアニメーションを宣言的に指定することも可能です。 +これは、ユーザーがボタンを押したときなど、状態の変化によってアニメーションを動作する場合に特に役立ちます。 +詳細については、 +<a href="{@docRoot}training/material/animations.html#ViewState">ビューの状態遷移にアニメーションを付ける</a>をご覧ください。</p> + +<p>Z 値は dp(密度非依存ピクセル)で測られます。</p> + + +<h2 id="Shadows">ビューシャドウとアウトラインをカスタマイズする</h2> + +<p>ビュー背景のドローアブルの範囲によってシャドウのデフォルトの形状が決まります。 +<strong>Outlines</strong> はグラフィック オブジェクトの外形を表し、タッチ フィードバックのリップル(波紋)の領域を定義します。 +</p> + +<p>背景ドローアブルで定義されたビューについて考えてみます。</p> + +<pre> +<TextView + android:id="@+id/myview" + ... + android:elevation="2dp" + android:background="@drawable/myrect" /> +</pre> + +<p>背景ドローアブルが角が丸い長方形として定義されます。</p> + +<pre> +<!-- res/drawable/myrect.xml --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="#42000000" /> + <corners android:radius="5dp" /> +</shape> +</pre> + +<p>背景ドローアブルによってビューの外形が定義されるため、このビューは角が丸いシャドウを付与します。 +カスタム アウトラインを使えば、ビューシャドウのデフォルトの形状を更新できます。</p> + +<p>コードでビューのカスタム アウトラインを定義するには: <p> + +<ol> +<li>{@link android.view.ViewOutlineProvider} クラスを拡張します。</li> +<li>{@link android.view.ViewOutlineProvider#getOutline getOutline()} メソッドを上書きします。</li> +<li>{@link +android.view.View#setOutlineProvider View.setOutlineProvider()} メソッドで、ビューに新しい OutlineProvider を割り当てます。</li> +</ol> + +<p> +{@link android.graphics.Outline} クラスのメソッドを使用して、楕円形や角が丸い長方形のアウトラインを作成できます。ビューのデフォルトの OutlineProvider は、ビューの背景から外形を決定します。 +ビューがシャドウを付与しないようにするには、OutlineProvider を <code>null</code> に設定します。 +</p> + + +<h2 id="Clip">ビューをクリップする</h2> + +<p>ビューをクリップすると、ビューの形を簡単に変更できます。ビューをクリップすることで、他のデザイン要素との統一性を保ったり、ユーザーのインプットに応じてビューの形を変えたりできます。 + +{@link android.view.View#setClipToOutline +View.setClipToOutline()} メソッドか <code>android:clipToOutline</code> 属性を使用すると、ビューをそのアウトラインの範囲にクリップできます。 +{@link android.graphics.Outline#canClip Outline.canClip()} メソッドで指定されているように、クリップがサポートされるのは長方形、円形、角が丸い長方形のみです。 +</p> + +<p>上述のように、ドローアブルの範囲でビューをクリップするには、ドローアブルをビューの背景として設定し、{@link android.view.View#setClipToOutline View.setClipToOutline()} +メソッドを呼び出します。 +</p> + +<p>ビューのクリップは負荷の高い操作であるため、ビューのクリップに使用する形状にはアニメーションを付けないでください。 +この効果を発揮させるには、<a href="{@docRoot}training/material/animations.html#Reveal">出現エフェクト</a>アニメーションを使用します。</p> diff --git a/docs/html-intl/intl/ja/training/material/theme.jd b/docs/html-intl/intl/ja/training/material/theme.jd new file mode 100644 index 000000000000..43e5c6c995d6 --- /dev/null +++ b/docs/html-intl/intl/ja/training/material/theme.jd @@ -0,0 +1,131 @@ +page.title=マテリアル テーマの使用 + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#ColorPalette">カラーパレットをカスタマイズする</a></li> + <li><a href="#StatusBar">ステータスバーをカスタマイズする</a></li> + <li><a href="#Inheritance">テーマ個別のビュー</a></li> +</ol> +<h2>関連ドキュメント</h2> +<ul> + <li><a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a></li> + <li><a href="{@docRoot}design/material/index.html">Android でのマテリアル デザイン</a></li> +</ul> +</div> +</div> + + +<p>新しいマテリアル テーマでは、次のものが提供されます。</p> + +<ul> + <li>カラーパレットを設定できるシステム ウィジェット</li> + <li>システム ウィジェットのタッチ フィードバック アニメーション</li> + <li>アクティビティ遷移アニメーション</li> +</ul> + +<p>マテリアル テーマの外観は、ブランド イメージにあわせて自分のカラーパレットでカスタマイズできます。 +<a href="#fig3">図 3</a> のように、アクションバーやステータスバーにテーマ属性で色を付けることができます。 +</p> + +<p>システム ウィジェットには、新しいデザインやタッチ フィードバックがあります。カラーパレット、タッチ フィードバック、アクティビティ遷移は、自分のアプリ向けにカスタマイズできます。 +</p> + +<p>マテリアル テーマは次のように定義されます。</p> + +<ul> + <li><code>@android:style/Theme.Material</code> (暗色バージョン)</li> + <li><code>@android:style/Theme.Material.Light</code> (明色バージョン)</li> + <li><code>@android:style/Theme.Material.Light.DarkActionBar</code></li> +</ul> + +<p>使用できるマテリアル スタイルのリストについては、API リファレンスの +{@link android.R.style R.style} をご覧ください。</p> + +<!-- two columns, dark/light material theme example --> +<div style="width:700px;margin-top:25px;margin-bottom:10px"> +<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> + <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238"> + <div style="width:170px;margin:0 auto"> + <p style="margin-top:8px;font-size:12px"><strong>図 1</strong> 暗い色のマテリアル テーマ</p> + </div> +</div> +<div style="float:left;width:250px;margin-right:0px;"> + <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238"> + <div style="width:170px;margin:0 auto"> + <p style="margin-top:8px;font-size:12px"><strong>図 2</strong> 明るい色のマテリアル テーマ</p> + </div> +</div> +<br style="clear:left"> +</div> + +<p class="note"> +<strong>注: </strong>マテリアル テーマは、Android 5.0(API レベル 21)以降でのみ使用できます。 +<a href="{@docRoot}tools/support-library/features.html#v7">v7 サポート ライブラリ</a>は、一部のウィジェットに対してマテリアル デザイン スタイルでテーマを提供し、カラーパレットのカスタマイズをサポートしています。 + +詳細については、 +<a href="{@docRoot}training/material/compatibility.html">互換性の維持</a>をご覧ください。 +</p> + + +<h2 id="ColorPalette">カラーパレットをカスタマイズする</h2> + +<p style="margin-bottom:30px">ブランド イメージに合うようにテーマの基本色をカスタマイズするには、次の例に示すようにマテリアル テーマから継承する場合、テーマ属性を使ってカスタムカラーを定義します。 +</p> + +<pre> +<resources> + <!-- inherit from the material theme --> + <style name="AppTheme" parent="android:Theme.Material"> + <!-- Main theme colors --> + <!-- your app branding color for the app bar --> + <item name="android:colorPrimary">@color/primary</item> + <!-- darker variant for the status bar and contextual app bars --> + <item name="android:colorPrimaryDark">@color/primary_dark</item> + <!-- theme UI controls like checkboxes and text fields --> + <item name="android:colorAccent">@color/accent</item> + </style> +</resources> +</pre> + +<div style="float:right;margin-left:25px;margin-top:20px;margin-bottom:10px" id="fig3"> +<img src="{@docRoot}training/material/images/ThemeColors.png" width="250" height="445" /> +<p class="img-caption" style="margin-bottom:0px"> +<strong>図 3</strong> マテリアル テーマのカスタマイズ</p> +</div> + + +<h2 id="StatusBar">ステータスバーをカスタマイズする</h2> + +<p>マテリアル テーマを使うと、ステータスバーを簡単にカスタマイズできます。ブランド イメージに合わせて、またコントラストで白色のステータス アイコンを際立たせて色を設定できます。 +ステータスバーのカスタムカラーを設定するには、マテリアル テーマを拡張するときに <code>android:statusBarColor</code> 属性を使用します。 + +デフォルトでは <code>android:statusBarColor</code> は <code>android:colorPrimaryDark</code> の値を継承します。 +</p> + +<p>また、ステータスバーの背景を描くこともできます。たとえば、白色のステータス アイコンが見にくくならないように薄い暗色のグラデーションを付けて、ステータスバーを写真の上に透過的に表示したい場合、 + +<code>android:statusBarColor</code> 属性に +<code>@android:color/transparent</code> を指定してウィンドウ フラグを必要に応じて調整します。アニメーションやフェードには、{@link android.view.Window#setStatusBarColor Window.setStatusBarColor()} メソッドも使用できます。 + +</p> + +<p class="note"> +<strong>注: </strong>ステータスバーはメインのツールバーと明確に分かれている必要があります。ただし、背景に画面の端から端まで表示される鮮やかな画像やメディア コンテンツを使用したり、アイコンが見にくくならないようにグラデーションを使用する場合は例外です。 + + +</p> + +<p>ナビケーションとステータスバーをカスタマイズするときは、どちらも透過的にするか、ステータスバーだけを変更します。 +その他のケースではナビゲーション バーは黒色のままにする必要があります。</p> + + +<h2 id="Inheritance">テーマ個別のビュー</h3> + +<p>XML レイアウト定義の各要素では、テーマのリソースを参照する <code>android:theme</code> 属性を指定できます。 +この属性は、要素や子要素のテーマを変更し、インターフェースの一定の割合を占めるテーマ カラーパレットを変更する場合に役立ちます。 + +</p> |