Xamarin.Forms.AndroidでAssetsファイルをコピー
xamarin.forms-Androidでアプリ内に含めたsqliteを使用する場合、Assetsとしてbuildしたsqliteファイルをxamarinでアクセス可能なディレクトリにコピーする必要がある。インストール初期DBを持たせたい場合だ。
xamarin-AndroidでのAssets
Assetsとして設定されたリソースはビルドされるアプリの中に含められる。しかし、xamarinのApp内からこのAssetsにアクセスすることができず、assetsのパスを取得することも出来なかった。(いくら探しても有用な情報が出てこず) ちなみにiOSのNSBundleはアクセスできる。
しかし、AndroidのActivityクラス内ではAssetsにアクセスできる。であるからして、new App()の前にActivity内でassetsを何処かにコピーする必要がある。
assetsファイルをコピー
Activityクラス内で以下の様にして"Environment.SpecialFolder"のどこかにファイルをコピー。
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
CopyFile();
LoadApplication(new App());
}
/// <summary>
/// AssetsからLocalApplicationData内にファイルをコピー
/// </summary>
/// <returns></returns>
private void CopyFile()
{
string fileName = "hoge.db";
string toDir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
string filePath = Path.Combine(toDir, fileName);
if (!File.Exists(filePath))
{
using (BinaryReader br = new BinaryReader(Application.Context.Assets.Open(fileName)))
{
using (BinaryWriter bw = new BinaryWriter(new FileStream(filePath, FileMode.Create)))
{
byte[] buffer = new byte[2048];
int len = 0;
while ((len = br.Read(buffer, 0, buffer.Length)) > 0)
{
bw.Write(buffer, 0, len);
}
}
}
}
}
}
あとはコピー先のパスに対して読み込みをすれば良い。
iOSではNSBundleをコピー
iOSでも同様の処理を行う場合以下のようになる。
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
CopyFile();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
/// <summary>
/// BundleからLibrary内にファイルをコピー
/// </summary>
/// <returns></returns>
private void CopyFile()
{
string fileName = "hoge.db";
string toDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Library");
string filePath = Path.Combine(NSBundle.MainBundle.BundlePath, fileName);
if (!File.Exists(Path.Combine(toDir, fileName)))
{
File.Copy(filePath, toDir, true);
}
}
}
まとめ
上記の様にすれば、アプリ内に初期DBを含ませてリリースし、起動時に端末内にコピーして使用することができる。
しかし、本当はAssetsまたはNSBundleのファイルのコピーもxamarin内で行いたかったが、おそらく不可能なのだろう。
ディスカッション
コメント一覧
まだ、コメントがありません