我目前正在将现有的 Xamarin.Forms 应用程序迁移到 .NET MAUI。现有的应用程序使用 SQLite 数据库来存储一些数据。
数据库路径在 Xamarin.Forms 应用程序中设置如下:
public static string DatabasePath
{
get
{
var basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return Path.Combine(basePath, "mydb.db3");
}
}
在 Xamarin.Forms 中,Android 上的结果路径是:
/data/user/0/my.app/files/.local/share/mydb.db3
但是,当在 MAUI 中使用与上面完全相同的代码时,Android 上的结果路径是:
/data/user/0/my.app/files/mydb.db3
这就产生了无法在MAUI中访问现有数据的问题,除非我在迁移的代码中修改如下代码:
public static string DatabasePath
{
get
{
var basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
#if ANDROID
var localShare = ".local/share";
if (!basePath.Contains(localShare))
{
basePath = Path.Combine(basePath, localShare);
}
#endif
return Path.Combine(basePath, "mydb.db3");
}
}
现在,这可以解决我的问题,但我认为这不是正确的方法。有谁知道如何正确迁移使用
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
获得的路径,以便访问与之前相同的精确路径?
这很重要,因为我需要能够从迁移的 MAUI 应用程序中访问和重用使用 Xamarin.Forms 版本创建的现有本地数据库。
注意:我知道Xamarin.Forms和MAUI有文件系统帮助程序,但这对解决此问题没有帮助,因为创建 Xamarin.Forms 应用程序时未使用它们.
我重现了你的问题。确切地说,将Xamarin升级到Maui后,
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
方法的路径缺少.local/share
部分。建议将此问题发布到github。
另外,我发现在
File Storage and Access with Xamarin.Android中提到了
LocalApplicationData
的路径,但是没有找到Maui相关的文档。
所以,在Maui,可以使用下面的方法来重构代码文件路径:
Path.Combine(Environment.GetFolderPath(Environment.SpecialFoler.Personal),".local/share/mydb.db3");
虽然这和你的解决方案没有太大区别,但是这是官方使用的重构代码路径方法。
您可能需要考虑在较低级别上工作,以更好地了解 Android 文件系统。
以下内容将始终返回包含数据的应用程序文件夹。
// the main data folder only available to your app
Java.IO.File folder = ContextCompat.GetExternalFilesDirs(Application.Context, null)[0];
在调试器中,您将看到字符串为“/storage/emulated/0/Android/data/packagename/files”,其中您的包名称采用常用格式“com.companyname.appname”
首次运行应用程序时,您可能会创建一个子文件夹,用于保存特定数据。
那么您可以通过
获取数据string appDataFolder = System.IO.Path.Combine(folder.Path, GetString(Resource.String.your_app_data_folder));
我可能想调试用户数据文件的内容。用户向我发送文件,然后我可以从我的设备上项目的 Assets 文件夹中访问数据,这样我就可以在必要时使用用户的数据调试我的设备上的问题。
string filename = System.IO.Path.Combine(appDataFolder, diagnosticFileName);
using Stream asset = Assets!.Open(diagnosticFileName);
if (!File.Exists(filename))
{
using FileStream fileStream = File.Create(filename);
asset.CopyTo(fileStream);
}