VIsualStudio2017, XamarinでAndroidアプリの勉強中、
FileProvider.GetUriForFileでハマりました。
##起こったエラーと解決方法
-
####Java.Lang.NullPointerException
providerがタグの外に出ていた。
入れ子になっていないと読み込んでくれなかった。 -
####Java.Lang.IllegalStateException
SpecialFolder.Personal(内部領域)を使用しているのに、
filepaths.xmlのタグがfiles-pathではなくexternal-pathになっていた
まず、前提として「file://~」を使った書き方はAPIが更新されていて使えないので、FileProviderを使ったやり方で実装しましょう(2019/4月)
※でも、Webのブログなどにはfileを使ったやり方がたくさんのっていて辛かった。
ちなみに、AndroidのReferenceは僕には合わなかった。
Xamarinのドキュメントが充実しているので(Androidのやきなおしだが・・・)
Xamarinを見るか、海外のフォーラムを見るのが情報が新鮮でよかったように思う。
みんなAPIとxmlの定義で苦戦していたので、どの世界も同じようだ。
//Androidのファイル・ディレクトリ取得
var folderPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var fileName = folderPath + @"/sample.tsv";
/* 途中、省略 */
Android.Net.Uri uri = FileProvider.GetUriForFile(this,
this.ApplicationContext.PackageName+ ".provider",
new File(path));
<?xml version="1.0" encoding="utf-8"?>
<resources>
<files-path name="share" path="." />
</resources>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="io.github.muyoku.MrTimeRecorder" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" />
</provider>
</application>
</manifest>
ちゃんとAndroidの基礎も抑えずにコード書いてせいでハマッたんだと思う。
Xamarinといっても、普段慣れ親しんだ言語出かけるだけなので、
ライフサイクルとかファイル構成とかAndroidの基礎的な思想を学んでからのほうが近道だったように思う。
特にストレージを触るなら、内部領域と外部領域の話を抑えてからのほうがいいと思う。
以下、問題解決で参考にしたサイト
★外部領域と内部領域の話
https://docs.microsoft.com/ja-jp/xamarin/android/platform/files/
★外部、内部領域でXmlのタグ名が違う。外部の場合のみexternalで始まるものを使用する。
http://yuki312.blogspot.com/2014/04/androidfileprovider.html
・AndroidManifest、providerがapplicationタグのそとに書かれていたので参照できずヌルぽが発生
http://mo3789530.hatenablog.com/entry/2018/07/30/093434
・親切な人の解説
https://stackoverflow.com/questions/40462245/fileprovider-xamarin-not-displaying-file
・getExternalFilesDirs(外部領域からのファイルパス取得API)
https://stackoverflow.com/questions/42516126/fileprovider-illegalargumentexception-failed-to-find-configured-root
ありがとうございました。