【问题标题】:Xamarin Android - Write to file - access deniedXamarin Android - 写入文件 - 访问被拒绝
【发布时间】:2018-11-07 21:32:45
【问题描述】:

我在 PCL 项目中使用以下代码获取保存视频 .mp4 文件的路径,该代码返回“/storage/emulated/0/DCIM/ ":

 #if __ANDROID__
   var dir = Android.OS.Environment
   .GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim);
   var publicPath= dir.AbsolutePath;
   var newFilepath = System.IO.Path.Combine(publicPath, fileName); 
   video.path = newFilepath;
 #endif

我已将权限添加到 Android.Manifest,如下所示:

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

这个函数会从互联网上获取.mp4文件并保存到路径:

 public void downloadVideo(VideoInfor video, bool isRetried)
    {
        if (!video.downloadUrl.Contains(HLS) && !video.downloadUrl.Contains(HLS_1))
        {
            string filepath = video.path;

            if (Uri.IsWellFormedUriString(video.downloadUrl, UriKind.RelativeOrAbsolute) && !video.downloadUrl.Contains("https://v.vnecdn.net/vnexpress/video/video_default.mp4"))
            {
                video.downloadUrl = video.downloadUrl.Replace("&amp;", "&");
                Console.WriteLine("Downloading url:  " + video.downloadUrl);
                try
                {
                    if (!video.downloadUrl.Contains(".m3u8"))
                    {
                        Console.WriteLine("Downloading.....");

                        var request = (HttpWebRequest)WebRequest.Create(video.downloadUrl);
                        if (isRetried)
                        {
                            request.Timeout = 120000;
                        }
                        using (WebResponse response = request.GetResponse())
                        {
                            using (Stream source = response.GetResponseStream())
                            {
                                using (FileStream target = File.Open(filepath, FileMode.Create, System.IO.FileAccess.Write))
                                {
                                    var buffer = new byte[1024];
                                    bool cancel = false;
                                    int bytes;
                                    int copiedBytes = 0;

                                    while (!cancel && (bytes = source.Read(buffer, 0, buffer.Length)) > 0)
                                    {
                                        target.Write(buffer, 0, bytes);

                                        copiedBytes += bytes;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception download url = " + video.downloadUrl);
                    Console.WriteLine("Exception download url Exception = " + ex.ToString());
                    if (!isRetried)
                    {
                        downloadVideo(video, true);
                    }

                }
            }
        }
    }

当程序运行到“target.Write(buffer, 0, bytes);”时,我得到异常“访问路径被拒绝”,所以请告诉我这是为什么发生错误?

我已经尝试过Plugin.permissions

 Dictionary<Permission, PermissionStatus> results = 
 await CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage);
 PermissionStatus status = results[Permission.Storage];

但我得到了“status = Permission.Unknow

我已经尝试将视频保存到只有我的应用程序可以访问以下代码的私有路径,它返回“/data/user/0/com.companyname.VideoDownloader/files/”:

 var dir = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
     video.path = System.IO.Path.Combine(dir, filename);

并且downloadVideo函数可以将所有字节数据写入路径而没有错误,但是浏览到该路径时我看不到任何文件。

这是我的 SDK 配置:

<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="25" />

【问题讨论】:

  • 你能提到使用的目标sdk版本吗?
  • @GauravKP:这里是:
  • 您尝试的目录可能不存在,尝试保存在现有目录中,或者在保存文件之前创建目录
  • @GauravKP:我已经调用了 new FileInfo(video.path).Directory.Create();在调用downloadVideo之前
  • 既然你的目标sdk是25,你有requested permissions at runtime吗?你可以参考这个blog,了解如何在 xamarin 中进行操作。

标签: xamarin xamarin.forms xamarin.ios xamarin.android


【解决方案1】:

由于你的目标 sdk 是 25,你必须request permissions at runtime。你可以参考这个blog,了解如何在 xamarin 中进行操作。

【讨论】:

    【解决方案2】:

    我在我的项目中启用了上述所有关于权限的内容,但它仍然不允许我写入文件,只需读取它们即可。

    我的解决方案:你必须在File.WriteAllText(..)中使用Path.Combine,即使你在File.WriteAllText(path)中传递了一个字符串变量,你仍然需要将它写成File.WriteAllText(Path.Combine(path))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-19
      相关资源
      最近更新 更多