Xamarin.Forms如何将SQLite数据库备份到SD卡中?

3

我在我的项目中有一个SQLite数据库,并且我想添加一个备份功能来将该数据库保存在SD卡中。是否有一种简单的方法可以在使用Xamarin.Forms的Android和IOS上实现此操作?我搜索了一些旧问题(其中一些非常旧),但是我找不到明确的答案。


对于 Android 来说,你应该可以使用常规文件 IO 将文件从其正常位置复制到 SD 卡上的路径。iOS 不支持 SD 卡。 - Jason
1个回答

2

iOS:

iOS系统中没有“sdcard”,但是您可以将数据库使用File.Copy复制到应用的Documents目录中,以便通过iTunes应用程序访问,并将其复制到您的PC/Mac电脑上:

使用此目录来存储用户生成的内容。该目录的内容可通过文件共享向用户公开;因此,该目录应仅包含您希望向用户公开的文件。 此目录的内容由iTunes和iCloud进行备份。

因此,假设您正在使用App支持目录作为您的数据库,您应该这样做:

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);
}

将文件复制到您应用程序的文档目录就像这样简单:
public void CopyDBToDocs(string dbFileName)
{
    var docDir = NSSearchPath.GetDirectories(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User)[0];
    File.Copy(GetDBPath(dbFileName), Path.Combine(docDir, dbFileName));
}

安卓:

在安卓上,根据设备的API和您正在开发的应用程序的安卓API目标,它可能非常简单或非常繁琐。

可以很简单,如下所示:

public void CopyDBToSdCard(string dbName)
{
    File.Copy(GetDBPath(dbName), Path.Combine(Android.OS.Environment.DirectoryDownloads, dbName);
}

在这种情况下,GetDBPath 实际上使用的是“真实”的数据库目录,即您应用程序的沙盒化“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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接