アンドロイドには大きく2種類の外部記憶があります。1つは、「内蔵ストレージ」(Internal Storage)と呼ばれる領域で、システムのメインボード上にあり、取り外しが不可能な状態になっています。

もう1つは「外部ストレージ」(External Storage。SDカードなどと呼ぶこともあります)と呼ばれる外部記憶領域ですが、物理的なデバイスとしては、SDカード、マイクロSDカードなどの取り外し可能なデバイスと、内蔵ストレージのようにメインボード上で取り外しが不可能な領域の2種類があります(図01)。

図01: アンドロイドのストレージには内部と外部の2種類ある。さらに外部ストレージは、マイクロSDカードなどのメモリカードを使う場合と内部ストレージを使う場合があり、後者の場合、「設定」 ⇒ 「ストレージ」には内蔵ストレージしか表示されない。ただし、アプリからみれば、内蔵ストレージもメモリカードに相当する/sdcardフォルダも必ず存在している

アンドロイドは、アプリケーションやシステムは、内蔵ストレージを使います。これは、常にアクセス出来る必要があるからでです。これに対して、SDカードなどのメモリカードを使う場合、必ずしも装着されているとは限らないし、ある時点で装着されていたとしても、次にアクセスするときには、存在しない、あるいは別のメモリカードに差し替わっている可能性があります。

このため、2つのストレージは、条件に応じて使い分ける必要があります。特に初期の頃、内蔵ストレージ用のフラッシュメモリデバイスは、メモリカードに比べるとビットあたりの単価が高く、数百メガバイト~1ギガバイト程度しか搭載されておらず、それ以上の利用は、メモリカードで拡張するという形式のものが少なくありませんでした。

しかし、メモリカードと内蔵ストレージにはいくつかの違いがあります。アンドロイド自体は、Linuxカーネルを使っている関係で、ファイルシステムは、マウントされている状態でのみアクセスが可能で、マウント中は、メモリカードを簡単に取り外すことはできません。システムを高速化するため、書き込みのタイミングをずらして、アプリケーション側には、すぐに書き込みが終わったように応答することもあるからです。

このため、一般にスマートフォンなどでは、SIMカードなどと同じく、バッテリを外さないと取り出せないような位置に付けられていました。電源がオフになるということは、メモリカードがアンマウントされることだからです。SIMカードも、運用上、ネットワークに接続しているような状態で交換ができないような構造であることが携帯電話側に要求されているため、多くの携帯電話は、バッテリを外さないとSIMカードが交換できないようになっていました。しかし、バッテリ交換が不可能になった現在、こうしたルール自体が無意味になってしまいました。同様に初期のアンドロイドでは、メモリカードを簡単に取り外せないようになっていたのです。

最近では、内蔵ストレージに利用するフラッシュメモリのビット単価も下がってきているため、多くの機種が数ギガバイトから数十ギガバイトの内蔵ストレージを搭載しています。このとき、メモリカードスロットはなく、ソフトウェアで内蔵ストレージの一部を「外部ストレージ」として見えるような工夫がしてあります。

もともとメモリカードのアクセスには、システム側のソフトウェアが介在していました。メモリカードに使われるVFATシステムやEx-FATシステムは、Windows由来のファイルシステムであり、ファイル名や最大ファイルサイズ、アクセス単位(クラスタなど)は、Windowsのものに準拠したものでした。このため、たとえば、ファイル名などでに利用できる文字に違いがあり、アプリケーションが書き込んだファイル名を変換してメモリカードに書き込み、元のファイル名をどこかに保存しておくといった処理が必要になります。また、Windows系のファイルシステムでは、大文字小文字を区別しないため、「ファイルが同名」の概念がLinuxとは違います。こうした問題にも対処しておかないと、メモリカードをWindowsマシンから読めなくなってしまいます。

当初、メモリカードの用途は、音楽や画像やビデオ(カメラアプリなどによるものを含む)などのメディアデータなど大きなファイルの保存先でした。初期のアンドロイドの内蔵ストレージは小さく、システムが動作して、アプリをインストールするのには十分な大きさでも、メディアデータを保存するのには小さかったのです。

外部ストレージアクセスの許可

アプリケーションによる、この外部ストレージのアクセスに関しては、制限が掛けられています。Andorid 1.0では、書き込みに許可が必要でした。こうした許可は、アプリケーションの開発時に開発者が必要な権限を指定しておき、インストール時にユーザーはこれをまとめて許可するかどうかを選択します(許可しない場合はインストールが行われない)。

Android 4.1では、読み出しにも許可が必要になりました。このため、「書き込み」、「読み出し」の許可を持っていないアプリケーションは、外部ストレージには、アクセスができません。

さらにAndroid 4.4では、ファイルやディレクトリに対して設定されている「パーミッション」によるアクセス制御が加わり、外部ストレージに対して読み書きの許可を持っていたとしても、ファイルやフォルダに対するアクセス権限がなければ、アクセスすることはできなくなりました。アプリケーションは、特定のユーザーが実行していることになっていて、そのユーザーがファイルやフォルダにアクセスする権限を持っているかどうかがチェックされるわけです。

ただし、外部ストレージにアプリケーションが自分専用のデータを保存するディレクトリを作り、そこにファイルを置いたり、これを読み出したりすることは可能です。これには許可は必要ありません。ただし、場所は、/sdcard/Android/data以下に限られ、このフォルダの下にアプリケーションごとにサブフォルダが作られ、その中だけがアクセス可能です。

こうした仕組みになっているため、外部ストレージをアプリからアクセスする場合に、それが開発された時期によっては、問題が起きることがあります。Android 4.1登場以前に作られたアプリは、読み出しの許可の存在などを知らないため、インストール時に許可を求めることはありません。このため、もし、外部メモリを読む機能があったとしても、アクセスができなくなります。同様に、4.4以前にリリースされたアプリは、外部メモリ読み出しの許可を持っていても、アクセスできないファイルやフォルダが出てきます。

最近では、スマートフォン内部の情報を勝手に送信するアプリなど、セキュリティ的に問題のあるアプリも出てきています。なので、こうしたセキュリティの強化についてはしかたがない部分があり、できれば開発者の方には、最新の状況に合わせてアップデートをお願いしたいところです。

本稿は、2014年5月2日にAndorid情報のWeb専門誌「AndroWire」に掲載した記事を再構成したものです。