diff options
Diffstat (limited to 'docs/html-intl/intl/ja')
13 files changed, 2474 insertions, 0 deletions
diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/index.jd new file mode 100644 index 0000000..837fc2b --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/index.jd @@ -0,0 +1,72 @@ +page.title=アクティビティのライフサイクル 管理 +page.tags=アクティビティのライフサイクル +helpoutsWidget=true + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + + +<h2>必要な知識と前提条件</h2> +<ul> + <li>Android プロジェクトの作成方法(<a href="{@docRoot}training/basics/firstapp/creating-project.html">Android +プロジェクトの作成</a>を参照)</li> +</ul> + + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a></li> +</ul> + + +<h2>試してみる</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">デモのダウンロード</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + +</div> +</div> + +<p>ユーザーがアプリ内を移動したり、アプリ外に移動したり、再びアプリに戻ったりすると、アプリの +{@link android.app.Activity} インスタンスが、それらのライフサイクルの異なる状態間で遷移します。 +たとえば、アクティビティが新規に開始されると、システムのフォアグラウンドに表示され、ユーザーに認識されるようにします。 + +このプロセスの間に、Android システムは、ユーザー インターフェースやその他のコンポーネントが設定されたアクティビティ上で一連のライフサイクル メソッドを呼び出します。 +ユーザーが別のアクティビティを開始する、または別のアプリに切り替えるアクションを実行した場合、システムはアクティビティ上で別の一連のライフサイクル メソッドを呼び出し、アクティビティがバックグラウンドに移動します(この場合、アクティビティが表示されなくなりますが、インスタンスとその状態はそのまま維持されます)。 + + +</p> + +<p>ライフサイクル コールバック メソッドでは、ユーザーがアクティビティを離れたり、再開させたりした場合のアクティビティの動作について宣言することができます。 +たとえば、ストリーミング ビデオ プレーヤーをビルドしている場合、ユーザーが別のアプリに切り替えた際にビデオを一時停止したり、ネットワーク接続を終了することが可能です。ユーザーが戻った場合には、ネットワークに再接続し、一時停止した場所からビデオを再開できるようにすることができます。 + + +</p> + +<p>このクラスでは、各 {@link +android.app.Activity} インスタンスが受け取る重要なライフサイクル コールバック メソッドについて、またそれらを使用してユーザーが期待する内容でアクティビティを動作させる方法、アクティビティがそれらを必要としないときにシステムのリソースを消費しないようにする方法について学習します。 +</p> + +<h2>レッスン</h2> + +<dl> + <dt><b><a href="starting.html">アクティビティを開始する</a></b></dt> + <dd>アクティビティのライフサイクルに関する基本、ユーザーがアプリを起動する方法、基本的なアクティビティ作成の方法について学習します。 +</dd> + <dt><b><a href="pausing.html">アクティビティの一時停止と再開</a></b></dt> + <dd>アクティビティが一時停止状態(部分的に不可視)および、再開された場合の動作、そしてこれらの状態の変遷時に何をすべきかについて学習します。 +</dd> + <dt><b><a href="stopping.html">アクティビティの停止と再起動</a></b></dt> + <dd>ユーザーが完全にアクティビティから移動し、その後戻ってきた場合の動作について学習します。</dd> + <dt><b><a href="recreating.html">アクティビティを再作成する</a></b></dt> + <dd>アクティビティが破棄されるときの動作と、必要に応じてアクティビティの状態を再構築する方法について学習します。 +</dd> +</dl> + diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/pausing.jd new file mode 100644 index 0000000..b837a00 --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/pausing.jd @@ -0,0 +1,147 @@ +page.title=アクティビティの一時停止と再開 +page.tags=アクティビティのライフサイクル +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>このレッスンでの学習内容</h2> + <ol> + <li><a href="#Pause">アクティビティを一時停止する</a></li> + <li><a href="#Resume">アクティビティを再開する</a></li> + </ol> + + <h2>関連ドキュメント</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a> + </li> + </ul> + +<h2>試してみる</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">デモのダウンロード</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>通常のアプリの使用中、フォアグラウンドのアクティビティは、他のビジュアル コンポーネントによって隠される場合があり、これによりアクティビティが<em>一時停止</em>します。 +たとえば、半透明のアクティビティが開くと(ダイアログのスタイルなど)、以前のアクティビティは一時停止します。 +そのアクティビティは、まだ部分的に表示されていても、現在フォーカスされているアクティビティではない状態である限り、一時停止状態が維持されます。 +</p> + +<p>ただし、アクティビティが完全に隠され、表示されなくなった場合は、<em>停止</em>します(これについては次のレッスンで説明します)。 +</p> + +<p>アクティビティが一時停止状態に入ると、一時停止中は継続させない方が望ましい進行中のアクション(ビデオなど)を停止させたり、ユーザーがアプリを離れたままになった場合に備えて保存する必要のある情報すべてを保持したりできるよう、システムは {@link android.app.Activity} 上で {@link +android.app.Activity#onPause onPause()} メソッドを呼び出します。ユーザーが一時停止状態からアクティビティに復帰した場合は、システムはアクティビティを再開し、{@link android.app.Activity#onResume onResume()} メソッドを呼び出します。 + + + +</p> + +<p class="note"><strong>注:</strong> アクティビティが {@link +android.app.Activity#onPause()} の呼び出しを受信した場合は、アクティビティが一瞬一時停止された後、ユーザーが同アクティビティにフォーカスを戻す可能性があることを示している場合があります。 +ただし、通常は、ユーザーがアクティビティを離れていることを最初に示すものです。 +</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" /> +<p class="img-caption"><strong>図 1.</strong>半透明のアクティビティによって自分のアクティビティが隠されると、システムは {@link android.app.Activity#onPause onPause()} を呼び出し、アクティビティは一時停止の状態で待機します(1)。 + +一時停止中にユーザーがアクティビティに復帰した場合、システムは {@link android.app.Activity#onResume onResume()} を呼び出します(2)。 +</p> + + +<h2 id="Pause">アクティビティを一時停止する</h2> + +<p>システムがアクティビティに対して {@link android.app.Activity#onPause()} を呼び出した場合、技術的にはアクティビティはまだ部分的に表示されていることを意味しますが、ほとんどの場合は、ユーザーがアクティビティを離れていて、ほどなく停止状態になる徴候を示しています。 + +通常、以下を行う場合には、{@link android.app.Activity#onPause()} コールバックを使用する必要があります。 +</p> + +<ul> + <li>CPU を消費する可能性があるアニメーションや他の進行中のアクションを停止する。</li> + <li>ユーザーがアクティビティを離れた場合にも変更が永続的に保存されると期待するような場合(メールの下書きなど)でのみ、未保存の変更をコミットする。 +</li> + <li>放送用レシーバーなどのシステム リソース、(GPS +などの)センサー処理や、アクティビティが一時停止され、ユーザーが必要としない間にバッテリー寿命に影響を与える可能性があるすべてのリソースを解放する。 +</li> +</ul> + +<p>たとえば、アプリケーションが {@link android.hardware.Camera} を使用する場合、{@link android.app.Activity#onPause()} メソッドは、リソースの解放に適した手段です。 +</p> + +<pre> +@Override +public void onPause() { + super.onPause(); // Always call the superclass method first + + // Release the Camera because we don't need it when paused + // and other activities might need to use it. + if (mCamera != null) { + mCamera.release() + mCamera = null; + } +} +</pre> + +<p>一般的には、(フォームに入力された個人情報などの)ユーザーの変更を永続的なストレージに保存する目的の場合には、{@link android.app.Activity#onPause()} の使用は<strong>避ける</strong>必要があります。 +特定のユーザーが(メールの下書きのように)変更の自動保存を期待していると確信できる場合のみ、{@link android.app.Activity#onPause()}の期間内に永続的なストレージにユーザーの変更を保持する必要があります。ただし、{@link +android.app.Activity#onPause()} メソッド中にはデータベースへの書き込みなどの CPU に高負荷をかける作業を行うことは避けてください。これにより、次のアクティビティへの表示上の遷移を遅らせる可能性があります(代わりに +{@link android.app.Activity#onStop onStop()} メソッド中に高負荷のシャットダウン操作を実行する必要があります)。 + + + +</p> + +<p>{@link android.app.Activity#onPause +onPause()} メソッドで実行される処理量を比較的シンプルに抑えて、アクティビティが実際に停止している場合にユーザーの次の移動先への迅速な遷移を可能にする必要があります。 +</p> + +<p class="note"><strong>注:</strong> アクティビティが一時停止されると、{@link +android.app.Activity} インスタンスはメモリに常駐し、アクティビティが再開されたときに再び呼び出されます。再開状態に導くいずれかのコールバック メソッドの間に作成されたコンポーネントを再初期化する必要はありません。 + +</p> + + + +<h2 id="Resume">アクティビティを再開する</h2> + +<p>ユーザーが一時停止状態からアクティビティを再開した場合、システムは、{@link +android.app.Activity#onResume()} メソッドを呼び出します。</p> + +<p>新規に作成された場合を含め、アクティビティがフォアグラウンドに表示されるたびに、システムがこのメソッドを呼び出すことに注意してください。 +したがって、{@link +android.app.Activity#onPause()} メソッド中に解放したコンポーネントの初期化、およびアクティビティが再開状態になるたびに発生するその他の初期化(アニメーションの開始や、アクティビティがユーザーのフォーカスを取得したときにのみ使用されるコンポーネントの初期化など)を実行するように、{@link +android.app.Activity#onResume()} を実装する必要があります。 + +</p> + +<p>{@link android.app.Activity#onResume()} に関する次の例は、上記の +{@link android.app.Activity#onPause()} に関する例に対応するものであり、アクティビティが一時停止したときに解放されたカメラ機能を初期化します。 +</p> + +<pre> +@Override +public void onResume() { + super.onResume(); // Always call the superclass method first + + // Get the Camera instance as the activity achieves full user focus + if (mCamera == null) { + initializeCamera(); // Local method to handle camera init + } +} +</pre> + + + + + + + diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/recreating.jd new file mode 100644 index 0000000..8647375 --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/recreating.jd @@ -0,0 +1,178 @@ +page.title=アクティビティを再作成する +page.tags=アクティビティのライフサイクル +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>このレッスンでの学習内容</h2> + <ol> + <li><a href="#SaveState">自分のアクティビティ状態を保存する</a></li> + <li><a href="#RestoreState">自分のアクティビティ状態をリストアする</a></li> + </ol> + + <h2>関連ドキュメント</h2> + <ul> + <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">異なる画面のサポート +</a></li> + <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">実行時の変更を処理する</a></li> + <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a> + </li> + </ul> + + </div> +</div> + +<p>アクティビティには、通常のアプリの動作によって破棄されるいくつかのシナリオがあります。たとえば、ユーザーが <em>[戻る]</em> ボタンを押したり、アクティビティが {@link android.app.Activity#finish()} を呼び出すことによって自身の破棄を知らせる場合などです。 + +システムはまた、現在停止していて長時間使用されていないアクティビティがある場合や、フォアグラウンドのアクティビティが多くのリソースを必要とするためにシステムがメモリを取り戻すためにバックグラウンド プロセスを停止する必要がある場合にも、アクティビティを破棄することがあります。 + +</p> + +<p>ユーザーが <em>[戻る]</em> を押すか、アクティビティ自身が終了することでアクティビティが破棄されたとき、これらの動作はアクティビティの必要性がなくなったことを示すため、システムの方針として {@link android.app.Activity} インスタンスは永遠に失われます。 + +システムの制約(通常のアプリの動作ではなく)が原因で +アクティビティが破棄される場合、実際の +{@link android.app.Activity} インスタンスは失われますが、アクティビティが存在していたことをシステムが記憶しているため、ユーザーがアクティビティに復帰した場合は、破棄されたときのアクティビティの状態を記述する一連の保存されたデータを使用して、アクティビティの新しいインスタンスが作成されます。 + +システムが以前の状態を復元するために使用する保存されたデータは、「インスタンス状態」と呼ばれ、{@link android.os.Bundle} オブジェクトに格納されたキーと値のペアの集合です。 + +</p> + +<p class="caution"><strong>警告: </strong>ユーザーが画面を回転させるたびに、アクティビティが破棄され、再作成されます。 +画面の向きが変更されると、画面構成が変更され、アクティビティで(レイアウトなどの)代替リソースをロードする必要が生じる場合があるため、システムはフォアグラウンドのアクティビティを破棄し、再作成します。 + +</p> + +<p>デフォルトでは、システムは {@link android.os.Bundle} のインスタンス状態を使用して、アクティビティのレイアウトの各 {@link android.view.View} オブジェクトに関する情報を保存しています({@link android.widget.EditText} オブジェクトに入力されたテキスト値など)。 + +アクティビティのインスタンスが破棄され、再作成される場合、レイアウトの状態はコードを必要とすることなく以前の状態に復元されます。 + +しかし、アクティビティでは、アクティビティにおけるユーザーの作業状況を追跡しているメンバ変数などの、復元することが望ましいその他の情報が存在する可能性があります。 + +</p> + +<p class="note"><strong>注:</strong> Android システムがアクティビティのビューの状態を復元できるようにするためには、<strong>各ビューは固有の ID を持っている必要があります</strong>。これは + <a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code +android:id}</a> によって提供されます。 +</p> + +<p>アクティビティ状態についての追加データを保存するには、 +{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} コールバック メソッドをオーバーライドする必要があります。システムは、ユーザーがアクティビティを離れようとするとこのメソッドを呼び出し、{@link android.os.Bundle} オブジェクトに渡してアクティビティが予期せずに破棄された場合に備えて保存します。 + + +システムが後でアクティビティのインスタンスを再作成する必要がある場合は、同じ {@link +android.os.Bundle} オブジェクトを {@link android.app.Activity#onRestoreInstanceState +onRestoreInstanceState()} と {@link android.app.Activity#onCreate onCreate()} + の両方のメソッドに渡します。 +</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" /> +<p class="img-caption"><strong>図 2.</strong> システムがアクティビティを停止し始めると、 +{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}(1)が呼び出されるため、{@link android.app.Activity} インスタンスの再作成の必要がある場合に備えて、保存する追加の状態データを指定できます。アクティビティが破棄され、同じインスタンスを再作成する必要がある場合、システムは(1)で定義された状態データを {@link android.app.Activity#onCreate onCreate()} メソッド(2)と +{@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} メソッド(3)の両方に渡します。 + + + + +</p> + + + +<h2 id="SaveState">自分のアクティビティ状態を保存する</h2> + +<p>アクティビティが停止し始めると、システムは {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} を呼び出すため、アクティビティではキー値のペアのコレクションを使用して、状態情報を保存することができます。 +このメソッドのデフォルトの実装では、{@link android.widget.EditText} ウィジェット内のテキストまたは {@link android.widget.ListView} のスクロール位置などのアクティビティのビュー階層の状態に関する情報が保存されます。 + +</p> + +<p>アクティビティの追加の状態情報を保存するには、 +{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} を実装し、{@link android.os.Bundle} オブジェクトにキー値のペアを追加する必要があります。 +次に例を示します。</p> + +<pre> +static final String STATE_SCORE = "playerScore"; +static final String STATE_LEVEL = "playerLevel"; +... + +@Override +public void onSaveInstanceState(Bundle savedInstanceState) { + // Save the user's current game state + savedInstanceState.putInt(STATE_SCORE, mCurrentScore); + savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); + + // Always call the superclass so it can save the view hierarchy state + super.onSaveInstanceState(savedInstanceState); +} +</pre> + +<p class="caution"><strong>警告: </strong>デフォルトの実装でビュー階層の状態を保存できるよう、{@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} のスーパークラスの実装を常に呼び出す必要があります。 +</p> + + + +<h2 id="RestoreState">自分のアクティビティ状態をリストアする</h2> + +<p>以前破棄された後にアクティビティが再作成される場合、システムがアクティビティを渡した先の {@link android.os.Bundle} から、保存済みの状態を回復することができます。 + +{@link android.app.Activity#onCreate onCreate()} と {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} の両方のコールバック メソッドが、インスタンスの状態情報を含む同じ {@link android.os.Bundle} を受け取ります。 +</p> + +<p>{@link android.app.Activity#onCreate onCreate()} メソッドは、システムがアクティビティの新しいインスタンスを作成しているか、以前のものを復元しているかどうかに関係なく呼び出されるため、状態の {@link android.os.Bundle} を読み取る前にこれが null かどうかを確認する必要があります。 + +null の場合は、破棄された以前のアクティビティを復元する代わりにアクティビティの新しいインスタンスが作成されます。 + +</p> + +<p>{@link android.app.Activity#onCreate +onCreate()} で、いくつかの状態データを復元する方法について、次に例を示します。</p> + +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); // Always call the superclass first + + // Check whether we're recreating a previously destroyed instance + if (savedInstanceState != null) { + // Restore value of members from saved state + mCurrentScore = savedInstanceState.getInt(STATE_SCORE); + mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); + } else { + // Probably initialize members with default values for a new instance + } + ... +} +</pre> + +<p>{@link android.app.Activity#onCreate onCreate()} 中に状態を復元する代わりに、 +{@link android.app.Activity#onStart()} メソッドの後に呼び出される {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} の実装を選択できます。 +復元対象の保存済みの状態がある場合のみ {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} が呼び出されるため、 +{@link android.os.Bundle} が null であるかどうかをチェックする必要はありません。</p> + +<pre> +public void onRestoreInstanceState(Bundle savedInstanceState) { + // Always call the superclass so it can restore the view hierarchy + super.onRestoreInstanceState(savedInstanceState); + + // Restore state members from saved instance + mCurrentScore = savedInstanceState.getInt(STATE_SCORE); + mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); +} +</pre> + +<p class="caution"><strong>警告: </strong>デフォルトの実装でビュー階層の状態を復元できるよう、{@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} のスーパークラスの実装を常に呼び出す必要があります。 +</p> + +<p>実行時の再起動イベント(画面が回転したときなど)によるアクティビティの再作成の詳細については、<a href="{@docRoot}guide/topics/resources/runtime-changes.html">実行時の変更を処理する</a>をお読みください。 +</p> + diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/starting.jd new file mode 100644 index 0000000..7c865a9 --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/starting.jd @@ -0,0 +1,285 @@ +page.title=アクティビティを開始する +page.tags=アクティビティのライフサイクル +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#lifecycle-states">ライフサイクル コールバックを理解する</a></li> + <li><a href="#launching-activity">アプリのランチャーのアクティビティを指定する</a></li> + <li><a href="#Create">新しいインスタンスを作成する</a></li> + <li><a href="#Destroy">アクティビティを破棄する</a></li> +</ol> + + <h2>関連ドキュメント</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a></li> + </ul> + +<h2>試してみる</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">デモのダウンロード</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>{@code main()} メソッドを使用してアプリを起動する他のプログラミング パラダイムとは異なり、Android システムでは、そのライフサイクルの特定の段階に対応する特定のコールバック メソッドを呼び出すことによって、{@link android.app.Activity} インスタンスでコードを開始します。 + + +アクティビティを起動するコールバック メソッドのシーケンスと、アクティビティを破棄するコールバック メソッドのシーケンスがあります。 +</p> + +<p>このレッスンでは、最も重要なライフサイクル メソッドの概要を示し、アクティビティの新しいインスタンスを作成する最初のライフサイクル コールバックを扱う方法について説明します。 +</p> + + + +<h2 id="lifecycle-states">ライフサイクル コールバックを理解する</h2> + +<p>アクティビティの存続期間において、システムは、階段ピラミッド型のシーケンスで、ライフサイクル メソッドのコア セットを呼び出します。 +つまり、アクティビティのライフサイクルの各段階は、ピラミッドの個別の段です。 +システムが新しいアクティビティのインスタンスを作成すると、各コールバック メソッドはアクティビティ状態を 1 ステップ上に向かって移動させます。 +ピラミッドの頂点は、アクティビティがフォアグラウンドで実行されるポイントであり、ユーザーはそこで操作を行うことができます。 +</p> + +<p>ユーザーがアクティビティを離れる操作を始めると、システムはアクティビティを破棄するために、アクティビティ状態をピラミッドの下に向かって移動させる、別のメソッドを呼び出します。 +アクティビティがピラミッドの下に向かって途中まで移動し、待機する場合がありますが(ユーザーが別のアプリに切り替えた場合など)、そのポイントからアクティビティは頂点に戻ることができ(ユーザーがアクティビティに戻った場合)、アクティビティはユーザーが離れた場所から再開します。 + + +</p> + + +<img src="{@docRoot}images/training/basics/basic-lifecycle.png" /> +<p class="img-caption"><strong>図 1.</strong> アクティビティのライフサイクルの簡略図は階段ピラミッドとして表現されます。 +ここでは、アクティビティを頂点の再開状態に向かって 1 ステップ移動させるために使用されるすべてのコールバックに対して、下に向かってアクティビティを移動させるコールバック メソッドがどのように分布しているかを示しています。 + +アクティビティはまた、一時停止や停止の状態から再開した状態に復帰することができます。 +</p> + + +<p>アクティビティの複雑さにもよりますが、すべてのライフサイクルメソッドを実装する必要はありません。 +ただし、それぞれを理解して、自分のアプリがユーザーの期待どおり動作するよう実装することが重要です。 +アクティビティのライフサイクル メソッドを正しく実装すると、自分のアプリが次を含めたいくつかの状態で良好に動作するようになります。 +</p> +<ul> + <li>アプリの使用中にユーザーが電話を受けたり、別のアプリに切り替えた場合にもクラッシュしません。 +</li> + <li>ユーザーの使用頻度が低いときは、貴重なシステムリソースを消費しません。 +</li> + <li>ユーザーがアプリから離れ、後で復帰した場合でも、アプリを離れた時点における作業状態を失いません。 +</li> + <li>画面の向きが横長と縦長との間で切り替わったときも、クラッシュしたり、ユーザーの作業内容が失われることがありません。 +</li> +</ul> + +<!-- +<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback +methods.</p> +<table> + <tr> + <th scope="col">Lifecycle State</th> + <th scope="col">Startup Method</th> + <th scope="col">Teardown Method</th> + </tr> + <tr> + <td>Created / Destroyed</td> + <td>{@link android.app.Activity#onCreate onCreate()}</td> + <td>{@link android.app.Activity#onDestroy()}</td> + </tr> + <tr> + <td>Started / Stopped</td> + <td>{@link android.app.Activity#onStart()}</td> + <td>{@link android.app.Activity#onStop()}</td> + </tr> + <tr> + <td>Resumed / Resumed</td> + <td>{@link android.app.Activity#onResume()}</td> + <td>{@link android.app.Activity#onPause()}</td> + </tr> +</table> +--> + +<p>次のレッスンで学習するように、図 1 に示されているさまざまな状態間で起きるアクティビティ遷移には、いくつかの状況があります。 +ただし、これらの状態のうち 3 つのみが静的なものとなります。 +すなわち、アクティビティが長期間にわたる場合、3 つの状態のいずれかで存在することになります。 +</p> +<dl> + <dt>再開状態</dt> + <dd>この状態では、アクティビティがフォアグラウンドで実行され、ユーザーはそこで操作を行うことができます(「実行」状態とも呼ばれます)。 +</dd> + <dt>一時停止状態</dt> + <dd>この状態では、アクティビティは別のアクティビティによって部分的に隠されています。フォアグラウンドにある別のアクティビティは半透明になっているか、全画面をカバーしていません。 +一時停止したアクティビティはユーザーの入力を受信せず、一切のコードを実行できません。 + + <dt>停止状態</dt> + <dd>この状態では、アクティビティは完全に隠され、ユーザーには表示されません。バックグラウンドに存在するとみなされます。 +停止状態の間、アクティビティ インスタンスとメンバ変数のようなそのすべての状態情報は保持されますが、アクティビティ インスタンスは一切のコードを実行できません。 +</dd> +</dl> + +<p>他の状態(作成や起動の状態)は一過性であり、システムはすぐに次のライフサイクル コールバック メソッドを呼び出して、次の状態に移動します。 +つまり、システムは +{@link android.app.Activity#onCreate onCreate()} を呼び出した後、すぐに {@link +android.app.Activity#onStart()} を呼び出しますが、この後で速やかに {@link +android.app.Activity#onResume()} が続きます。</p> + +<p>以上が、アクティビティの基本ライフサイクルです。次に、特定のライフサイクルの動作のいくつかについて学習を開始しましょう。 +</p> + + + +<h2 id="launching-activity">アプリのランチャー アクティビティを指定する</h2> + +<p>ユーザーがホーム画面からアプリのアイコンを選択すると、システムはアプリ内で「ランチャー」(または「メイン」)のアクティビティであると宣言された {@link android.app.Activity} に対して {@link +android.app.Activity#onCreate onCreate()} メソッドを呼び出します。 +これは、アプリのユーザー インターフェースへのメインのエントリ ポイントとして機能するアクティビティです。 +</p> + +<p>プロジェクト ディレクトリのルートにある Android のマニフェスト ファイル、<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a> で、メインのアクティビティとして +どのアクティビティを使用するが定義することができます。</p> + +<p>アプリのメインのアクティビティは、{@link +android.content.Intent#ACTION_MAIN MAIN} アクションと {@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} カテゴリを含む <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> を使用してマニフェストで宣言する必要があります。 +次に例を示します。</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> +</pre> + +<p class="note"><strong>注:</strong> Android SDK ツールを使用して新しい Android プロジェクトを作成すると、デフォルトのプロジェクト ファイルに、このフィルタを用いてマニフェストで宣言された {@link android.app.Activity} クラスが含まれます。 + +</p> + +<p>自分のアクティビティの 1 つについて、{@link android.content.Intent#ACTION_MAIN MAIN} アクションまたは +{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} カテゴリのいずれかが宣言されていない場合は、アプリのアイコンがホーム画面のアプリ リストに表示されません。 +</p> + + + +<h2 id="Create">新しいインスタンスを作成する</h2> + +<p>ほとんどのアプリには、ユーザーが異なるアクションを実行できるようにする、いくつかの異なるアクティビティが含まれます。あるアクティビティが、ユーザーがアプリのアイコンをクリックしたときに作成されるメインのアクティビティであっても、ユーザーのアクションに応答してアプリが開始する別のアクティビティであっても、システムはその {@link +android.app.Activity#onCreate onCreate()} を呼び出すことにより、{@link android.app.Activity} の新しいインスタンスを毎回作成します。 + + +</p> + +<p>アクティビティの存続期間すべてにわたり、一度のみ発生すべき基本的なアプリの起動ロジックを実行するための +{@link android.app.Activity#onCreate onCreate()} メソッドを実装する必要があります。たとえば、 +{@link android.app.Activity#onCreate onCreate()} の実装では、ユーザー インターフェースを定義し、場合によってはいくつかのクラススコープの変数をインスタンス化する必要があります。 +</p> + +<p>たとえば、{@link android.app.Activity#onCreate onCreate()}メソッドに関する次の例では、(XML レイアウトファイルで定義される)ユーザー インターフェースを宣言したり、メンバ変数を定義したり、UI の一部を構成したりするなどの、アクティビティ用のいくつかの基本的なセットアップを実行する複数のコードを示しています。 + + +</p> + +<pre> +TextView mTextView; // Member variable for text view in the layout + +@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Set the user interface layout for this Activity + // The layout file is defined in the project res/layout/main_activity.xml file + setContentView(R.layout.main_activity); + + // Initialize member TextView so we can manipulate it later + mTextView = (TextView) findViewById(R.id.text_message); + + // Make sure we're running on Honeycomb or higher to use ActionBar APIs + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // For the main activity, make sure the app icon in the action bar + // does not behave as a button + ActionBar actionBar = getActionBar(); + actionBar.setHomeButtonEnabled(false); + } +} +</pre> + +<p class="caution"><strong>警告: </strong>{@link android.os.Build.VERSION#SDK_INT} を使用すると、Android 2.0(API レベル 5)以降でのみこの方法で動作する新しい API が古いシステムで実行してしまうことを回避できます。 + +古いバージョンでは、実行時の例外が発生します。</p> + +<p>{@link android.app.Activity#onCreate onCreate()} の実行が終了すると、システムが引き続き {@link android.app.Activity#onStart()} と {@link android.app.Activity#onResume()} メソッドを呼び出します。 + +アクティビティは、作成や開始の状態で留まることはありません。技術的には、アクティビティは {@link android.app.Activity#onStart()} が呼び出されたときにユーザーに表示されますが、すぐに +{@link android.app.Activity#onResume()} が続き、電話の着信やユーザーが別のアクティビティに移動したり、端末の画面がオフになったりした際のように、状態を変える状況が発生するまで、アクティビティは再開状態のままとなります。 + + +</p> + +<p>この後に続く他のレッスンでは、その他の起動メソッドである {@link +android.app.Activity#onStart()} と {@link android.app.Activity#onResume()} が一時停止状態または停止状態からアクティビティを再開するために使用された場合、これらのメソッドがアクティビティのライフサイクル中にいかに有用であるかを説明します。 +</p> + +<p class="note"><strong>注:</strong> {@link android.app.Activity#onCreate onCreate()}メソッドには、<a href="recreating.html">アクティビティの再作成</a>についての後続のレッスンで説明している <code>savedInstanceState</code> と呼ぶパラメータが含まれています。 + +</p> + + +<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" /> +<p class="img-caption"><strong>図 2.</strong> アクティビティの新しいインスタンスを作成する際に +システムが順に呼び出す 3 つの主なコールバックである +{@link android.app.Activity#onCreate onCreate()}、{@link +android.app.Activity#onStart()}、{@link android.app.Activity#onResume()} を強調した、アクティビティのライフサイクル構造の別の図です。コールバックのこのシーケンスが完了すると、アクティビティは再開状態に達し、ユーザーは別のアクティビティに切り替えるまではこのアクティビティを操作できます。 + +</p> + + + + + + + +<h2 id="Destroy">アクティビティを破棄する</h2> + +<p>アクティビティの最初のライフサイクル コールバックは、{@link android.app.Activity#onCreate +onCreate()} であり、最終のコールバックは {@link android.app.Activity#onDestroy} です。システムは、アクティビティのインスタンスが完全にシステム メモリから削除される最終的な指示として、アクティビティでこのメソッドを呼び出します。 + +</p> + +<p>ほとんどのアプリでは、このメソッドを実装する必要はありません。なぜなら、ローカルのクラス参照はアクティビティを使用して破棄され、自分のアクティビティでは、{@link +android.app.Activity#onPause} と {@link android.app.Activity#onStop} の間にほぼすべてのクリーンアップを実行する必要があるからです。 +ただし、アクティビティに、{@link +android.app.Activity#onCreate onCreate()} の間、または他の長時間実行中のリソースで作成された、正常に閉じないとメモリのリークを引き起こす可能性のあるバックグラウンド スレッドが含まれている場合、{@link +android.app.Activity#onDestroy} の間にそれらを破棄する必要があります。 + +</p> + +<pre> +@Override +public void onDestroy() { + super.onDestroy(); // Always call the superclass + + // Stop method tracing that the activity started during onCreate() + android.os.Debug.stopMethodTracing(); +} +</pre> + +<p class="note"><strong>注:</strong> ある状況を除くすべての状況では、システムは{@link android.app.Activity#onPause} と {@link +android.app.Activity#onStop} を呼び出した後に {@link android.app.Activity#onDestroy}を呼び出します。ある状況とは、{@link android.app.Activity#onCreate onCreate()}メソッド内から {@link +android.app.Activity#finish()} を呼び出したときです。 + +自分のアクティビティが別のアクティビティを起動するための一時的な意思決定機能として動作する場合のようないくつかのケースでは、{@link +android.app.Activity#onCreate onCreate()} 内から {@link android.app.Activity#finish()} を呼び出してアクティビティを破棄できます。 +この場合、システムは他のライフサイクルの任意のメソッドを呼び出すことなく、すぐに {@link android.app.Activity#onDestroy} を呼び出します。 + +</p> diff --git a/docs/html-intl/intl/ja/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/stopping.jd new file mode 100644 index 0000000..0007fe6 --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/activity-lifecycle/stopping.jd @@ -0,0 +1,187 @@ +page.title=アクティビティの停止と再起動 +page.tags=アクティビティのライフサイクル +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>このレッスンでの学習内容</h2> + <ol> + <li><a href="#Stop">アクティビティを停止する</a></li> + <li><a href="#Start">アクティビティを開始/再起動する</a></li> + </ol> + + <h2>関連ドキュメント</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">アクティビティ</a> + </li> + </ul> + +<h2>試してみる</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">デモのダウンロード</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>アクティビティを適切に停止、再起動することは、アクティビティのライフサイクルにおいて重要なプロセスであり、これによりアプリが常に動作中であり、進捗中の作業が失われないことをユーザーが認識できるようになります。アクティビティを停止して再開させるシナリオの主な例を次に示します。 + +</p> + +<ul> + <li>ユーザーが [最近使用したアプリ] ウィンドウを開き、現在のアプリから別のアプリに切り替えると、現在フォアグラウンドにあるアプリのアクティビティが停止します。 +ユーザーがホーム画面のランチャー アイコンまたは [最近使用したアプリ] ウィンドウから復帰した場合は、アクティビティは再起動します。 +</li> + <li>ユーザーが新しいアクティビティを開始するアプリ内のアクションを実行します。2 番目のアクティビティが作成されると現在のアクティビティが停止します。 +ユーザーが <em>[戻る]</em> ボタンを押すと、最初のアクティビティが再起動されます。 +</li> + <li>ユーザーが自分の携帯電話でアプリの使用中に電話を受けます。</li> +</ul> + +<p>{@link android.app.Activity} クラスでは、{@link +android.app.Activity#onStop()} と {@link android.app.Activity#onRestart()} の 2 つのライフサイクル メソッドが提供され、アクティビティの停止動作と再起動動作を明確に制御できます。 +UI が部分的に隠されることでわかる一時停止状態とは異なり、停止状態では必ず UI が完全に表示されなくなり、ユーザーのフォーカスが別のアクティビティ(または完全に別個のアプリ)に移ります。 + +</p> + +<p class="note"><strong>注:</strong> {@link android.app.Activity}インスタンスは、停止中にシステム メモリ内に保持されるため、 +{@link android.app.Activity#onStop()} と {@link android.app.Activity#onRestart()} (さらに {@link +android.app.Activity#onStart()})メソッドを実装する必要がない場合があります。 +比較的単純なほとんどのアクティビティの場合、アクティビティの停止と再起動が問題なく行われるため、現行のアクションを一時停止してシステム リソースから切り離すために {@link +android.app.Activity#onPause()} を使用するだけでよい場合もあります。 +</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" /> +<p class="img-caption"><strong>図 1.</strong> ユーザーがアクティビティを離れたとき、システムは +{@link android.app.Activity#onStop onStop()} を呼び出してアクティビティ(1)を停止します。アクティビティが停止している間にユーザーが復帰した場合、システムは {@link android.app.Activity#onRestart onRestart()} +(2)を呼び出し、すぐに {@link android.app.Activity#onStart onStart()}(3)と {@link +android.app.Activity#onResume()}(4)が続きます。 +アクティビティを停止させるシナリオによらず、システムは {@link +android.app.Activity#onStop onStop()} を呼び出す前に、常に {@link android.app.Activity#onPause onPause()} を呼び出すことに注意してください。 +</p> + + + +<h2 id="Stop">アクティビティを停止する</h2> + +<p>アクティビティは {@link android.app.Activity#onStop()} メソッドの呼び出しを受信すると表示されなくなり、ユーザーが使用していない間は必要とされないほぼすべてのリソースが解放されます。 + +アクティビティが停止すると、システムはそのメモリを取り戻す必要がある場合に、インスタンスを破棄することがあります。 +極端な場合には、システムは、アクティビティの最終段階に当たる {@link android.app.Activity#onDestroy()} コールバックを呼び出すことなく、アプリのプロセスを強制終了する場合があるため、 +{@link android.app.Activity#onStop()} を使用してメモリのリークを引き起こす可能性があるリソースを解放することが重要です。 +</p> + +<p>{@link android.app.Activity#onPause onPause()} メソッドが +{@link android.app.Activity#onStop()} の前に呼び出されますが、データベースに情報を書き込むような、規模が大きく CPU に負荷がかかるシャットダウン操作を実行するためには {@link android.app.Activity#onStop onStop()}を使用する必要があります。 + +</p> + +<p>永続ストレージに下書きのメモの内容を保存する {@link android.app.Activity#onStop onStop()} の実装の例を次に示します。 +</p> + +<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a +separate thread but that's too complicated to show here. --> +<pre> +@Override +protected void onStop() { + super.onStop(); // Always call the superclass method first + + // Save the note's current draft, because the activity is stopping + // and we want to be sure the current note progress isn't lost. + ContentValues values = new ContentValues(); + values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()); + values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()); + + getContentResolver().update( + mUri, // The URI for the note to update. + values, // The map of column names and new values to apply to them. + null, // No SELECT criteria are used. + null // No WHERE columns are used. + ); +} +</pre> + +<p>アクティビティが停止すると、{@link android.app.Activity} オブジェクトはメモリに常駐し、アクティビティが再開したときに再び呼び出されます。 +再開状態に導くいずれかのコールバック メソッドの間に作成されたコンポーネントを再初期化する必要はありません。 +また、レイアウト内の各 {@link android.view.View} の現在の状態が追跡されます。そのため、ユーザーが {@link android.widget.EditText} ウィジェットにテキストを入力した場合、その内容が保持されるので、それを保存、復元する必要はありません。 + + +</p> + +<p class="note"><strong>注:</strong> アクティビティが停止している間にシステムにより破棄された場合でも、依然として {@link android.os.Bundle}(ひとまとまりのキー値のペア)の {@link android.view.View} オブジェクト({@link +android.widget.EditText} のテキストなど)の状態を保持し、ユーザーがアクティビティの同じインスタンスに復帰した場合には、それらを復元します(次の<a href="recreating.html">レッスン</a>では、アクティビティが破棄され、再作成された場合に、その他の状態データを保存するために {@link android.os.Bundle} を使用する方法の詳細について説明します)。 + + +</p> + + + +<h2 id="Start">アクティビティを開始/再起動する</h2> + +<p>アクティビティが停止状態からフォアグラウンドに復帰したとき、 +{@link android.app.Activity#onRestart()} の呼び出しを受信します。システムはまた、アクティビティが表示されるたびに(再起動か新規に作成された場合かのいずれか) {@link +android.app.Activity#onStart()} メソッドを呼び出します。 +ただし、{@link +android.app.Activity#onRestart()} メソッドはアクティビティが停止状態から再開する場合にのみ呼び出されるため、アクティビティが以前に停止したが破壊されていない場合にのみ必要となる可能性がある、特別な復旧作業を実行するためにこれを使用できます。 + +</p> + +<p>多くの場合、アプリがアクティビティの状態を復元するために {@link android.app.Activity#onRestart()} の使用が必要となることはないため、一般的な多くのアプリに適用されるこのメソッドに関するガイドラインはありません。 + +ただし、{@link android.app.Activity#onStop()} メソッドは、基本的にアクティビティのすべてのリソースをクリーンアップするため、アクティビティが再起動した際には再インスタンス化する必要があります。 + +また、アクティビティが新規に作成されたとき(アクティビティの既存のインスタンスがない場合)にも、インスタンス化する必要があります。 +このような理由から、{@link android.app.Activity#onStop()} メソッドへの対応として、通常は {@link android.app.Activity#onStart()} コールバック メソッドを使用する必要があります。なぜなら、アクティビティを作成したときと停止状態からアクティビティを再開したときの両方において、システムが {@link +android.app.Activity#onStart()} を呼び出すからです。 + + +</p> + +<p>たとえば、ユーザーが復帰まで長時間アプリから離れている可能性があるため、 +{@link android.app.Activity#onStart()} メソッドは、必要なシステム機能が有効になっているかを確認する場合に有用です。 +</p> + +<pre> +@Override +protected void onStart() { + super.onStart(); // Always call the superclass method first + + // The activity is either being restarted or started for the first time + // so this is where we should make sure that GPS is enabled + LocationManager locationManager = + (LocationManager) getSystemService(Context.LOCATION_SERVICE); + boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + if (!gpsEnabled) { + // Create a dialog here that requests the user to enable GPS, and use an intent + // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action + // to take the user to the Settings screen to enable GPS when they click "OK" + } +} + +@Override +protected void onRestart() { + super.onRestart(); // Always call the superclass method first + + // Activity being restarted from stopped state +} +</pre> + + + + +<p>システムがアクティビティを破棄する場合は、{@link android.app.Activity} に対して {@link android.app.Activity#onDestroy()} メソッドが呼び出されます。 +通常、{@link android.app.Activity#onStop()} を使用してリソースのほとんどを解放している可能性があるため、{@link +android.app.Activity#onDestroy()} の呼び出しを受信する時点では、大抵のアプリでは必要な作業は少なくなっています。 +このメソッドは、メモリ リークにつながる可能性を持つリソースを一掃する最後のチャンスであるため、付加的なスレッドが破棄され、さらにメソッドのトレースのような長時間実行するその他のアクションも停止するようにする必要があります。 + + +</p> + diff --git a/docs/html-intl/intl/ja/training/basics/data-storage/databases.jd b/docs/html-intl/intl/ja/training/basics/data-storage/databases.jd new file mode 100644 index 0000000..d0a4d8f --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/data-storage/databases.jd @@ -0,0 +1,317 @@ +page.title=SQL データベースにデータを保存する +page.tags=データ保存 +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#DefineContract">スキーマとコントラクトを定義する</a></li> + <li><a href="#DbHelper">SQL ヘルパーを使用してデータベースを作成する</a></li> + <li><a href="#WriteDbRow">データベースに情報を格納する</a></li> + <li><a href="#ReadDbRow">データベースから情報を読み取る</a></li> + <li><a href="#DeleteDbRow">データベースから情報を削除する</a></li> + <li><a href="#UpdateDbRow">データベースを更新する</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#db">データベースを使用する</a></li> +</ul> + +<!-- +<h2>Try it out</h2> + +<div class="download-box"> + <a href="{@docRoot}shareables/training/Sample.zip" class="button">Download the sample</a> + <p class="filename">Sample.zip</p> +</div> +--> + +</div> +</div> + + +<p>データベースへのデータ保存は、連絡先情報などの繰り返し使用する、または構造化されたデータに最適です。 +このクラスでは、受講者が全般的な SQL データベースの知識に精通していることを前提としており、Android 上での SQLite データベースの導入を支援します。 + +Android 上でのデータベース使用の際に必要な API は、{@link android.database.sqlite} パッケージに含まれています。 +</p> + + +<h2 id="DefineContract">スキーマとコントラクトを定義する</h2> + +<p>SQL データベースの重要な要素の 1 つがスキーマであり、これはデータベースの編成方法に関する正式な宣言です。 +スキーマは、データベースを作成するために使用する SQL 文に反映されます。 +<em>コントラクト</em> クラスとして知られているコンパニオン クラスの作成が有用です。コンパニオン クラスでは、スキーマのレイアウトを明示的に、そして体系的な自己文書化する方法で指定します。 + +</p> + +<p>コントラクト クラスは、URI、表、列の名前を定義する定数のコンテナです。 +コントラクト クラスを使用すると、同じパッケージ内の他のすべてのクラスで、同じ定数を使用することができます。 +これにより、1 つの場所で列名を変更した場合に、それをコード全体にプロパゲートすることができます。 +</p> + +<p>コントラクト クラスを編成するお勧めの方法の 1 つは、クラスのルート レベルでデータベース全体に対しグローバルな定義を設定することです。 +その後、その列を列挙する各表の内部クラスを作成します。 +</p> + +<p class="note"><strong>注:</strong> {@link +android.provider.BaseColumns} インターフェースを実装することで、内部クラスでは、カーソル アダプタのようないくつかの Android クラスでも存在を想定されている、 +{@code _ID} と呼ばれるプライマリキーフィールドを継承することができます。 +これは必須ではありませんが、データベースが Android フレームワークと調和して動作する上で役立ちます。 +</p> + +<p>たとえば、次のスニペットでは、単一の表の表名と列名を定義します。 +</p> + + +<pre> +public final class FeedReaderContract { + // To prevent someone from accidentally instantiating the contract class, + // give it an empty constructor. + public FeedReaderContract() {} + + /* Inner class that defines the table contents */ + public static abstract class FeedEntry implements BaseColumns { + public static final String TABLE_NAME = "entry"; + public static final String COLUMN_NAME_ENTRY_ID = "entryid"; + public static final String COLUMN_NAME_TITLE = "title"; + public static final String COLUMN_NAME_SUBTITLE = "subtitle"; + ... + } +} +</pre> + + + +<h2 id="DbHelper">SQL ヘルパーを使用してデータベースを作成する</h2> + +<p>データベースの概要を定義した後、データベースと表を作成、管理するメソッドを実装する必要があります。 +表を作成して削除するための一般的な宣言の例を次にいくつか示します。 +</P> + +<pre> +private static final String TEXT_TYPE = " TEXT"; +private static final String COMMA_SEP = ","; +private static final String SQL_CREATE_ENTRIES = + "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" + + FeedEntry._ID + " INTEGER PRIMARY KEY," + + FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP + + FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP + + ... // Any other options for the CREATE command + " )"; + +private static final String SQL_DELETE_ENTRIES = + "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME; +</pre> + +<p>デバイスの<a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">内部ストレージ</a>にファイルを保存する場合と同様に、Android はアプリケーションに関連付けられているプライベート ディスク スペースにデータベースを格納します。 + +デフォルトでは、この領域は他のアプリケーションからアクセスできないため、データの安全性は確保されています。 +</p> + +<p>一連の便利な API が、{@link +android.database.sqlite.SQLiteOpenHelper}クラスで利用できます。このクラスを使用してデータベースへの参照を取得すると、<em>アプリケーションの起動時にではなく</em>必要な場合にのみ、データベースの作成、更新などの時間がかかる可能性が高い操作が実行されます。 + + + + +{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} または +{@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} の呼び出し以外は必要ありません。</p> + +<p class="note"><strong>注:</strong> 長時間実行する可能性があるため、 +{@link android.os.AsyncTask} または {@link android.app.IntentService} などを使用して、{@link +android.database.sqlite.SQLiteOpenHelper#getWritableDatabase} または {@link +android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} をバックグラウンド スレッドで呼び出すようにしてください。 +</p> + +<p>{@link android.database.sqlite.SQLiteOpenHelper} を使用するには、 +{@link +android.database.sqlite.SQLiteOpenHelper#onCreate onCreate()}、{@link +android.database.sqlite.SQLiteOpenHelper#onUpgrade onUpgrade()}、{@link +android.database.sqlite.SQLiteOpenHelper#onOpen onOpen()} コールバック メソッドを上書きするサブクラスを作成します。また +{@link android.database.sqlite.SQLiteOpenHelper#onDowngrade onDowngrade()} を実装することもできますが、必須ではありません。 +</p> + +<p>次に、上記に示したいくつかのコマンドを使用した {@link +android.database.sqlite.SQLiteOpenHelper} の実装例を示します。</p> + +<pre> +public class FeedReaderDbHelper extends SQLiteOpenHelper { + // If you change the database schema, you must increment the database version. + public static final int DATABASE_VERSION = 1; + public static final String DATABASE_NAME = "FeedReader.db"; + + public FeedReaderDbHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + public void onCreate(SQLiteDatabase db) { + db.execSQL(SQL_CREATE_ENTRIES); + } + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + // This database is only a cache for online data, so its upgrade policy is + // to simply to discard the data and start over + db.execSQL(SQL_DELETE_ENTRIES); + onCreate(db); + } + public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { + onUpgrade(db, oldVersion, newVersion); + } +} +</pre> + +<p>データベースにアクセスするには、{@link +android.database.sqlite.SQLiteOpenHelper} のサブクラスのインスタンスを作成します。</p> + +<pre> +FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext()); +</pre> + + + + +<h2 id="WriteDbRow">データベースに情報を格納する</h2> + +<p>{@link android.content.ContentValues}オブジェクトを {@link android.database.sqlite.SQLiteDatabase#insert insert()} メソッドに渡してデータベースにデータを格納できます。 +</p> + +<pre> +// Gets the data repository in write mode +SQLiteDatabase db = mDbHelper.getWritableDatabase(); + +// Create a new map of values, where column names are the keys +ContentValues values = new ContentValues(); +values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id); +values.put(FeedEntry.COLUMN_NAME_TITLE, title); +values.put(FeedEntry.COLUMN_NAME_CONTENT, content); + +// Insert the new row, returning the primary key value of the new row +long newRowId; +newRowId = db.insert( + FeedEntry.TABLE_NAME, + FeedEntry.COLUMN_NAME_NULLABLE, + values); +</pre> + +<p>{@link android.database.sqlite.SQLiteDatabase#insert insert()}の最初の引数は単なる表の名前です。 +2 番目の引数は列の名前を指定します。この列では、{@link android.content.ContentValues} が空の場合にフレームワークが NULL を挿入できます(これを {@code "null"} に設定した場合、フレームワークは値がない場合には行を挿入しません)。 + + +</p> + + + + +<h2 id="ReadDbRow">データベースから情報を読み取る</h2> + +<p>データベースから情報を読み取るには、{@link android.database.sqlite.SQLiteDatabase#query query()}メソッドを使用して選択条件および対象となる列をこれに渡します。このメソッドは、{@link android.database.sqlite.SQLiteDatabase#insert insert()}と {@link android.database.sqlite.SQLiteDatabase#update update()} 要素を組み合わせたもので(列リストを除く)、挿入するデータではなく取得対象のデータを定義します。 + + + +クエリの結果は、 +{@link android.database.Cursor} オブジェクトとして返されます。</p> + +<pre> +SQLiteDatabase db = mDbHelper.getReadableDatabase(); + +// Define a <em>projection</em> that specifies which columns from the database +// you will actually use after this query. +String[] projection = { + FeedEntry._ID, + FeedEntry.COLUMN_NAME_TITLE, + FeedEntry.COLUMN_NAME_UPDATED, + ... + }; + +// How you want the results sorted in the resulting Cursor +String sortOrder = + FeedEntry.COLUMN_NAME_UPDATED + " DESC"; + +Cursor c = db.query( + FeedEntry.TABLE_NAME, // The table to query + projection, // The columns to return + selection, // The columns for the WHERE clause + selectionArgs, // The values for the WHERE clause + null, // don't group the rows + null, // don't filter by row groups + sortOrder // The sort order + ); +</pre> + +<p>Cursor 内の特定の行に注目するには、いずれかの {@link android.database.Cursor} 移動メソッドを使用します。これは、必ず値の読み取りを開始する前に呼び出す必要があります。 +通常、初めに +{@link android.database.Cursor#moveToFirst} を呼び出します。これは、結果の最初のエントリ上に「読み取り位置」を置きます。 +各行では、{@link android.database.Cursor#getString +getString()} または {@link android.database.Cursor#getLong getLong()} のような +{@link android.database.Cursor} 取得メソッドのいずれかを呼び出すことによって、列の値を読み取ることができます。各取得メソッドに対して、必要な列のインデックス位置を渡す必要があります。これは、{@link android.database.Cursor#getColumnIndex getColumnIndex()} または +{@link android.database.Cursor#getColumnIndexOrThrow getColumnIndexOrThrow()}を呼び出すことによって取得できます。以下に例を示します。 + + +</p> + +<pre> +cursor.moveToFirst(); +long itemId = cursor.getLong( + cursor.getColumnIndexOrThrow(FeedEntry._ID) +); +</pre> + + + + +<h2 id="DeleteDbRow">データベースから情報を削除する</h2> + +<p>表から行を削除するには、削除対象の行を特定するための条件を指定する必要があります。 +データベース API により、SQL インジェクションから保護される選択条件を作成するメカニズムが提供されます。 +このメカニズムでは、選択の指定を選択句と選択引数に分割します。 +句では参照対象の列を定義し、また、列のテストを組み合わせることができます。 + +引数はテスト対象の値であり、句にバインドされます。結果は通常の SQL 文と同様には扱われないため、SQL インジェクションの影響を受けません。 + +</p> + +<pre> +// Define 'where' part of query. +String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; +// Specify arguments in placeholder order. +String[] selectionArgs = { String.valueOf(rowId) }; +// Issue SQL statement. +db.delete(table_name, selection, selectionArgs); +</pre> + + + +<h2 id="UpdateDbRow">データベースを更新する</h2> + +<p>データベースの値のサブセットを変更する必要がある場合には、{@link +android.database.sqlite.SQLiteDatabase#update update()} メソッドを使用します。</p> + +<p>表の更新では、{@link +android.database.sqlite.SQLiteDatabase#insert insert()} のコンテンツ値の構文と、 +{@link android.database.sqlite.SQLiteDatabase#delete delete()} の {@code where} 構文が組み合わされます。</p> + +<pre> +SQLiteDatabase db = mDbHelper.getReadableDatabase(); + +// New value for one column +ContentValues values = new ContentValues(); +values.put(FeedEntry.COLUMN_NAME_TITLE, title); + +// Which row to update, based on the ID +String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; +String[] selectionArgs = { String.valueOf(rowId) }; + +int count = db.update( + FeedReaderDbHelper.FeedEntry.TABLE_NAME, + values, + selection, + selectionArgs); +</pre> + diff --git a/docs/html-intl/intl/ja/training/basics/data-storage/files.jd b/docs/html-intl/intl/ja/training/basics/data-storage/files.jd new file mode 100644 index 0000000..dddfe37 --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/data-storage/files.jd @@ -0,0 +1,379 @@ +page.title=ファイルを保存する +page.tags=データ ストレージ +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#InternalVsExternalStorage">内部または外部ストレージを選択する</a></li> + <li><a href="#GetWritePermission">外部ストレージのパーミッションを取得する</a></li> + <li><a href="#WriteInternalStorage">内部ストレージ上にファイルを保存する</a></li> + <li><a href="#WriteExternalStorage">外部ストレージ上にファイルを保存する</a></li> + <li><a href="#GetFreeSpace">空き領域をクエリする</a></li> + <li><a href="#DeleteFile">ファイルを削除する</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">内部ストレージを使用する</a> +</li> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">外部ストレージを使用する</a> +</li> +</ul> + +</div> +</div> + +<p>Android は、他のプラットフォーム上のディスクベースの +ファイル システムと同様なファイルシステムを使用しています。このレッスンでは、 +{@link java.io.File} API を使用したファイルの読み書きに関する Android ファイルシステムの操作方法について説明します。 +</p> + +<p>{@link java.io.File} オブジェクトは、スキップすることなく開始から終了までの順序で大量のデータを読み取りまたは書き込みするのに適しています。 +これは、たとえば画像ファイルやネットワークを介して交換される任意のファイルに対して有効です。 +</p> + +<p>このレッスンでは、自分のアプリで基本的なファイル関連のタスクを実行する方法を紹介します。ここでは、Linux ファイルシステムの基礎と +{@link java.io} での標準的なファイル入力/出力の API に精通していることを前提としています。 +</p> + + +<h2 id="InternalVsExternalStorage">内部または外部ストレージを選択する</h2> + +<p>すべての Android 端末には、「内部」ストレージと「外部」ストレージの 2 つのファイル記憶領域があります。これらの名前は初期の Android の名残として、当時ほとんどの端末が内蔵の不揮発性メモリ(内部ストレージ)を備えていたのに加え、マイクロ SD カードのような取り外し可能な記憶媒体(外部記憶装置)も備えていたことから来ています。一部の端末では、永続的なストレージ領域を「内部」と「外部」のパーティションに分割しており、リムーバブル記憶媒体が備わっていない場合でも常に 2 つのストレージ スペースがあり、外部ストレージが取り外し可能であるか否かにかかわらず、API の動作は同じです。以下のリストでは、各ストレージ スペースの特徴を要約しています。 + + + + + +</p> + +<div class="col-5" style="margin-left:0"> +<p><b>内部ストレージ:</b></p> +<ul> +<li>常に使用可能。</li> +<li>ここに保存されたファイルは、デフォルトでは自分のアプリからのみアクセスできます。</li> +<li>ユーザーがアプリをアンインストールすると、システムは内部ストレージから当該アプリのファイルをすべて削除します。 +</li> +</ul> +<p>ユーザーからも他のアプリからも、自分のファイルにアクセスできないようにしたい場合、内部ストレージが最適です。 +</p> +</div> + +<div class="col-7" style="margin-right:0"> +<p><b>外部ストレージ:</b></p> +<ul> +<li>ユーザーは、USB ストレージなどの外部記憶装置をマウントできますが、端末から取り外す場合もあるため、常に使用可能というわけではありません。 +</li> +<li>誰でも読み取り可能なため、ここに保存されたファイルは自分のコントロールの及ばない所で読み取られる可能性があります。 +</li> +<li>ユーザーがアプリをアンインストールすると、当該アプリのファイルは、{@link android.content.Context#getExternalFilesDir +getExternalFilesDir()} からディレクトリに保存された場合に限り、ここからすべて削除されます。 +</li> +</ul> +<p>アクセス制限を必要としないファイルや、他のアプリと共有したり、ユーザーがコンピュータ経由でアクセスできるようにしたりするファイルの場合、外部ストレージが最適です。 + +</p> +</div> + + +<p class="note" style="clear:both"> +<strong>ヒント: </strong>アプリはデフォルトでは内部ストレージにインストールされますが、自分のアプリが外部ストレージにインストールされるように、マニフェスト内で <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code +android:installLocation}</a> 属性を指定できます。 + +APK のサイズが非常に大きく、内部ストレージよりも外部ストレージ容量が大きい場合、ユーザーにとってこのオプションは便利なものとなります。 +詳細については、<a href="{@docRoot}guide/topics/data/install-location.html">App Install Location</a> をご覧ください。 +</p> + + +<h2 id="GetWritePermission">外部ストレージのパーミッションを取得する</h2> + +<p>外部ストレージに書き込むには、自分の<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">マニフェスト ファイル</a>で +{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} パーミッションをリクエストする必要があります。</p> + +<pre> +<manifest ...> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + ... +</manifest> +</pre> + +<div class="caution"><p><strong>警告: </strong>現在、すべてのアプリは特別なパーミッションを必要とせずに、外部ストレージからの読み取りが可能です。 + +ただし、これは将来のリリースで変更される予定です。自分のアプリで外部ストレージの読み取り(書き込みではなく)の必要がある場合は、{@link +android.Manifest.permission#READ_EXTERNAL_STORAGE} パーミッションを宣言する必要があります。 +アプリが正常に動作し続けるようにするには、すぐにこのパーミッションを宣言して、変更を有効にする必要があります。 +</p> +<pre> +<manifest ...> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + ... +</manifest> +</pre> +<p>ただし、自分のアプリで {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}パーミッションを使用している場合は、暗黙的に外部ストレージの読み取りパーミッションも持つことになります。 +</p> +</div> + +<p>内部ストレージにファイルを保存する際には、一切のパーミッションを必要としません。 +自分のアプリは常に、内部ストレージ ディレクトリ内のファイルの読み取りおよび書き込みパーミッションを持っています。 +</p> + + + + + +<h2 id="WriteInternalStorage">内部ストレージ上にファイルを保存する</h2> + +<p>内部ストレージにファイルを保存する場合は、次の 2 つのメソッドのいずれかを呼び出すことにより、 +{@link java.io.File} として適切なディレクトリを取得することができます。</p> + +<dl> + <dt>{@link android.content.Context#getFilesDir}</dt> + <dd>自分のアプリ用の内部ディレクトリを示す {@link java.io.File} を返します。</dd> + <dt>{@link android.content.Context#getCacheDir}</dt> + <dd>自分のアプリの一時キャッシュ ファイル用の内部ディレクトリを示す {@link java.io.File} を返します。 +必要がなくなった各ファイルを削除して、1MB などの、任意の時点で使用するメモリ量として適度なサイズ制限を実装してください。 + +システムはストレージが不足し始めた場合、警告なしでキャッシュ ファイルを削除することがあります。 +</dd> +</dl> + +<p>これらのディレクトリのいずれかに新しいファイルを作成するには、自分の内部ストレージ ディレクトリを指定する、上記のいずれかのメソッドで提供された {@link java.io.File} を渡して、{@link +java.io.File#File(File,String) File()} コンストラクタを使用することができます。 +次に例を示します。</p> + +<pre> +File file = new File(context.getFilesDir(), filename); +</pre> + +<p>代わりに {@link +android.content.Context#openFileOutput openFileOutput()} を呼び出して、自分の内部ディレクトリ内のファイルに書き込みを行う {@link java.io.FileOutputStream}を取得することができます。 +ファイルにテキストを書き込む方法の例を次に示します。 +</p> + +<pre> +String filename = "myfile"; +String string = "Hello world!"; +FileOutputStream outputStream; + +try { + outputStream = openFileOutput(filename, Context.MODE_PRIVATE); + outputStream.write(string.getBytes()); + outputStream.close(); +} catch (Exception e) { + e.printStackTrace(); +} +</pre> + +<p>または、いくつかのファイルをキャッシュする必要がある場合は、代わりに {@link +java.io.File#createTempFile createTempFile()} を使用してください。たとえば、次のメソッドでは {@link java.net.URL} からファイル名を抽出し、自分のアプリの内部キャッシュ ディレクトリに、抽出した名前でファイルを作成します。 + +</p> + +<pre> +public File getTempFile(Context context, String url) { + File file; + try { + String fileName = Uri.parse(url).getLastPathSegment(); + file = File.createTempFile(fileName, null, context.getCacheDir()); + catch (IOException e) { + // Error while creating file + } + return file; +} +</pre> + +<p class="note"><strong>注:</strong>アプリの内部ストレージ ディレクトリは、Android ファイルシステムの特定の場所にアプリのパッケージ名で指定されています。技術的には、読み取り可能になるようファイル モードを設定した場合、別のアプリから自分の内部ストレージのファイルを読むことができます。 + + + +ただし、他のアプリ側でもアプリのパッケージ名とファイル名が既知である必要があります。 +他のアプリからは、自分のアプリの内部ディレクトリを参照することはできず、明示的にファイルを読み取り可能または書き込み可能に設定しない限り、読み書きのアクセス権もないからです。 +すなわち、内部ストレージ上のファイルに対して {@link android.content.Context#MODE_PRIVATE} を使用する限り、ファイルは他のアプリからアクセス可能になることはありません。 + +</p> + + + + + +<h2 id="WriteExternalStorage">外部ストレージ上にファイルを保存する</h2> + +<p>外部ストレージは使用できない場合があります(ユーザーが PC にストレージをマウントしているか、外部ストレージを提供する SD カードを取り外した場合など)。アクセスする前に、当該ボリュームが利用可能であるかを常に確認する必要があります。 + +{@link android.os.Environment#getExternalStorageState} を呼び出すことによって、外部ストレージの状態をクエリすることができます。 +返された状態が {@link android.os.Environment#MEDIA_MOUNTED} に等しい場合は、ファイルの読み取りと書き込みができます。 + +たとえば、次のメソッドは、ストレージの可用性を判断するのに有用です。 +</p> + +<pre> +/* Checks if external storage is available for read and write */ +public boolean isExternalStorageWritable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state)) { + return true; + } + return false; +} + +/* Checks if external storage is available to at least read */ +public boolean isExternalStorageReadable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state) || + Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { + return true; + } + return false; +} +</pre> + +<p>外部ストレージは、ユーザーや他のアプリから変更可能ですが、ここで保存可能なファイルには次の 2 つのカテゴリがあります。 +</p> + +<dl> + <dt>パブリック ファイル</dt> + <dd>他のアプリおよびユーザーから自由に利用可能にすべきファイル。 +ユーザーがアプリをアンインストールしても、これらのファイルはユーザーから利用可能なままにしておく必要があります。 + + <p>たとえば、アプリで撮影した写真、その他のダウンロードされたファイルなどです。</p> + </dd> + <dt>プライベート ファイル</dt> + <dd>正当に自分のアプリに帰属しているファイルは、ユーザーがアプリをアンインストールした時点で削除する必要があります。これらのファイルは外部ストレージ上にあるため、技術的にはユーザーと他のアプリからアクセス可能ですが、現実問題としてアプリを離れたユーザーにとって価値を持たないファイルです。そのため、ユーザーがアプリをアンインストールすると、アプリの外部プライベート ディレクトリ内のすべてのファイルが削除されます。 + + + + + <p>たとえば、自分のアプリでダウンロードした追加のリソースや一時的なメディア ファイルです。</p> + </dd> +</dl> + +<p>外部ストレージにパブリック ファイルを保存する場合は、 +{@link android.os.Environment#getExternalStoragePublicDirectory +getExternalStoragePublicDirectory()} メソッドを使用して、外部ストレージ上の適切なディレクトリを示す {@link java.io.File} を取得します。 +このメソッドは、{@link android.os.Environment#DIRECTORY_MUSIC} または {@link +android.os.Environment#DIRECTORY_PICTURES} などの保存するファイルの種類を指定する引数を取り、他のパブリック ファイルとともに論理的に整理することができます。 + +次に例を示します。</p> + +<pre> +public File getAlbumStorageDir(String albumName) { + // Get the directory for the user's public pictures directory. + File file = new File(Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_PICTURES), albumName); + if (!file.mkdirs()) { + Log.e(LOG_TAG, "Directory not created"); + } + return file; +} +</pre> + + +<p>自分のアプリのプライベート ファイルを保存する場合は、{@link +android.content.Context#getExternalFilesDir getExternalFilesDir()} を呼び出して希望するディレクトリのタイプを示す名前を渡し、適切なディレクトリを取得することができます。 + +このように作成した各ディレクトリは、ユーザーがアプリをアンインストールするときにシステムが削除するアプリの外部ストレージ ファイルのすべてをカプセル化する親ディレクトリに追加されます。 + +</p> + +<p>ここでは、個々のフォト アルバム用のディレクトリを作成するために使用できるメソッドの例を次に示します。</p> + +<pre> +public File getAlbumStorageDir(Context context, String albumName) { + // Get the directory for the app's private pictures directory. + File file = new File(context.getExternalFilesDir( + Environment.DIRECTORY_PICTURES), albumName); + if (!file.mkdirs()) { + Log.e(LOG_TAG, "Directory not created"); + } + return file; +} +</pre> + +<p>あらかじめ定義されたサブディレクトリ名のいずれもが自分のファイルに適合しない場合、代わりに {@link +android.content.Context#getExternalFilesDir getExternalFilesDir()} を呼び出し、{@code null} を渡すことができます。これにより、外部ストレージ上のアプリのプライベート ディレクトリのルート ディレクトリが返されます。 +</p> + +<p>{@link android.content.Context#getExternalFilesDir getExternalFilesDir()}は、ユーザーがアプリをアンインストールすると削除されるディレクトリ内にディレクトリを作成することに注意してください。ユーザーがアプリをアンインストールした後も、保存対象のファイルを利用可能にすべき場合(自分のアプリがカメラであり、ユーザーが撮った写真の利用を望むような場合)は、代わりに {@link android.os.Environment#getExternalStoragePublicDirectory +getExternalStoragePublicDirectory()} を使用する必要があります。 + + + +</p> + + +<p>共有ファイルに対して {@link android.os.Environment#getExternalStoragePublicDirectory +getExternalStoragePublicDirectory()} を使用しているか、自分のアプリにとってプライベートなファイルに対して +{@link android.content.Context#getExternalFilesDir +getExternalFilesDir()} を使用しているかどうかに関係なく、 +{@link android.os.Environment#DIRECTORY_PICTURES} のような API 定数が提供するディレクトリ名を使用することが重要です。 + +これらのディレクトリ名により、ファイルがシステムによって正しく処理されるようになります。 +たとえば、{@link +android.os.Environment#DIRECTORY_RINGTONES} に保存されたファイルは、システムのメディア スキャナにより音楽ではなく着信音として分類されます。 +</p> + + + + +<h2 id="GetFreeSpace">空き領域をクエリする</h2> + +<p>前もって保存対象のデータ量がわかっている場合は、{@link java.io.File#getFreeSpace} または {@link +java.io.File#getTotalSpace} 呼び出して、{@link +java.io.IOException} を生じさせることなく十分な空き領域が利用可能かどうかを調べることができます。 +これらのメソッドでは、それぞれ、ストレージ ボリューム内の現在利用可能な領域と総領域がそれぞれ得られます。 +この情報は、一定の閾値以上のストレージ ボリュームの消費を避けるためにも有用です。 +</p> + +<p>しかし、システム上、{@link java.io.File#getFreeSpace} で示されたバイト数の書き込みは保証されるものではありません。 +返された数量が保存するデータのサイズよりも数 MB 上回る場合、またはファイルシステムの使用率が 90%未満の場合は、続行しても安全でしょう。それ以外の場合は、ストレージへの書き込みは避けるべきです。 + + +</p> + +<p class="note"><strong>注:</strong> ファイルを保存する前に、使用可能な領域の量をチェックする必要はありません。 +代わりにすぐにファイルを書き込んでみて、不都合が生じた場合に {@link java.io.IOException} を受け取ることができます。 +正確にどのくらいの領域が必要か不明な場合は、これを行う必要がある場合があります。 +たとえばファイルを保存する前に、PNG 画像を JPEG に 変換してエンコーディングを変更した場合、事前にファイルのサイズを知ることができません。 + +</p> + + + + +<h2 id="DeleteFile">ファイルを削除する</h2> + +<p>不要になったファイルは、常に削除する必要があります。ファイルを削除する最も簡単な方法は、 +開かれたファイル上で参照呼び出し {@link java.io.File#delete} を行うことです。</p> + +<pre> +myFile.delete(); +</pre> + +<p>ファイルが内部ストレージに保存されている場合は、{@link android.content.Context} を使用して場所を特定し、 +{@link android.content.Context#deleteFile deleteFile()} を呼び出してファイルを削除することもできます。</p> + +<pre> +myContext.deleteFile(fileName); +</pre> + +<div class="note"> +<p><strong>注:</strong> ユーザーがアプリをアンインストールすると、Android システムは次を削除します。 +</p> +<ul> +<li>内部ストレージに保存したすべてのファイル</li> +<li>{@link +android.content.Context#getExternalFilesDir getExternalFilesDir()} を使用して外部ストレージに保存したすべてのファイル</li> +</ul> +<p>ただし、定期的に +{@link android.content.Context#getCacheDir()} で作成されたすべてのキャッシュ済みファイルを手動で削除し、必要なくなったファイルも定期的に削除する必要があります。 +</p> +</div> + diff --git a/docs/html-intl/intl/ja/training/basics/data-storage/index.jd b/docs/html-intl/intl/ja/training/basics/data-storage/index.jd new file mode 100644 index 0000000..9109143 --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/data-storage/index.jd @@ -0,0 +1,57 @@ +page.title=データの保存 +page.tags=データ ストレージ、ファイル、SQL、データベース、環境設定 +helpoutsWidget=true + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>必要な知識と前提条件</h2> +<ul> + <li>Android 1.6(API レベル 4)以降</li> + <li>Map のキー値コレクションに精通していること</li> + <li>Java ファイルの I/O API に精通していること</li> + <li>SQL データベースに精通していること</li> +</ul> + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html">ストレージ オプション</a></li> +</ul> + +</div> +</div> + +<p>ほとんどの Android アプリは、ユーザー操作の進行状況が失われないように {@link android.app.Activity#onPause onPause()} 中のアプリの状態に関する情報を保存する目的のみの場合でも、データを保存する必要があります。 +多くの主要アプリではユーザー設定も保存する必要があり、一部のアプリでは、ファイルやデータベース内の大量の情報を管理する必要があります。 + +このクラスでは、次のような Android の主要なデータ ストレージ オプションを紹介します。 +</p> + +<ul> + <li>単純なデータ タイプのキー値のペアを共有の環境設定ファイル内に保存する +</li> + <li>Android のファイル システム内に任意のファイルを保存する</li> + <li>SQLite で管理されたデータベースを使用する</li> +</ul> + + +<h2>レッスン</h2> + +<dl> + <dt><b><a href="shared-preferences.html">キー値セットを保存する</a></b></dt> + <dd>キー値ペアの少量の情報を格納するための、共有環境設定ファイルの使用について学びます。 +</dd> + + <dt><b><a href="files.html">ファイルを保存する</a></b></dt> + <dd>通常順に読み取られる長いデータ シーケンスの格納方法など、基本的なファイルの保存について学びます。 +</dd> + + <dt><b><a href="databases.html">SQL データベースにデータを保存する</a></b></dt> + <dd>構造化データを読み書きする際の SQLite データベースの使用について学びます。</dd> + +</dl> diff --git a/docs/html-intl/intl/ja/training/basics/data-storage/shared-preferences.jd b/docs/html-intl/intl/ja/training/basics/data-storage/shared-preferences.jd new file mode 100644 index 0000000..5f6d5ff --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/data-storage/shared-preferences.jd @@ -0,0 +1,120 @@ +page.title=キー値セットを保存する +page.tags=データ ストレージ +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#GetSharedPreferences">SharedPreferences を操作する</a></li> + <li><a href="#WriteSharedPreference">共有の環境設定に書き込む</a></li> + <li><a href="#ReadSharedPreference">共有の環境設定から読み取る</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#pref">共有の環境設定を使用する</a></li> +</ul> + +</div> +</div> + + +<p>保存しようとするキー値の比較的小さなコレクションがある場合は、 +{@link android.content.SharedPreferences} API を使用する必要があります。 +{@link android.content.SharedPreferences} オブジェクトは、キー値のペアを含むファイルをポイントし、読み取りと書き込み用の単純なメソッドを提供します。 +各 +{@link android.content.SharedPreferences} ファイルは、フレームワークによって管理され、プライベートまたは共有にすることができます。 +</p> + +<p>このクラスでは、{@link android.content.SharedPreferences} API を使用して単純な値を格納し、取得する方法について説明します。 +</p> + +<p class="note"><strong>注:</strong> {@link android.content.SharedPreferences} API は、キー値のペアの読み取りおよび書き込みの目的にのみ使用できます。自分のアプリの設定用のユーザー インタフェースのビルドを支援する + {@link android.preference.Preference} API と混同しないようにしてください(ただし、これらは + {@link android.content.SharedPreferences} を実装として使用してアプリの設定を保存します)。 + +{@link +android.preference.Preference} API の使用方法については、<a href="{@docRoot}guide/topics/ui/settings.html">設定</a>のガイドを参照してください。</p> + +<h2 id="GetSharedPreferences">SharedPreferences を操作する</h2> + +<p>新しい共有の環境設定ファイルを作成したり、次の 2 つのメソッドのいずれかを呼び出すことにより、既存のファイルにアクセスできます。 +</p> +<ul> + <li>{@link android.content.Context#getSharedPreferences(String,int) +getSharedPreferences()} - 最初のパラメータで指定した名前で識別される共有の環境設定ファイルが複数必要な場合に使用します。 +自分のアプリの任意の +{@link android.content.Context} から、これを呼び出すことができます。</li> + <li>{@link android.app.Activity#getPreferences(int) getPreferences()} - アクティビティに対して共有の環境設定ファイルを 1 つのみ使用する必要がある場合、 +{@link android.app.Activity} からこれを使用します。 +これにより、アクティビティに属するデフォルトの共有の環境設定ファイルを取得できるので、名前を指定する必要はありません。 +</li> +</ul> + +<p>たとえば、{@link android.app.Fragment} 内で次のコードが実行されます。これにより、リソース文字列 {@code R.string.preference_file_key} で識別する共有の環境設定ファイルにアクセスし、自分のアプリからのみアクセス可能になるよう、プライベート モードを使用して開きます。 + + +</p> + +<pre> +Context context = getActivity(); +SharedPreferences sharedPref = context.getSharedPreferences( + getString(R.string.preference_file_key), Context.MODE_PRIVATE); +</pre> + +<p>共有の環境設定ファイルに名前を付ける場合は、{@code "com.example.myapp.PREFERENCE_FILE_KEY"} のような、自分のアプリを識別できる、一意の名前を使用する必要があります。 +</p> + +<p>または、アクティビティ用に共有の環境設定ファイルが 1 つのみ必要な場合、 +{@link android.app.Activity#getPreferences(int) getPreferences()} メソッドを使用することができます。</p> + +<pre> +SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); +</pre> + +<p class="caution"><strong>警告: </strong>{@link android.content.Context#MODE_WORLD_READABLE} または {@link +android.content.Context#MODE_WORLD_WRITEABLE} を使用して共有の環境設定を作成した場合、ファイル識別子が既知である任意の他のアプリが自分のデータにアクセスできるようになります。 + +</p> + + +<h2 id="WriteSharedPreference">共有の環境設定に書き込む</h2> + +<p>共有の環境設定ファイルに書き込むには、自分の {@link android.content.SharedPreferences} で {@link +android.content.SharedPreferences#edit} を呼び出して、{@link +android.content.SharedPreferences.Editor} を作成します。</p> + +<p>{@link +android.content.SharedPreferences.Editor#putInt putInt()} や {@link +android.content.SharedPreferences.Editor#putString putString()} などのメソッドを使用して、書き込む対象のキーと値を渡します。{@link +android.content.SharedPreferences.Editor#commit} を呼び出して変更を保存します。次に例を示します。</p> + +<pre> +SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); +SharedPreferences.Editor editor = sharedPref.edit(); +editor.putInt(getString(R.string.saved_high_score), newHighScore); +editor.commit(); +</pre> + + +<h2 id="ReadSharedPreference">共有の環境設定から読み取る</h2> + +<p>共有の環境設定ファイルから希望の値を取得するには、{@link +android.content.SharedPreferences#getInt getInt()} や {@link +android.content.SharedPreferences#getString getString()} などのメソッドを呼び出して値のキーを指定しますが、オプションで、キーが存在しない場合に戻すデフォルト値を指定します。 + +次に例を示します。</p> + +<pre> +SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); +int defaultValue = getResources().getInteger(R.string.saved_high_score_default); +long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue); +</pre> + diff --git a/docs/html-intl/intl/ja/training/basics/intents/filters.jd b/docs/html-intl/intl/ja/training/basics/intents/filters.jd new file mode 100644 index 0000000..5f0d69a --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/intents/filters.jd @@ -0,0 +1,236 @@ +page.title=他のアプリからのアクティビティの開始を許可する +page.tags=インテント +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#AddIntentFilter">インテント フィルタを追加する</a></li> + <li><a href="#HandleIntent">自分のアクティビティでインテントを処理する</a></li> + <li><a href="#ReturnResult">結果を返す</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li> + <li><a href="{@docRoot}training/secure-file-sharing/index.html">ファイルの共有</a> +</ul> + </div> +</div> + +<p>前 2 回のレッスンでは、自分のアプリから別のアプリのアクティビティを開始する場合について焦点を当てました。一方、自分のアプリで別のアプリにとって役に立つかもしれないアクションを実行できる場合について、自分のアプリが他のアプリからのアクション要求に応答できるようにする必要があります。 + +たとえば、友人とメッセージや写真を共有できるソーシャル アプリをビルドした場合、ユーザーが別のアプリから「共有」アクションを開始し、こちら側のアプリを起動してそのアクションを実行できるよう、{@link android.content.Intent#ACTION_SEND} インテントをサポートすることが最善の方法です。 + + +</p> + +<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>アプリが端末にインストールされている場合、システムはインテント フィルタを識別し、インストールされているすべてのアプリでサポートされるインテントの内部カタログに情報を追加します。アプリが暗黙的インテントを使って {@link android.app.Activity#startActivity +startActivity()} または {@link android.app.Activity#startActivityForResult startActivityForResult()}を呼び出すと、システムがどのアクティビティ(または複数のアクティビティ)がインテントに応答できるかを特定します。 + + + +</p> + + + +<h2 id="AddIntentFilter">インテント フィルタを追加する</h2> + +<p>アクティビティがどのインテントを処理できるか適切に定義するためには、アクティビティが受け入れるアクションとデータのタイプについて、追加する各インテント フィルタをできるだけ具体的にする必要があります。 + +</p> + +<p>アクティビティが {@link android.content.Intent} オブジェクトに関する次の基準を満たしているインテント フィルタを持つ場合、システムは、アクティビティに対して所定の {@link android.content.Intent} を送信することができます。 +</p> + +<dl> + <dt>アクション</dt> + <dd>実行するアクション名を表す文字列。通常、 +{@link android.content.Intent#ACTION_SEND} や {@link android.content.Intent#ACTION_VIEW} などのプラットフォームに定義された値のいずれか。 + <p><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a> 要素を使用してインテント フィルタでこれを指定します。この要素で指定した値は、API 定数ではなく、アクションの完全な文字列名(下記の例を参照)である必要があります。 + +</p></dd> + + <dt>データ</dt> + <dd>インテントに関連するデータの詳細。 + <p><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> 要素を使用して、インテント フィルタでこれを指定します。この要素で 1 つ以上の属性を +使用して、MIME タイプのみ、URI 接頭辞のみ、URI スキームのみ、またはこれらと受け入れられるデータ タイプを示すその他の項目の組み合わせを指定することができます。 + +</p> + <p class="note"><strong>注:</strong> {@link android.net.Uri} データに関する詳細を宣言する必要がない場合(アクティビティが URI ではなく他の種類の「特別」データを処理するときなど)は、 +{@code text/plain} {@code image/jpeg} のようなアクティビティが処理するデータのタイプを宣言する {@code android:mimeType} 属性のみを指定する必要があります。 + +</p> +</dd> + <dt>カテゴリ</dt> + <dd>インテントを処理するアクティビティを特徴づけるための追加的な方法を提供し、通常はユーザーの操作や起動元の場所に関連付けられます。 +システムでサポートされているいくつかの異なるカテゴリがありますが、大抵のカテゴリはほとんど使用されません。 +しかし、すべての暗黙的インテントは、デフォルトでは +{@link android.content.Intent#CATEGORY_DEFAULT} を使用して定義されています。 + <p><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a> +要素を使用して、インテント フィルタでこれを指定します。</p></dd> +</dl> + +<p>インテント フィルタでは、それぞれの基準を<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> 要素内でネストした対応する XML 要素を使用して宣言することによって、アクティビティが受け入れる基準を宣言することができます。 + +</p> + +<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"/> + <data android:mimeType="image/*"/> + </intent-filter> +</activity> +</pre> + +<p>受信するインテントはそれぞれ 1 つのアクションと 1 つのデータ タイプのみを指定しますが、各 +<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> 内で <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</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>アクションとデータのいずれか 2 つのペアが、各自の動作において相互に排他的である場合は、別のインテント フィルタを作成して、どのデータ タイプと組み合わされたときにとのアクションが受け入れられるかを指定する必要があります。 + +</p> + +<p>たとえば、アクティビティが {@link +android.content.Intent#ACTION_SEND} と {@link +android.content.Intent#ACTION_SENDTO} の両方のインテントに関してテキストと画像の両方を処理するとします。この場合は、次の 2 つのアクションのための 2 つの別々のインテント フィルタを定義する必要があります。なぜなら {@link +android.content.Intent#ACTION_SENDTO} インテントは、URI スキームの {@code send} または {@code sendto} を使用して受信者のアドレスを指定するために、 +{@link android.net.Uri} データを使用する必要があるからです。 +次に例を示します。</p> + +<pre> +<activity android:name="ShareActivity"> + <!-- filter for sending text; accepts SENDTO action with sms URI schemes --> + <intent-filter> + <action android:name="android.intent.action.SENDTO"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:scheme="sms" /> + <data android:scheme="smsto" /> + </intent-filter> + <!-- filter for sending text or images; accepts SEND action and text or image data --> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="image/*"/> + <data android:mimeType="text/plain"/> + </intent-filter> +</activity> +</pre> + +<p class="note"><strong>注:</strong> 暗黙的インテントを受信するためには、インテント フィルタで +{@link android.content.Intent#CATEGORY_DEFAULT} カテゴリを含める必要があります。{@link +android.app.Activity#startActivity startActivity()} と {@link +android.app.Activity#startActivityForResult startActivityForResult()} メソッドは、すべてのインテントを {@link android.content.Intent#CATEGORY_DEFAULT} カテゴリを宣言しているものとして処理します。 +インテント フィルタで宣言していない場合、暗黙的インテントはアクティビティに紐付けされません。 +</p> + +<p>ソーシャル共有行動を実行する {@link android.content.Intent#ACTION_SEND}インテントの送受信方法の詳細については、<a href="{@docRoot}training/sharing/receive.html">他のアプリから単純なデータを受信する</a> のレッスンを参照してください。 +</p> + + +<h2 id="HandleIntent">自分のアクティビティでインテントを処理する</h2> + +<p>アクティビティで実行するアクションを決定するために、起動時に使用された {@link +android.content.Intent} を読み取ることができます。</p> + +<p>アクティビティが開始されたら、{@link android.app.Activity#getIntent()} を呼び出して、アクティビティを開始した +{@link android.content.Intent} を取得します。アクティビティのライフサイクル中はいつでもこれを行うことができますが、通常は、 +{@link android.app.Activity#onCreate onCreate()} や {@link android.app.Activity#onStart()} などの早い段階のコールバックの間に行う必要があります。 +</p> + +<p>次に例を示します。</p> + +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.main); + + // Get the intent that started this activity + Intent intent = getIntent(); + Uri data = intent.getData(); + + // Figure out what to do based on the intent type + if (intent.getType().indexOf("image/") != -1) { + // Handle intents with image data ... + } else if (intent.getType().equals("text/plain")) { + // Handle intents with text ... + } +} +</pre> + + +<h2 id="ReturnResult">結果を返す</h2> + +<p>呼び出し元のアクティビティに結果を返したい場合は、{@link +android.app.Activity#setResult(int,Intent) setResult()} を呼び出して結果コードと結果の {@link +android.content.Intent} を指定します。操作が実行され、ユーザーが元のアクティビティに復帰する必要がある場合、 +{@link android.app.Activity#finish()} を呼び出してアクティビティを閉じます(その後破棄します)。次に例を示します。 +</p> + +<pre> +// Create intent to deliver some kind of result data +Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"); +setResult(Activity.RESULT_OK, result); +finish(); +</pre> + +<p>結果に対しては常に結果コードを指定する必要があります。通常は {@link +android.app.Activity#RESULT_OK} または {@link android.app.Activity#RESULT_CANCELED} のいずれかになります。その後、必要に応じて {@link android.content.Intent} を使用して、追加のデータを指定することができます。 +</p> + +<p class="note"><strong>注:</strong> 結果は、デフォルトでは {@link +android.app.Activity#RESULT_CANCELED} に設定されています。したがって、ユーザーがアクションを完了する前に<em>戻る</em>ボタンを押して、結果がまだ設定されていない場合、元のアクティビティは「キャンセルされた」結果を受け取ります。 + +</p> + +<p>いくつかの結果オプションのいずれかを示す整数を返す必要がある場合は、0 よりも大きい任意の値に結果コードを設定することができます。 +結果コードを使用して整数を返す場合に {@link android.content.Intent} を含める必要がなければ、{@link +android.app.Activity#setResult(int) setResult()} を呼び出して結果コードのみを渡すことができます。 +次に例を示します。</p> + +<pre> +setResult(RESULT_COLOR_RED); +finish(); +</pre> + +<p>この場合、可能性のある結果の数はわずかであるため、結果コードは、ローカルに定義されている整数(0 より大きい)になります。 +これは、自分が作成したアプリのアクティビティに結果を返す場合に役立ちます。結果を受け取るアクティビティがパブリック定数を参照でき、結果コードの値を判断できるためです。 + +</p> + +<p class="note"><strong>注:</strong> 自分のアクティビティが {@link +android.app.Activity#startActivity startActivity()} または {@link +android.app.Activity#startActivityForResult startActivityForResult()} を使用して開始されたかどうかをチェックする必要はありません。 +アクティビティを開始したインテントが結果を待っている場合は、{@link +android.app.Activity#setResult(int,Intent) setResult()} を呼び出します。 +元のアクティビティが {@link +android.app.Activity#startActivityForResult startActivityForResult()} を呼び出していた場合、 +{@link android.app.Activity#setResult(int,Intent) setResult()} に提供した結果がそこに送られます。それ以外の場合は、結果は無視されます。 +</p> + + + + + + diff --git a/docs/html-intl/intl/ja/training/basics/intents/index.jd b/docs/html-intl/intl/ja/training/basics/intents/index.jd new file mode 100644 index 0000000..ac14fd5 --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/intents/index.jd @@ -0,0 +1,62 @@ +page.title=他のアプリとの相互操作 +page.tags=インテント、アクティビティ +helpoutsWidget=true + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<h2>必要な知識と前提条件</h2> +<ul> + <li>アクティビティのライフサイクルに関する基本知識(<a href="{@docRoot}training/basics/activity-lifecycle/index.html">アクティビティのライフサイクル管理</a>を参照) +</li> +</ul> + + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li> + <li><a href="{@docRoot}training/secure-file-sharing/index.html">ファイルの共有</a> + <li><a href="http://android-developers.blogspot.com/2009/11/integrating-application-with-intents.html">Integrating Application with Intents(ブログ投稿)</a> +</li> + <li><a href="{@docRoot}guide/components/intents-filters.html">インテントとインテントフィルタ</a> +</li> +</ul> + +</div> +</div> + +<p>Android アプリには通常、いくつかの<a href="{@docRoot}guide/components/activities.html">アクティビティ</a>があります。各アクティビティでは、ユーザーが特定のタスク(マップの表示や写真の撮影など)を実行できるユーザー インターフェースが表示されます。あるアクティビティから別のアクティビティにユーザーを移動させるためには、アプリで {@link +android.content.Intent} を使用して、ある動作に至るアプリの「インテント(意図)」を定義する必要があります。 + +{@link +android.app.Activity#startActivity startActivity()} のようなメソッドでシステムに +{@link android.content.Intent} を渡すと、システムは {@link +android.content.Intent} を使用して適切なアプリ コンポーネントを特定して起動します。インテントを使用すると、自分のアプリから別のアプリにあるアクティビティを開始させることもできます。 +</p> + +<p>{@link android.content.Intent} は、特定のコンポーネント(特定の {@link android.app.Activity} インスタンス)を開始するために<em>明示的</em>にしたり、または(「写真を撮影する」などの)意図したアクションを処理できる任意のコンポーネントを開始するために<em>暗黙的</em>にしたりすることができます。 + +</p> + +<p>このクラスでは {@link android.content.Intent} を使用して、別のアプリを起動する、そのアプリから結果を受け取る、などの他のアプリとの間でいくつかの基本的な相互操作を実行し、他のアプリのインテントに自分のアプリが応答できるようにする方法を示します。 + +</p> + +<h2>レッスン</h2> + +<dl> + <dt><b><a href="sending.html">別のアプリにユーザーを送る</a></b></dt> + <dd>あるアクションを実行する他のアプリを起動するために、暗黙的なインテントを作成する方法を示します。 +</dd> + <dt><b><a href="result.html">アクティビティから結果を取得する</a></b></dt> + <dd>別のアクティビティを開始し、そのアクティビティの結果を受け取る方法を示します。</dd> + <dt><b><a href="filters.html">他のアプリからのアクティビティの開始を許可する</a></b></dt> + <dd>自分のアプリが受け入れる暗黙的なインテントを宣言するインテント フィルタを定義することによって、他のアプリからの使用に供するために、自分のアプリ内のアクティビティをオープンにする方法を示します。 +</dd> +</dl> + diff --git a/docs/html-intl/intl/ja/training/basics/intents/result.jd b/docs/html-intl/intl/ja/training/basics/intents/result.jd new file mode 100644 index 0000000..62c06ae --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/intents/result.jd @@ -0,0 +1,178 @@ +page.title=アクティビティから結果を取得する +page.tags=インテント +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#StartActivity">アクティビティを開始する</a></li> + <li><a href="#ReceiveResult">結果を受け取る</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li> + <li><a href="{@docRoot}training/secure-file-sharing/index.html">ファイルの共有</a> +</ul> + + </div> +</div> + +<p>別のアクティビティを開始する場合、必ずしも一方向である必要はありません。別のアクティビティを開始して、結果を受け取ることもできます。 +結果を受け取るには、({@link android.app.Activity#startActivity +startActivity()} ではなく) {@link android.app.Activity#startActivityForResult +startActivityForResult()} を呼び出します。</p> + +<p>たとえば、自分のアプリでカメラアプリを起動し、結果として撮影した写真を受け取ることができます。または、ユーザーが連絡先を選択するケースにおいて、連絡帳アプリを起動し、結果として連絡先の詳細を受け取ることができます。 + +</p> + +<p>もちろん、応答するアクティビティは結果を返すように設計されていなければなりません。その場合は、別の {@link android.content.Intent} オブジェクトとして結果を送信します。 +自分のアクティビティ側では、 +{@link android.app.Activity#onActivityResult onActivityResult()} コールバック内で結果を受け取ります。</p> + +<p class="note"><strong>注: </strong> +{@link android.app.Activity#startActivityForResult startActivityForResult()} を呼び出す際は、明示的または暗黙的インテントを使用することができます。自分のアクティビティのいずれかを開始して結果を受け取ろうとする場合は、想定通りの結果を受け取れるようにするため、明示的なインテントを使用する必要があります。 + +</p> + + +<h2 id="StartActivity">アクティビティを開始する</h2> + +<p>結果を受け取るためにアクティビティを開始する際、使用する {@link android.content.Intent} オブジェクトに関して特に記すべき内容はありませんが、{@link +android.app.Activity#startActivityForResult startActivityForResult()} メソッドに対して追加で整数の引数を渡す必要があります。 +</p> + +<p>整数の引数は、リクエストを識別する「要求コード」です。結果の +{@link android.content.Intent} を受け取ると、アプリが正常に結果を識別し、その処理方法を決定することができるように、コールバックが同じ要求コードを提供します。 +</p> + +<p>たとえば、ユーザーが連絡先を選択できるようにするアクティビティの開始方法について、次に例を示します。</p> + +<pre> +static final int PICK_CONTACT_REQUEST = 1; // The request code +... +private void pickContact() { + Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts")); + pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers + startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); +} +</pre> + + +<h2 id="ReceiveResult">結果を受け取る</h2> + +<p>ユーザーが、その後のアクティビティを終えて復帰すると、システムは自分のアクティビティの +{@link android.app.Activity#onActivityResult onActivityResult()} メソッドを呼び出します。このメソッドには、次の 3 つの引数が含まれます。 +</p> + +<ul> + <li>{@link +android.app.Activity#startActivityForResult startActivityForResult()} に渡した要求コード。</li> + <li>第 2 のアクティビティによって指定された結果コード。これは、操作が成功した場合の {@link +android.app.Activity#RESULT_OK} か、ユーザーがバックアウトしたり、何らかの理由で失敗したりした場合の {@link +android.app.Activity#RESULT_CANCELED} か、いずれか一方です。 +</li> + <li>結果のデータを運ぶ {@link android.content.Intent}。</li> +</ul> + +<p>たとえば、「連絡先を選ぶ」インテント用に結果を処理する方法について、次に例を示します。</p> + +<pre> +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // Check which request we're responding to + if (requestCode == PICK_CONTACT_REQUEST) { + // Make sure the request was successful + if (resultCode == RESULT_OK) { + // The user picked a contact. + // The Intent's data Uri identifies which contact was selected. + + // Do something with the contact here (bigger example below) + } + } +} +</pre> + +<p>この例では、Android の連絡先または連絡帳アプリから返される結果の {@link android.content.Intent} は、ユーザーが選択した連絡先を識別するコンテンツ {@link android.net.Uri} を提供します。 + +</p> + +<p>正常に結果を処理するためには、結果の +{@link android.content.Intent} の形式がどうなるかを理解する必要があります。これは、結果を返すアクティビティが自分のアクティビティの 1 つである場合には簡単です。 +Android プラットフォームに付属のアプリでは、特定の結果データに対して役立つ、独自の API を提供しています。 +たとえば、連絡帳アプリ(一部の古いバージョンでは連絡先アプリ)は常に選択した連絡先を識別するコンテンツ URI を含む結果を返し、カメラアプリは別に {@code "data"} で {@link android.graphics.Bitmap} を返します(<a href="{@docRoot}training/camera/index.html">写真を撮影する</a>のクラスを参照)。 + + +</p> + + +<h4>ボーナス: 連絡先データを読み取る</h4> + +<p>連絡帳アプリから結果を取得する方法を示した上記のコードでは、実際に結果からデータを読み取る方法の詳細には触れていませんが、これは、<a href="{@docRoot}guide/topics/providers/content-providers.html">コンテンツプロバイダ</a>に関する高度な説明が必要であるためです。 + + +ここでは興味がある方向けに、結果データをクエリして、選択された連絡先から電話番号を取得する方法について、次にコード例を示します。 +</p> + +<pre> +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // Check which request it is that we're responding to + if (requestCode == PICK_CONTACT_REQUEST) { + // Make sure the request was successful + if (resultCode == RESULT_OK) { + // Get the URI that points to the selected contact + Uri contactUri = data.getData(); + // We only need the NUMBER column, because there will be only one row in the result + String[] projection = {Phone.NUMBER}; + + // Perform the query on the contact to get the NUMBER column + // We don't need a selection or sort order (there's only one result for the given URI) + // CAUTION: The query() method should be called from a separate thread to avoid blocking + // your app's UI thread. (For simplicity of the sample, this code doesn't do that.) + // Consider using {@link android.content.CursorLoader} to perform the query. + Cursor cursor = getContentResolver() + .query(contactUri, projection, null, null, null); + cursor.moveToFirst(); + + // Retrieve the phone number from the NUMBER column + int column = cursor.getColumnIndex(Phone.NUMBER); + String number = cursor.getString(column); + + // Do something with the phone number... + } + } +} +</pre> + +<p class="note"><strong>注: </strong>Android 2.3(API レベル 9)以前では、 +{@link android.provider.ContactsContract.Contacts Contacts Provider} でクエリ(上記のような)を実行する場合、自分のアプリで {@link +android.Manifest.permission#READ_CONTACTS} パーミッション(<a href="{@docRoot}guide/topics/security/security.html">セキュリティとパーミッション</a>を参照)を宣言することが必要です。 +ただし、Android 2.3 からは連絡先または連絡帳アプリにより、結果を返すときに連絡先プロバイダから読み取るための一時的パーミッションが付与されます。 + +一時的パーミッションは要求された特定の連絡先にのみ適用されるため、{@link +android.Manifest.permission#READ_CONTACTS} パーミッションを宣言した場合を除き、インテントの {@link android.net.Uri} で指定したもの以外の連絡先はクエリできません。 + +</p> + + + + + + + + + + + + + + + diff --git a/docs/html-intl/intl/ja/training/basics/intents/sending.jd b/docs/html-intl/intl/ja/training/basics/intents/sending.jd new file mode 100644 index 0000000..586bc15 --- /dev/null +++ b/docs/html-intl/intl/ja/training/basics/intents/sending.jd @@ -0,0 +1,256 @@ +page.title=別のアプリにユーザーを送る +page.tags=インテント +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> + <div id="tb"> + +<h2>このレッスンでの学習内容</h2> +<ol> + <li><a href="#Build">暗黙的インテントをビルドする</a></li> + <li><a href="#Verify">インテントを受け取るアプリがあるか確認する</a></li> + <li><a href="#StartActivity">インテントを使ってアクティビティを開始する</a></li> + <li><a href="#AppChooser">アプリ チューザを表示する</a></li> +</ol> + +<h2>関連ドキュメント</h2> +<ul> + <li><a href="{@docRoot}training/sharing/index.html">単純なデータの共有</a></li> +</ul> + + </div> +</div> + +<p>Android の最も重要な特長の一つに、ユーザーが実行を希望する「アクション」に基づいて、別のアプリにユーザーを送信するアプリの機能があります。 +たとえば、自分のアプリで地図上に表示したいお店やサービスの住所がある場合、アプリでマップを表示するアクティビティをビルドする必要はありません。 + +代わりに {@link android.content.Intent} 使用して、住所を表示するための要求を作成することができます。 +Android システムは、マップ上に住所を表示できるアプリを起動します。 +</p> + +<p>第 1 回のクラス<a href="{@docRoot}training/basics/firstapp/index.html">初めてのアプリ作成</a>で説明したように、自分のアプリでのアクティビティ間を移動するためにインテントを使用する必要があります。通常それには、起動するコンポーネントの正確なクラス名を定義する、<em>明示的なインテント</em>を使用します。 + + +ただし、「マップを表示する」などのアクションを別のアプリに実行させたい場合、<em>暗黙的なインテント</em>を使用する必要があります。 +</p> + +<p>このレッスンでは、特定のアクションの暗黙的インテントを作成する方法や、他のアプリでアクションを実行するアクティビティを開始させる目的で、暗黙的インテントを使用する方法を示します。 +</p> + + + +<h2 id="Build">暗黙的インテントをビルドする</h2> + +<p>暗黙的インテントは、開始するコンポーネントのクラス名を宣言せず、代わりに実行するアクションを宣言します。 +アクションでは、<em>表示</em>、<em>編集</em>、<em>送信</em>や、<em>取得</em>などの、希望する操作を指定します。 +インテントは、多くの場合、表示対象の住所、送信対象の電子メール メッセージなど、アクションに関連するデータを含みます。作成するインテントにもよりますが、データは {@link android.net.Uri}、またはその他のいくつかのデータ タイプのいずれかとなるか、データ自体全く必要とならない場合もあります。 + + +</p> + +<p>データが {@link android.net.Uri} である場合は、単純な {@link +android.content.Intent#Intent(String,Uri) Intent()} コンストラクタを使用してアクションとデータを定義することができます。 +</p> + +<p>ここでは、電話番号を指定するための {@link +android.net.Uri} のデータを使用して、電話をかけるインテントを作成する方法について次の例を示します。</p> + +<pre> +Uri number = Uri.parse("tel:5551234"); +Intent callIntent = new Intent(Intent.ACTION_DIAL, number); +</pre> + +<p>{@link android.app.Activity#startActivity +startActivity()} を呼び出すことにより、自分のアプリでインテントが起動されると、電話アプリは指定された電話番号への通話を開始します。</p> + +<p>ここでは他の 2 つのインテント、およびそのアクションと{@link android.net.Uri} データのペアの例を示します。 +</p> + +<ul> + <li>マップを表示する: +<pre> +// Map point based on address +Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); +// Or map point based on latitude/longitude +// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level +Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); +</pre> + </li> + <li>ウェブ ページを表示する: +<pre> +Uri webpage = Uri.parse("http://www.android.com"); +Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage); +</pre> + </li> +</ul> + +<p>暗黙的インテントのその他の種類には、文字列などのさまざまなデータ タイプを提供する「特別」データを必要とします。 +さまざまな {@link +android.content.Intent#putExtra(String,String) putExtra()} メソッドを使用して、特別データを 1 つ以上追加することができます。</p> + +<p>デフォルトでは、インテントに含まれる +{@link android.net.Uri} データに基づいて、インテントに必要な適切な MIME タイプをシステムが決定します。インテントに {@link android.net.Uri} が含まれていない場合は、通常は {@link android.content.Intent#setType setType()} を使用して、インテントに関連するデータのタイプを指定する必要があります。 + +MIME タイプの詳細な指定により、どの種類のアクティビティがインテントを受け取るかが指定されます。 +</p> + +<p>ここでは、目的のアクションを指定するための特別データを追加しているインテントの例を示します。</p> + +<ul> + <li>添付ファイル付きのメールを送信する: +<pre> +Intent emailIntent = new Intent(Intent.ACTION_SEND); +// The intent does not have a URI, so declare the "text/plain" MIME type +emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); +emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients +emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject"); +emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text"); +emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment")); +// You can also attach multiple items by passing an ArrayList of Uris +</pre> + </li> + <li>カレンダーイベントを作成する: +<pre> +Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI); +Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30); +Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30); +calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()); +calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()); +calendarIntent.putExtra(Events.TITLE, "Ninja class"); +calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo"); +</pre> +<p class="note"><strong>注:</strong> カレンダー イベント用のこのインテントは、API レベル 14 以降でのみサポートされています。 +</p> + </li> +</ul> + +<p class="note"><strong>注:</strong> できるだけ具体的に {@link +android.content.Intent} を定義することが重要です。たとえば、 +{@link android.content.Intent#ACTION_VIEW} のインテントを使用して画像を表示する場合、 +{@code image/*} の MIME タイプを指定する必要があります。これにより、他のタイプのデータを「表示」できる(マップ アプリのような)アプリがインテントによってトリガーされることを回避します。 +</p> + + + +<h2 id="Verify">インテントを受け取るアプリがあるか確認する</h2> + +<p>Android プラットフォームは、特定のインテント(電話、メール、カレンダーアプリなど)が内蔵のアプリのいずれかへ解決することを保証しますが、インテントを呼び出す前に常に検証ステップを含める必要があります。 + +</p> + +<p class="caution"><strong>警告: </strong>インテントを呼び出した際、端末上で利用可能なインテントを処理できるアプリがない場合、アプリがクラッシュします。 +</p> + +<p>インテントに応答できる利用可能なアクティビティがあるかどうかを確認するには {@link +android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} を呼び出して、 +{@link android.content.Intent} を処理できるアクティビティのリストを取得します。返された {@link +java.util.List} が空ではない場合、安全にインテントを使用することができます。次に例を示します。</p> + +<pre> +PackageManager packageManager = {@link android.content.Context#getPackageManager()}; +List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, + PackageManager.MATCH_DEFAULT_ONLY); +boolean isIntentSafe = activities.size() > 0; +</pre> + +<p><code>isIntentSafe</code> が <code>true</code> であれば、少なくとも 1 つのアプリがインテントに応答します。 +<code>false</code> であれば、インテントを処理するアプリが存在しません。</p> + +<p class="note"><strong>注:</strong> ユーザーがインテントを使用する前にインテントを使用する機能を無効化する必要がある場合、アクティビティが最初に起動するときにこのチェックを実行する必要があります。 + +インテントを処理できるアプリが具体的に分かっている場合、当該アプリをダウンロードするユーザーのためにリンクを提供することができます(<a href="{@docRoot}distribute/tools/promote/linking.html">Google +Play 上の自分の製品にリンクする方法</a>を参照)。 +</p> + + +<h2 id="StartActivity">インテントを使ってアクティビティを開始する</h2> + +<div class="figure" style="width:200px;margin-top:-10px"> + <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" /> + <p class="img-caption"><strong>図 1.</strong> 複数のアプリがインテントを処理することができるときに表示される選択ダイアログの例です。 +</p> +</div> + +<p>{@link android.content.Intent} を作成し、付加情報を設定したら、{@link +android.app.Activity#startActivity startActivity()} を呼び出してシステムに送信します。システムがインテントを処理することができる複数のアクティビティを特定した場合、図 1 に示すように使用するアプリを選択できるダイアログをユーザーに表示します。 + +インテントを処理できるアクティビティが 1 つのみの場合、システムはすぐにそのアクティビティを起動します。 +</p> + +<pre> +startActivity(intent); +</pre> + +<p>次に、マップを表示するためのインテントを作成し、そのインテントを処理するアプリが存在するかを確認してから起動する、一連の方法について例を示します。 +</p> + +<pre> +// Build the intent +Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); +Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); + +// Verify it resolves +PackageManager packageManager = {@link android.content.Context#getPackageManager()}; +List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0); +boolean isIntentSafe = activities.size() > 0; + +// Start an activity if it's safe +if (isIntentSafe) { + startActivity(mapIntent); +} +</pre> + + + +<h2 id="AppChooser">アプリ チューザを表示する</h2> + +<div class="figure" style="width:200px;margin-top:-10px"> + <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" /> + <p class="img-caption"><strong>図 2.</strong> チューザのダイアログ</p> +</div> + +<p>自分の {@link android.content.Intent} を {@link +android.app.Activity#startActivity startActivity()} に渡してアクティビティを開始した際に、インテントに応答できる複数のアプリがある場合、ユーザーがデフォルトで使用するアプリを選択できること(ダイアログの下部にあるチェックボックスを選択してこれを行います。図 1 参照)に注意してください。 + +これは、(1 つのウェブ ブラウザのみを使用する傾向にあるユーザーが)ウェブ ページを開いたり、(1 つのカメラを選ぶ傾向にあるユーザーが)写真を撮影したりするときのように、ユーザーがアクション実行時に毎回同じアプリの使用を希望するような場合には有用です。 + +</p> + +<p>一方、実行対象のアクションが複数のアプリによって処理できる場合、ユーザーは毎回異なるアプリを選ぶかもしれません。たとえば「共有」アクションなど、いくつかのアプリを介してアイテムを共有する可能性があります。この場合、図 2 に示すように、チューザのダイアログを明示的に表示する必要があります。 + + +チューザのダイアログは、アクションのたびに使用するアプリを選択するよう、ユーザーを強制します(ユーザーはアクションのデフォルトのアプリを選択することはできません)。 + +</p> + +<p>チューザを表示するには、{@link +android.content.Intent#createChooser createChooser()} を使用して {@link android.content.Intent} を作成し、{@link +android.app.Activity#startActivity startActivity()} に渡します。次に例を示します。</p> + +<pre> +Intent intent = new Intent(Intent.ACTION_SEND); +... + +// Always use string resources for UI text. +// This says something like "Share this photo with" +String title = getResources().getString(R.string.chooser_title); +// Create intent to show chooser +Intent chooser = Intent.createChooser(intent, title); + +// Verify the intent will resolve to at least one activity +if (intent.resolveActivity(getPackageManager()) != null) { + startActivity(chooser); +} +</pre> + +<p>これにより、{@link +android.content.Intent#createChooser createChooser()} メソッドに渡されたインテントに応答するアプリのリストを示すダイアログが表示され、指定されたテキストがダイアログのタイトルになります。 +</p> + + + |