【问题标题】:how to show PDF from mobile storage in xamarin android c# app?如何在 xamarin android c# 应用程序中显示来自移动存储的 PDF?
【发布时间】:2020-02-14 12:16:19
【问题描述】:

我正在使用 c# 编写一个 xmarin android 应用程序。我想打开一个位于内部存储“TESTFOLDER”的自定义文件夹中的 pdf 文件。代码在下面给出,每次它去捕获部分,它将开始活动。如何打开它?

代码

var externalPath = global::Android.OS.Environment.ExternalStorageDirectory.Path + "/TESTFOLDER";
                Java.IO.File file = new Java.IO.File(externalPath, "qdummy.pdf");
                if(file.Exists())
                {
                    try
                    {
                        file.SetReadable(true);
                        Android.Net.Uri uri = Android.Net.Uri.FromFile(file);
                        Intent intent = new Intent(Intent.ActionView);
                        intent.SetDataAndType(uri, "application/pdf");
                        intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask);                        
                        intent.SetFlags(ActivityFlags.NoHistory);
                        StartActivity(intent);                        
                    }
                    catch (Exception ex)
                    {
                        Toast.MakeText(Application.Context, "problem", ToastLength.Long).Show();
                    }
                }
                else
                {
                    Toast.MakeText(Application.Context, "No exx", ToastLength.Long).Show();
                }

【问题讨论】:

标签: c# android pdf xamarin start-activity


【解决方案1】:

根据您的描述和错误信息,您需要使用 FileProvider 包装您的 URI。因为 android uri 会给你 file:// 而 FileProvider 会首先给你 content://。

 Android.Net.Uri pdfPath = FileProvider.GetUriForFile(context, context.ApplicationContext.PackageName + ".provider", file);

那么您需要将 FileProvider 添加到您的清单中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.pdfsample" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
    <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
    </provider>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>

您还需要使用 file_paths.xml 创建 Resources\xml 文件夹

<?xml version="1.0" encoding="utf-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
 <external-files-path name="root" path="."/>
 <external-files-path name="files" path="files" />
 <external-path name="external_files" path="."/>
</paths>

打开pdf代码:

 var externalPath = global::Android.OS.Environment.ExternalStorageDirectory.Path + "/testfolder";
        Java.IO.File file = new Java.IO.File(externalPath, "test.pdf");
        if(file.Exists())
        {
            var context = Android.App.Application.Context;
            try
            {

                Android.Net.Uri pdfPath = FileProvider.GetUriForFile(context, context.ApplicationContext.PackageName + ".provider", file);
                context.GrantUriPermission(context.PackageName, pdfPath, ActivityFlags.GrantReadUriPermission);
                Intent intent = new Intent();
                intent.SetFlags(ActivityFlags.GrantReadUriPermission);
                intent.SetAction(Android.Content.Intent.ActionView);
                intent.SetFlags(ActivityFlags.NoHistory);
                intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask);
                intent.SetDataAndType(pdfPath, "application/pdf");
                context.StartActivity(intent);

            }
            catch (Exception ex)
            {
                Toast.MakeText(Application.Context, "problem", ToastLength.Long).Show();
            }

        }

这是你可以看看的同一个线程:

How do I open an internally created pdf in Xamarin.Android via a FileProvider in the default system pdf app?

【讨论】:

  • 感谢您回复@Cherry Bu - MSFT,我只是将您的代码复制并粘贴到我的 MainActivity.cs 中,它现在要求用户使用安装在移动设备中的首选应用程序打开 pdf,我有 3 个选项在我的手机中打开 pdf,i) wps office ii) Drive PDF viewer iii)Adobe Acrobat Reader。打开 wps office 后 - 它说“wps office 正在确定文档的类型”并且 PDF 没有显示。在 Drive PDF 查看器中 - 打开后它什么也不显示。在 acrobat 阅读器中 - 它说“文件 colud 无法访问。请检查您的位置”,但 pdf 存在于正确的位置。
  • 这里我使用 minSdkVersion="19" 和 targetSdkVersion="27" ,测试 pdf 通常通过 i) wps office ii) Drive PDF viewer iii)Adobe Acrobat Reader 应用程序从外部存储文件夹打开.还有其他我想念的吗。请帮助@Cherry Bu - MSFT
  • @Soumen 请稍等,我会在我这边测试一下,选择pdf查看器。
  • 亲爱的@Cherry Bu - MSFT 问题已解决。我已经在答案部分提供了答案。
【解决方案2】:

问题已解决,

** 请按照本博客中的所有步骤进行操作,只需替换 try catch 块即可解决问题。

try
                    {
                        string extension = MimeTypeMap.GetFileExtensionFromUrl(Android.Net.Uri.FromFile(file).ToString());
                        string mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
                        Intent intent = new Intent(Intent.ActionView);
                        intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.NewTask);
                        Android.Net.Uri path = FileProvider.GetUriForFile(Application.Context, Android.App.Application.Context.PackageName + ".provider", file);
                        intent.SetDataAndType(path, mimeType);
                        intent.AddFlags(ActivityFlags.GrantReadUriPermission);
                        Application.Context.StartActivity(Intent.CreateChooser(intent, "Choose App"));
                    }
                    catch (Exception ex)
                    {
                        Toast.MakeText(Application.Context, "problem", ToastLength.Long).Show();
                    }

【讨论】:

  • 很高兴听到您的问题已解决,请记得将您的回复标记为答案,谢谢。
猜你喜欢
  • 2019-10-15
  • 1970-01-01
  • 2021-09-05
  • 2015-01-27
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
相关资源
最近更新 更多