読者です 読者をやめる 読者になる 読者になる

ぴよぴよエンジニアの日記

クラウドベンダーに勤める見習いSEの日記です。発言は私自身の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

Plugins for XamarinのPCL Storageでファイルが見えない問題

Plugins for XamarinのPCL Storageを使っていて、ファイルロケーションではまったので備忘録に.

PCL Storageの説明は下記リンクをご参照ください.
www.buildinsider.net


開発環境



デバッグ端末



Androidでファイルを見えない問題

using PCLStorage;

IFolder rootFolder = FileSystem.Current.LocalStorage;
IFile file = await rootFolder.CreateFileAsync("data.txt", CreationCollisionOption.ReplaceExisting);
await file.WriteAllTextAsync("保存するテキスト");

上記コードで簡単にファイルを保存できるのですが,問題はこいつのファイルロケーションにあります.


FileSystem.Current.LocalStorageのパスは「/data/user/0/[package name]/files」なのですが(端末によって変わる可能性があります),この領域は自アプリからでないとファイルを参照することができません.


どういうことかというと,AndroidにはASTROファイルマネージャーやESファイルエクスプローラーのようなファイラーアプリがあるわけですが,それらを使ってストレージを参照してもファイルはおろかフォルダすら存在しないのです(/dataは空のフォルダと表示されます).


USB接続で端末のストレージを参照しても同様です.


保存したファイルを自アプリ以外から参照したい場合は,root権限を取得する必要があります(これは実際に試してはいません,root権限の取得は自己責任でお願い致します).


もちろん,自アプリでファイルを参照(read)することはできますので,自アプリ内で完結する場合は何の問題もありません.
端末内に保存したファイルをPCにコピーしたいといった需要がある場合に問題になります.


解決策

参照できないのあれば,参照できる場所に保存してしまえー!です.

// 任意のパスで大丈夫です
private static readonly string FilePath = "/sdcard/[package name]";

IFolder rootFolder = await FileSystem.Current.GetFolderFromPathAsync(FilePath);

これでファイラーアプリで参照可能な領域にファイルを保存できます.

ただし,FileSystem.Current.GetFolderFromPathAsyncはフォルダが存在しない場合はNullを返すので,あらかじめフォルダを作成する必要があります.


まとめ

  • PCLStorageは簡単にファイルを保存できる
  • しかしながら,FileSystem.Current.LocalStorageではファイラーアプリで参照できない
  • FileSystem.Current.GetFolderFromPathAsyncを使えば参照可能(ぬるぽに注意).


ずっとファイルが保存できていなのだと思いかなり悩みました;
Androidでのみ確認していますが,もしかするとiOSやWinPhoneでも同様に困ったことがあるかもしれません.

また,参照可能な領域を変数で定義するのではなく,PCLで取って来れるのが理想ですが,無理ですかね...?
ネイティブで書く場合はたぶんできます.

参考になれば幸いです.

以上