我的项目中有一个SQLite数据库,我想添加一个备份功能来将该数据库保存在SD卡中。 有没有简单的方法可以使用Xamarin.Forms为Android和IOS执行此操作? 我在旧的(其中一些是陈旧的)问题中搜索,但我找不到明确的答案。
答案 0 :(得分:2)
iOS上没有“sdcard”,但您可以将(File.Copy
)数据库复制到应用程序的Documents
目录,以便可以通过iTunes应用程序访问它,这样您就可以复制到PC / MAC:
使用此目录存储用户生成的内容。该目录的内容可以通过文件共享提供给用户;因此,他的目录应该只包含您可能希望向用户公开的文件。 该目录的内容由iTunes和iCloud备份。
因此,假设您正在为数据库使用App Support目录,那么您应该:
public string GetDBPath(string dbFileName)
{
// If you are not using App Support directory for your DBs you are doing it wrong on iOS ;-)
var supportDir = NSSearchPath.GetDirectories(NSSearchPathDirectory.ApplicationSupportDirectory, NSSearchPathDomain.User, true)[0];
var dbDir = Path.Combine(supportDir, "database");
if (!Directory.Exists(dbDir))
Directory.CreateDirectory(dbDir);
return Path.Combine(supportDir, dbDir, dbFileName);
}
复制到App的doc目录非常简单:
public void CopyDBToDocs(string dbFileName)
{
var docDir = NSSearchPath.GetDirectories(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User)[0];
File.Copy(GetDBPath(dbFileName), Path.Combine(docDir, dbFileName));
}
在Android上,它可能非常简单,或者很麻烦,具体取决于设备的API以及您正在开发的应用的Android API目标。
简单如下:
public void CopyDBToSdCard(string dbName)
{
File.Copy(GetDBPath(dbName), Path.Combine(Android.OS.Environment.DirectoryDownloads, dbName);
}
在这种情况下, GetDBPath
实际上是使用“true”数据库目录,该目录是应用程序的沙盒“FileDir”位置的子目录:
public string GetDBPath(string dbFileName)
{
// FYI: GetDatabasePath("") fails on some APIs &| devices &|emulators so hack it... (Some API 23 devices, but not API 21, 27, 28, ...)
var dbPath = context.GetDatabasePath("ZZZ").AbsolutePath.Replace("/ZZZ", "");
if (!Directory.Exists(dbPath))
Directory.CreateDirectory(dbPath);
return context.GetDatabasePath(dbFileName).AbsolutePath;
}
现在要从应用程序实际执行该文件副本到“外部”位置,应用程序的清单权限是必需的:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
此外,如果您的应用具有“定位”且在API-23(Android 6.0)或更高版本上运行,则需要在运行时获得用户对该权限的同意。
使用Android.Support.Compat
是最简单的方法。基本上你需要检查是否已经授予权限,如果没有向用户显示你需要权限的原因,然后让操作系统要求用户接受/拒绝请求。然后,您将收到有关这些烫发结果的通知。
注意:JamesM的Forms'Perm插件用于非粗体编码器;-) PermissionsPlugin
void GetExternalPerms()
{
const string writePermission = Manifest.Permission.WriteExternalStorage;
const string readPermission = Manifest.Permission.ReadExternalStorage;
string[] PermissionsLocation =
{
writePermission, readPermission
};
if ((ContextCompat.CheckSelfPermission(this, writePermission) == Permission.Granted) && (ContextCompat.CheckSelfPermission(this, readPermission) == Permission.Granted))
{
return;
}
if (ActivityCompat.ShouldShowRequestPermissionRationale(this, writePermission))
// Displaying a dialog would make sense at this point...
}
ActivityCompat.RequestPermissions(this, PermissionsLocation, 999);
}
然后,用户接受或拒绝该请求的结果将通过OnRequestPermissionsResult
返回:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
switch (requestCode)
{
case 999: // This is the code that we supply via RequestPermissions
if (grantResults[0] == Permission.Granted)
{
// you have permission, so defer to your DB copy routine now
}
break;
default:
break;
}
}