【问题标题】:FileProvider Xamarin not displaying fileFileProvider Xamarin 不显示文件
【发布时间】:2017-03-20 14:57:37
【问题描述】:

我正在尝试使用文件提供程序显示 PDF 文件。但是,当 PDF 阅读器打开时,它不包含文件的内容。该文件存储在文件文件夹内的应用程序的内部存储器中。

清单:

    <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.mycom.myapp.fileprovider" android:exported="false" android:grantUriPermissions="true">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
    </provider>

文件路径:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="export" />
</paths>

pdfViewRenderer.cs:

string libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);   
var path = Path.Combine(libraryPath, fileName);


string application = "application/pdf";
Java.IO.File javaFile = new Java.IO.File(fileName);//externalPath  


Android.Net.Uri androidURI = FileProvider.GetUriForFile(Forms.Context.ApplicationContext, "com.mycom.myapp.fileprovider", javaFile);


Intent intent = new Intent(Intent.ActionView);
intent.SetDataAndType(androidURI, Filetype); 
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
intent.SetFlags(ActivityFlags.NoHistory);
intent.SetFlags(ActivityFlags.ClearWhenTaskReset);


Forms.Context.StartActivity(Intent.CreateChooser(intent, "Open PDF"));

【问题讨论】:

    标签: c# android xamarin xamarin.android android-fileprovider


    【解决方案1】:

    您不能直接访问应用程序的.apk 中的文件,`.apk' 不会以文件系统的形式出现。

    您可以将AndroidAsset 复制到您的应用程序缓存目录,然后将FileProvider 权限授予基于文件的Uri,以允许外部应用程序访问您应用程序沙箱中的该文件。

    AndroidManifestapplication 元素中添加provider

    <provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.sushihangover.artificialgravitycalc"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/cache_path" />
    

    然后将文件名与提供者的android:resource: 匹配的xml 文件添加到您的Resources/xml,其中包含您授予访问权限的路径:

    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <cache-path name="appcache" path="." />
    </paths>
    

    注意:您可能需要将xml 目录添加到您的Resources 文件夹中,因为默认情况下它不是通过基本的Xamarin.Android 项目模板添加的。 (并且必须命名为xml,小写)

    将您的.pdf 添加到Assets 目录并确保将其标记为AndroidAsset 构建类型:

    现在您可以将 Asset 复制到应用的缓存目录,创建一个基于 FileProviderUri,授予对它的读取权限,然后尝试打开它。在这种情况下,您需要至少一个已安装的应用程序发布它处理application/pdf mime-type:

    var pdfAssetName = "PlayScriptLanguageSpecification.pdf";
    var savePath = Path.GetTempFileName();
    using (var assetStream = Application.Context.Assets.Open(pdfAssetName))
    using (var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
    {
        byte[] buffer = new byte[1024];
        int readCount = 0;
        do
        {
            readCount = assetStream.Read(buffer, 0, buffer.Length);
            fileStream.Write(buffer, 0, readCount);
        } while (readCount > 0);
    }
    var targetIntent = new Intent(Intent.ActionView);
    var file = new Java.IO.File(savePath);
    var uri = FileProvider.GetUriForFile(this, PackageName, file);
    targetIntent.SetDataAndType(uri, "application/pdf");
    targetIntent.SetFlags(ActivityFlags.NoHistory);
    targetIntent.SetFlags(ActivityFlags.GrantReadUriPermission);
    Intent intent = Intent.CreateChooser(targetIntent, "Open File");
    StartActivity(intent);
    

    【讨论】:

    • 这看起来不错,但是结果会生成一个 .tmp 文件会在 PDF 查看器中打开吗?
    • @Simon 适用于我使用的所有 PDF 查看器,但您可以使用 GetTempPath 并添加您选择的文件名......即var savePath = Path.Combine(Path.GetTempPath(), pdfAssetName);
    • 我昨天刚刚使用它......你的解决方案很好,但仍然给了我同样的问题。进一步看,我发现权限存在问题。接收应用程序正在获得权限拒绝。通过授予 URI 权限,这解决了它,我可以使用我的原始代码。如果它有效,我使用内部存储是错误的吗?
    • 另外,我认为 ActivityFlags.GrantReadUriPermission 标志应该阻止了这个权利?
    猜你喜欢
    • 2017-08-27
    • 2018-01-21
    • 2020-07-28
    • 1970-01-01
    • 2018-09-14
    • 2021-10-16
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多