1

我正在尝试创建一个 PDF 文档,然后在 Android 应用程序中打开它。该代码基于 GitHub 项目https://github.com/AlessandroMartini/Delphi-Android-GeraPDF 我在 RAD Studio 11 中使用 Delphi。

我已经成功地解决了允许我的应用程序保存它创建的文件的权限,现在我卡在尝试查看我使用 Intent 创建的文件以允许在另一个应用程序中打开文件以查看它。

在我的主要形式中,我有以下内容:

  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);

  { based on solution from https://stackoverflow.com/questions/54535225/android-os-fileuriexposedexception-filename-exposed-beyond-app-through-intent }
  var lfile := TJFile.JavaClass.init(FileNameJ);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NO_HISTORY or
        TJIntent.JavaClass.FLAG_ACTIVITY_CLEAR_TOP);
  var LAuthority := TAndroidHelper.Context.getApplicationContext.getPackageName.concat(
        StringToJString('.fileprovider'));
  var Data := TJContent_FileProvider.JavaClass.getUriForFile(TAndroidHelper.Context,
        LAuthority,
        lFile);

  Intent.setDataAndType(Data, StringToJString('application/pdf'));

  TAndroidHelper.Activity.StartActivity(Intent);

到目前为止,这似乎很好。

我的 AndroidManifest.template.xml 文件是这样的,该<provider></provider>部分已添加到默认代码中:

<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="%package%"
    android:versionCode="%versionCode%"
    android:versionName="%versionName%"
    android:installLocation="%installLocation%">
    <uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />
<%uses-permission%>
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
    <queries>
<%queries-child-elements%>
    </queries>
    <application
        android:persistent="%persistent%"
        android:restoreAnyVersion="%restoreAnyVersion%"
        android:label="%label%"
        android:debuggable="%debuggable%"
        android:largeHeap="%largeHeap%"
        android:icon="%icon%"
        android:theme="%theme%"
        android:hardwareAccelerated="%hardwareAccelerated%"
        android:resizeableActivity="false"
        android:requestLegacyExternalStorage="true">
<%provider%>
        <provider android:name="android.support.v4.content.FileProvider"
            android:authorities="%package%.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/fileprovider" />
        </provider>
<%application-meta-data%>
<%uses-libraries%>
<%services%>
        <!-- Our activity is a subclass of the built-in NativeActivity framework class.
             This will take care of integrating with our NDK code. -->
        <activity
            android:name="com.embarcadero.firemonkey.FMXNativeActivity"
            android:label="%activityLabel%"
            android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
            android:launchMode="singleTask">
            <!-- Tell NativeActivity the name of our .so -->
            <meta-data android:name="android.app.lib_name" android:value="%libNameValue%" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
<%activity%>
<%receivers%>
    </application>
</manifest>
<!-- END_INCLUDE(manifest) -->

我的 fileprovider.xml 文件包含以下内容:

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

我知道路径值不是我应该使用的,我可以稍后修复。

问题出现在我构建它并尝试运行它之后。

AndroidManifest.template.xml 位于我的项目源的根文件夹中。

我尝试将 fileprovider.xml 放在项目根目录、./res、./xml 和 ./res/xml 文件夹中,但我收到一个 PAClient 错误,表明找不到 fileprovider.xml。

[PAClient 错误] 错误:E2312 无法执行“C:\Users\Public\Documents\Embarcadero\Studio\22.0\CatalogRepository\AndroidSDK-2525-22.0.42600.6491\build-tools\30.0.3\Aapt.exe”包-f -M "C:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\AndroidManifest.xml" -F "C:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\bin\TestPermissions-unaligned.apk" -I "C:\Users\Public\Documents\Embarcadero\Studio\22.0\CatalogRepository\AndroidSDK-2525-22.0.42600.6491\platforms\android-30\android.jar" -S "C:\Projects\Rad\JavaTest1\ Android\Debug\TestPermissions\res" -A "C:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\assets" "C:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\library" "C:\项目\Rad\JavaTest1\Android\Debug\TestPermissions\classes"'(错误 1)

[PAClient 错误] 错误:E2312 C:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\AndroidManifest.xml:38:错误:错误:未找到与给定名称匹配的资源(在“资源”处,值为“@xml” /文件提供者')。

为什么找不到 fileprovider.xml 的任何想法?

4

1 回答 1

0

在https://en.delphipraxis.net/topic/1361-android-how-to-call-a-tjintent/找到 Dave Nottage 的解决方案

在 Delphi 10.3 和更新版本中,provider 部分不需要手动添加到 AndroidManifest.template.xml。

更改项目选项,(右键单击项目,然后选择选项)。

在应用程序-> 授权列表中,选中安全文件共享。

如果提供程序部分是手动添加到 AndroidManifest.template.xml 的,则将其删除。

fileprovider.xml 文件非常高兴位于项目源根目录中。

最后,确保 fileprovider.xml 中指示的路径是您要共享的文件所在的位置。在我的情况下,我保存到“/storage/emulated/0/Download”,所以这是放入 fileprovider.xml 的值。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="external_files" path="/storage/emulated/0/Download"/>
</paths>

不过还是有问题。尽管该文件被放置在 /storage/emulated/0/Download 文件夹中,并且我的测试手机上的各种可能的 PDF 阅读器都可以找到该文件,但它们无法打开它。我可以导航到下载文件夹并使用相同的查看器打开文件,所以看起来我的应用程序中仍然存在一些权限问题。

于 2022-01-25T13:09:33.197 回答