summaryrefslogtreecommitdiff
path: root/docs/html-intl/intl/ja/preview/features/scoped-folder-access.jd
blob: 6bfae2d69dadeb026161126dd0fc07dd4c5b0ed2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
page.title=特定のディレクトリへのアクセス
page.keywords=preview,sdk,scoped directory access
page.tags=androidn

@jd:body

<div id="qv-wrapper">
<div id="qv">
  <h2>このドキュメントの内容</h2>
  <ol>
    <li><a href="#accessing">外部ストレージのディレクトリへのアクセス</a></li>
    <li><a href="#removable">リムーバブル メディアのディレクトリへのアクセス</a></li>
    <li><a href="#best">ベスト プラクティス</a></li>
  </ol>
</div>
</div>

<p>写真アプリなどは通常、外部ストレージの特定のディレクトリ(<code>Pictures</code> ディレクトリなど)のみにアクセスする必要があります。
外部ストレージへのアクセスに関する従来のアプローチでは、このようなアプリに目的のディレクトリへのアクセスを容易に提供できる設計にはなっていませんでした。

次に例を示します。</p>

<ul>
<li>マニフェストで {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} または {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} を要求すると、外部ストレージ上のすべての公開ディレクトリにアクセスできますが、この場合、アプリが不要な場所にもアクセスできます。


</li>
<li><a href="{@docRoot}guide/topics/providers/document-provider.html">ストレージ アクセス フレームワーク</a>を使用すると、通常、ユーザーはシステム UI を使用してディレクトリを選択できますが、アプリが常に同じ外部ディレクトリにアクセスする場合、この選択は不要です。Android N では、一般的な外部ストレージ ディレクトリにアクセスできる、新しいシンプルな API を提供します。



</li>
</ul>

<p>
 </p>

<h2 id="accessing">外部ストレージのディレクトリへのアクセス</h2>

<p><code>StorageManager</code> クラスを使用して、適切な 
<code>StorageVolume</code> インスタンスを取得します。次に、そのインスタンスの 
<code>StorageVolume.createAccessIntent()</code> メソッドを呼び出して、インテントを作成します。このインテントを使用して、外部ストレージのディレクトリにアクセスします。
リムーバブル メディア ボリュームなど、使用できるすべてのボリュームのリストを取得するには、
<code>StorageManager.getVolumesList()</code> を使用します。
</p>

<p>次のコード スニペットは、プライマリ共有ストレージの 
<code>Pictures</code> ディレクトリを開く方法の例を示しています。</p>

<pre>
StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
StorageVolume volume = sm.getPrimaryVolume();
Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code);
</pre>

<p>システムは外部ディレクトリへのアクセスの付与を試行し、必要に応じてシンプルな UI で、ユーザーにアクセスを確認します。
</p>

<img src="{@docRoot}preview/images/scoped-folder-access-framed.png" srcset="{@docRoot}preview/images/scoped-folder-access-framed.png 1x,
{@docRoot}preview/images/scoped-folder-access-framed_2x.png 2x" />
<p class="img-caption"><strong>図 1.</strong> Pictures ディレクトリへのアクセスを要求するアプリケーション
</p>

<p>ユーザーがアクセスを付与すると、
<code>Activity.RESULT_OK</code> の結果コードと、URI を含むインテント データを指定して、
<code>onActivityResult()</code> のオーバーライドを呼び出します。提供された URI を使用して、ディレクトリの情報にアクセスします。これは、<a href="{@docRoot}guide/topics/providers/document-provider.html">ストレージ アクセス フレームワーク</a>で返された URI を使用する場合と同様です。



</p>

<p>ユーザーがアクセスを付与しなかった場合は、
<code>Activity.RESULT_CANCELED</code> の結果コードと、null のインテント データを指定して、
<code>onActivityResult()</code> のオーバーライドを呼び出します。</p>

<p class="note"><b>注:</b> 特定の外部ディレクトリへのアクセスを取得すると、そのディレクトリ内のサブディレクトリへのアクセスも取得します。
</p>

<h2 id="removable">リムーバブル メディアのディレクトリへのアクセス</h2>

<p>特定のディレクトリへのアクセスを使用してリムーバブル メディア上のディレクトリにアクセスするには、まず {@link android.os.Environment#MEDIA_MOUNTED} 通知をリッスンする {@link android.content.BroadcastReceiver} を追加します。次に例を示します。

</p>

<pre>
&lt;receiver
    android:name=".MediaMountedReceiver"
    android:enabled="true"
    android:exported="true" &gt;
    &lt;intent-filter&gt;
        &lt;action android:name="android.intent.action.MEDIA_MOUNTED" /&gt;
        &lt;data android:scheme="file" /&gt;
    &lt;/intent-filter&gt;
&lt;/receiver&gt;
</pre>

<p>ユーザーが SD カードなどのリムーバブル メディアをマウントすると、システムは 
{@link android.os.Environment#MEDIA_MOUNTED} 通知を送信します。この通知は、インテント データ内の <code>StorageVolume</code> オブジェクトを提供します。このオブジェクトを使用して、リムーバブル メディア上のディレクトリにアクセスできます。

次の例では、リムーバブル メディア上の <code>Pictures</code> ディレクトリにアクセスします。
</p>

<pre>
// BroadcastReceiver has already cached the MEDIA_MOUNTED
// notification Intent in mediaMountedIntent
StorageVolume volume = (StorageVolume)
    mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code);
</pre>

<h2 id="best">ベスト プラクティス</h2>

<p>外部ディレクトリのアクセス URI はできる限り保持してください。そうすれば、ユーザーに何度もアクセス要求をする必要がなくなります。
ユーザーがアクセスを付与したら、ディレクトリのアクセス URI を指定して 
<code>getContentResolver().takePersistableUriPermssion()</code> を呼び出します。
システムが URI を保持し、以降のアクセス要求では <code>RESULT_OK</code> を返して、ユーザーに確認の UI を表示しません。

</p>

<p>ユーザーが外部ディレクトリへのアクセスを拒否した直後に、またアクセスを要求しないようにしてください。
何度もアクセスを要求すると、ユーザー エクスペリエンスが低下します。
</p>