我在项目中创建了一个包含一些数据的sqlite文件,但我不知道如何将它链接到我的应用程序。我希望数据可以在Android模拟器上加载。
我发现了一个2015年发布的教程,它不再起作用,比如新的FileAccessHelper类后无法找到GetLocalFilePath函数。教程项目似乎使用了旧版本的SQLite.net-PCL包,因为在教程项目中使用了SQLite.Net.Platform.XamarinAndroid,而这个包不再存在。有什么想法吗?
http://arteksoftware.com/deploying-a-database-file-with-a-xamarin-forms-app/
这是教程中的代码:
[Activity (Label = "People", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
string dbPath = FileAccessHelper.GetLocalFilePath ("people.db3");
LoadApplication (new People.App (dbPath, new SQLitePlatformAndroid ()));
}
}
FileAccessHelper.cs
public class FileAccessHelper
{
public static string GetLocalFilePath (string filename)
{
string path = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
string dbPath = Path.Combine (path, filename);
CopyDatabaseIfNotExists (dbPath);
return dbPath;
}
private static void CopyDatabaseIfNotExists (string dbPath)
{
if (!File.Exists (dbPath)) {
using (var br = new BinaryReader (Application.Context.Assets.Open ("people.db3"))) {
using (var bw = new BinaryWriter (new FileStream (dbPath, FileMode.Create))) {
byte[] buffer = new byte[2048];
int length = 0;
while ((length = br.Read (buffer, 0, buffer.Length)) > 0) {
bw.Write (buffer, 0, length);
}
}
}
}
}
}
答案 0 :(得分:3)
如果您想从Xamarin.Forms调用该方法,则需要为每个平台实现一个接口,但我不会详细介绍这个示例中的所有方法。以下是有关DependencyService主题的Xamarin文档。
对于Android,您需要将DB文件放在Assets文件夹中。这是您的Android项目中需要的代码,用于复制数据库并返回其路径的接口:
[assembly: Xamarin.Forms.Dependency(typeof(FileAccessHelper))]
namespace MyNamespace.Droid
{
class FileAccessHelper : MyXamarinFormsPage.IFileAccessHelper
{
public async Task<String> GetDBPathAndCreateIfNotExists()
{
String databaseName = "MyLite.db";
var docFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var dbFile = Path.Combine(docFolder, databaseName); // FILE NAME TO USE WHEN COPIED
if (!File.Exists(dbFile))
{
FileStream writeStream = new FileStream(dbFile, FileMode.OpenOrCreate, FileAccess.Write);
await Forms.Context.Assets.Open(databaseName).CopyToAsync(writeStream);
}
return dbFile;
}
}
}
对于UWP,您需要将DB文件放在根文件夹中。 UWP项目中复制文件并返回路径的界面应如下所示:
[assembly: Xamarin.Forms.Dependency(typeof(FileAccessHelper))]
namespace MyNamespace.UWP
{
public class FileAccessHelper : MyXamarinFormsPage.IFileAccessHelper
{
public async Task<String> GetDBPathAndCreateIfNotExists()
{
String filename = "MyLite.db";
bool isExisting = false;
try
{
StorageFile storage = await ApplicationData.Current.LocalFolder.GetFileAsync(filename);
isExisting = true;
}
catch (Exception)
{
isExisting = false;
}
if (!isExisting)
{
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync(filename);
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder, filename, NameCollisionOption.ReplaceExisting);
}
return Path.Combine(ApplicationData.Current.LocalFolder.Path, filename);
}
}
}
对于iOS,您需要将DB文件放在Resources文件夹中。然后,这是您的iOS项目中的代码:
[assembly: Xamarin.Forms.Dependency(typeof(FileAccessHelper))]
namespace MyNamespace.iOS
{
public class FileAccessHelper : MyXamarinFormsPage.IFileAccessHelper
{
public async Task<String> GetDBPathAndCreateIfNotExists()
{
String databaseName = "MyLite.db";
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, databaseName);
if (!File.Exists(path))
{
var existingDb = NSBundle.MainBundle.PathForResource("MyLite", "db");
File.Copy(existingDb, path);
}
return path;
}
}
}
然后可以通过执行此操作从您的Xamrin.Forms项目中调用它:
public class MyXamarinFormsPage
{
public MyXamarinFormsPage()
{
String DBPath = await DependencyService.Get<IFileAccessHelper>().GetDBPathAndCreateIfNotExists()
//Store string for path
}
public interface IFileAccessHelper
{
Task<String> GetDBPathAndCreateIfNotExists();
}
}
答案 1 :(得分:1)
尝试使用以下内容在Android项目中分配dbpath
变量(并忘记FileAccessHelper
类):
[Activity (Label = "People", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
// Retrieves the "AppHome"/files folder which is the root of your app sandbox on Android
var appDir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
// Locates your dbPath.
string dbPath = Path.Combine(appDir , "people.db3");
LoadApplication (new People.App (dbPath, new SQLitePlatformAndroid()));
}
}
希望这有帮助!