androidアプリのストレージ戦略

53
Android アプリのストレージ戦略 AndroidってSDカード使えるんでしょ?~

Upload: masahiro-hidaka

Post on 12-Apr-2017

2.944 views

Category:

Technology


0 download

TRANSCRIPT

Androidアプリのストレージ戦略~AndroidってSDカード使えるんでしょ?~

@mhidaka

SD

SDカードは概念

ユーザーの考えるSDカード

持ち運べる入れ替えられる拡張できる

完璧かよ

開発者の考えるSDカード

存在しないときがあるファイルが入れ替わる誰かが書き換える

地獄かよ

ギャップを埋めよう

果たして埋まるのか

Goal

Androidのストレージ制約を理解する

制約と機能要件のバランスを図る

これならできそう

Android One

SDカードの内部ストレージ化

Marshmallowの新機能Android Oneで有効化

ヤバそう

Keywords

• 内部ストレージ• 外部ストレージ• 拡張ストレージ

後で説明します

Keywords

• Permission• Multi User• Storage Access Framework• Scoped Directory Access

難しそう

Androidストレージの進化

Q. SDカードを使うと大容量アプリが可能になるんですか?

しないほうが幸せです。Export / Importなら選択肢の1つとして考えてもいいです

読者からのお手紙

Standard Strategy

<manifestxmlns:android="http://schemas.android.com/apk/res/android"

android:installLocation="internalOnly"... >

内部ストレージへのインストールを推奨(デフォルト値)※API Level 8を懐かしむページです

Standard Strategy

・Service・Alarm Service・IME・Account Manager・Sync Adapters・Device Administrators・listening for "boot completed"

外部ストレージへのインストールでは次の機能は動きませんし、いまは誰もやってません

Q. ではキャッシュデータが適してると聞きましたがSDカードを使っていいですか?

キャッシュには使わない

別なやり方がある

Standard Strategy

内部ストレージに余裕があるアプリキャッシュは自分で管理

ただしキャッシュを削除するアプリが少なく、内部ストレージを圧迫することが多い

Q. どうしても外部ストレージが使いたいです。SDカードへのアクセスはこうやるんですか?

/sdcard/mnt/sdcard/mnt/sdcard/external_sd/storage/sdcard0

牧歌的。

Standard Strategy

Android 4.4以降、外部ストレージの利用方法が変わりました。

Storage Access Framework

ファイル表現の抽象化

DocumentsProvider:外部ストレージやオンラインなどストレージを抽象化する

DropboxとかGoogle Driveとか

Standard Strategy

private void createNewFile() {Intent intent = new Intent(

Intent.ACTION_CREATE_DOCUMENT);intent.setType("text/plain");intent.putExtra(Intent.EXTRA_TITLE,

"Untitled.txt");startActivityForResult(intent,

CREATE_DOCUMENT_REQUEST);}

ファイルを作る

Standard Strategy

private void save(Uri uri, String text) throws FileNotFoundException, IOException {

OutputStream outputStream = null;try {

outputStream = getContentResolver().openOutputStream(uri);

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));

writer.write(text);writer.flush();

} finally {IOUtil.forceClose(outputStream);

}}

書き込む

Q. なぜ外部ストレージへのアクセスが抽象化されたのですか?

マルチユーザ対応のため、今までのようなパーミッション制御では限界が来ました

Android 4.4から仕込み

Permission制御の変化

ファイルへのアクセス制御からピッカーでのユーザ許可へ提供側はDocumentProviderを通じてストレージへのアクセスを許可&書き込みを行う

WRITE_EXTERNAL_STORAGE

Android 4.1で追加

本権限の適用範囲にポータブルな外部ストレージを含まない(4.4~適用)

マルチユーザ時でのセキュリテイ

伝統的なマウントポイントによるアクセス制限ではマルチユーザ対応に限界(アプリデータを守りきれない)

マルチユーザでのストレージ構成

Androidのストレージ戦略

内部ストレージ:アプリ用。基本的に隠蔽

拡張ストレージ:デバイスのプライマリストレージ

外部ストレージ:抜き差し可能なポータブルストレージ

なるほど分からん。

内部ストレージ

アクセス管理を強化。アプリケーション領域ごとアクセス権を設定

他のユーザ、アプリから見れなくなった

コマンド実行も制限

拡張ストレージ

マルチユーザ対応にあたり、ユーザごとに独立した拡張ストレージが必要に。いままではシングルユーザのため、ファイル構造が見えていても問題なかった。現在はPC接続時にUSBデバイス(MTP)として表示。音楽や動画、写真、データを置く。デバイス上のプライマリストレージ

WRITE_EXTERNAL_STORAGE適用範囲

外部ストレージ

デバイス上のセカンダリストレージ基本的にはUSBメモリのようなポータブルストレージが対象。

アクセスは制限。Storage AccessFramework経由のみ許可

機密データは置けない

Q. 拡張ストレージという区分はなぜ必要なのですか?

A.製品と同じライフサイクルの記憶メモリ(バッテリの裏にあるようなSDカード)に対応するためです

Standard Strategy

Context.getExternalFilesDirs()Context.getExternalCacheDirs()Context.getObbDirs()

Android 4.4~では複数の拡張ストレージに対応

Standard Strategy

Android 6.0~ではUSBメディアのサポートも開始

Storage Access Frameworkで制御可能(外部ストレージとして)

direct access is explicitly blocked for privacy and security reasons.

SDカードの内部ストレージ化

外部ストレージを内部ストレージに転用する

SDカード(外部ストレージのまま)

ポータブル可能な外部ストレージとして扱いたい場合はStorage Access Framework経由でのアクセス

書き込みは制限される

SDカードの内部ストレージ化

バッテリパックの内側や、SIMと同じように刺して抜き差しを考慮しないSDカードは内部ストレージとして扱えるようにできる

SDカードの内部ストレージ化

暗号化およびフォーマットされ、製品のライフサイクルに組み込まれるかわりに内部ストレージとして使える(アプリのインストール可能)

フォーマットはext4, f2fs

SDカード好きすぎでは…

What’s New in Android 7.0

FileSystemのパーミッション変更アプリ間のファイル共有変更Scoped Directory Access

Standard Strategy

アプリのプライベートディレクトリにアクセス制限(700)を追加

所有者でも緩和できないMODE_WORLD_READBLEやMODE_WORLD_WRITEBLEを使うとSecurityExeptionが発生

Standard Strategy

自身のアプリ外への file:// URI の公開を禁止する StrictModeが適用

ファイルURIを含むIntentはFileUriExposedExceptionになる

FileProviderで回避

Scoped Directory Access

Scoped Directory Access

StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);

StorageVolume volume = sm.getPrimaryStorageVolume();

Intent intent = volume.createAccessIntent(

Environment.DIRECTORY_PICTURES);startActivityForResult(intent, request_code);

ディレクトリを直接呼び出す

similar to using URIs returned by the Storage Access Framework.

まとめ

Q. つまりどういうことですか?

ざっくりと

内部 拡張 外部フォーマット Ext4, f2fs exFATなどアクセス File IO Storage Access Frameworkアプリから見た公開度

private private public

public

マルチユーザ対応 OK OK NG

Q. バックアップ用途でSDカードは向いているのですか?

一長一短です。小さければShared PreferencesにしてBackupオプションを使うと楽です。サーバがあればインターネットの向こう側も楽ですが基本的にアプリ以外で同じ苦労をしているに過ぎません

選択肢は多い

Q. SDカードのマウント状態はわかりますか?

EnvironmentにAPIがあります結局ファイル制御なのでR/Wのエラーハンドリングをきっちりするといいでしょう

信頼性は低い

Q. USBメモリにもアプリからアクセスしたいです

アプリ独自でやるならUSBホスト機能を使ってお話するかんじです(ファイラーも必要になるので重い)

外部ストレージ

@mhidaka

Thank you!

公式アプリからセッションフィードバックをお待ちしてます