简体   繁体   English

选择在 Xamarin Forms 中存储文件的路径

[英]Select path for storing file in Xamarin Forms

I have a Xamarin form application and I want to save file and the file should be shown when user open file manager in his phone or when the phone is connected to computer.我有一个 Xamarin 表单应用程序,我想保存文件,当用户在手机中打开文件管理器或手机连接到计算机时,应显示该文件。 I read this article , but the problem is that the file is stored to Environment.SpecialFolder.Personal and the user can't open this path.我读了这篇文章,但问题是该文件存储到Environment.SpecialFolder.Personal并且用户无法打开此路径。 Also I found this plugin which does exactly the same thing.我还发现了这个插件,它的作用完全相同。 It store file to the path Environment.SpecialFolder.Personal .它将文件存储到路径Environment.SpecialFolder.Personal And when I try to save file in another location, I always get error message says:当我尝试将文件保存在另一个位置时,我总是收到错误消息:

Access to the path '..' is denied访问路径“..”被拒绝

Which path should I use to save file?我应该使用哪个路径来保存文件?

The System.Environment.SpecialFolder.Personal type maps to the path /data/data/[your.package.name]/files . System.Environment.SpecialFolder.Personal类型映射到路径/data/data/[your.package.name]/files This is a private directory to your application so you won't be able to see these files using a file browser unless it has root privileges.这是您的应用程序的私有目录,因此您将无法使用文件浏览器查看这些文件,除非它具有 root 权限。

So if you want the file to be found by users, you can not save the file in the Personal folder, but in another folder (such as Downloads ):所以如果你想让文件被用户找到,你不能将文件保存在Personal文件夹中,而是保存在另一个文件夹中(例如Downloads ):

string directory = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
string file = Path.Combine(directory, "yourfile.txt");

You must also add permissions to AndroidManifest.xml :您还必须向AndroidManifest.xml添加权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Here is code to save an image for Android, iOS, and UWP:以下是为 Android、iOS 和 UWP 保存图像的代码:

Android:安卓:

public void SaveImage(string filepath)
{
    var imageData = System.IO.File.ReadAllBytes(filepath);
    var dir = Android.OS.Environment.GetExternalStoragePublicDirectory(
    Android.OS.Environment.DirectoryDcim);
    var pictures = dir.AbsolutePath;
    var filename = System.DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg";
    var newFilepath = System.IO.Path.Combine(pictures, filename);

    System.IO.File.WriteAllBytes(newFilepath, imageData);
    //mediascan adds the saved image into the gallery
    var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
    mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(newFilepath)));
    Xamarin.Forms.Forms.Context.SendBroadcast(mediaScanIntent);
}

iOS: IOS:

public async void SaveImage(string filepath)
{
    // First, check to see if we have initially asked the user for permission 
    // to access their photo album.
    if (Photos.PHPhotoLibrary.AuthorizationStatus == 
        Photos.PHAuthorizationStatus.NotDetermined)
    {
        var status = 
            await Plugin.Permissions.CrossPermissions.Current.RequestPermissionsAsync(
                Plugin.Permissions.Abstractions.Permission.Photos);
    }
    
    if (Photos.PHPhotoLibrary.AuthorizationStatus == 
        Photos.PHAuthorizationStatus.Authorized)
    {
        // We have permission to access their photo album, 
        // so we can go ahead and save the image.
        var imageData = System.IO.File.ReadAllBytes(filepath);
        var myImage = new UIImage(NSData.FromArray(imageData));

        myImage.SaveToPhotosAlbum((image, error) =>
        {
            if (error != null)
                System.Diagnostics.Debug.WriteLine(error.ToString());
        });
    }
}

Note that for iOS, I am using the Plugin.Permissions nuget packet to request permission from the user.请注意,对于 iOS,我使用 Plugin.Permissions nuget 数据包来请求用户的许可。

UWP: UWP:

public async void SaveImage(string filepath)
{
    var imageData = System.IO.File.ReadAllBytes(filepath);
    var filename = System.DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg";
    
    if (Device.Idiom == TargetIdiom.Desktop)
    {
        var savePicker = new Windows.Storage.Pickers.FileSavePicker();
        savePicker.SuggestedStartLocation = 
            Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
        savePicker.SuggestedFileName = filename;
        savePicker.FileTypeChoices.Add("JPEG Image", new List<string>() { ".jpg" });

        var file = await savePicker.PickSaveFileAsync();

        if (file != null)
        {
            CachedFileManager.DeferUpdates(file);
            await FileIO.WriteBytesAsync(file, imageData);
            var status = await CachedFileManager.CompleteUpdatesAsync(file);

            if (status == Windows.Storage.Provider.FileUpdateStatus.Complete)
                System.Diagnostics.Debug.WriteLine("Saved successfully"));
        }
    }
    else
    {
        StorageFolder storageFolder = KnownFolders.SavedPictures;
        StorageFile sampleFile = await storageFolder.CreateFileAsync(
            filename + ".jpg", CreationCollisionOption.ReplaceExisting);
        await FileIO.WriteBytesAsync(sampleFile, imageData);
    }
}

For Android, the answer of @David Moškoř work perfectly.对于 Android, @David Moškoř的回答非常有效。

For IOS, we can use the following path:对于IOS,我们可以使用以下路径:

Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Library"); 

but LSSupportsOpeningDocumentsInPlace and Supports Document Browser must be enabled in the Info.plist file of IOS project in order to make user browse the saved file (It will appear when you open Files app and navigate to On My iPhone )但是LSSupportsOpeningDocumentsInPlaceSupports Document Browser必须在 IOS 项目的Info.plist文件中启用才能让用户浏览保存的文件(当您打开Files应用程序并导航到On My iPhone时会出现)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM