Delphi 找不到 fileprovider.xml 建筑 Android
Delphi cannot find fileprovider.xml building Android
我正在尝试创建 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 }
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.0\CatalogRepository\AndroidSDK-2525-22.0.42600.6491\build-tools.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.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:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\classes"' (错误 1)
[PAClient 错误] 错误:E2312 C:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\AndroidManifest.xml:38: 错误:错误:找不到与给定名称匹配的资源(在 'resource' 处,值为 ' @xml/fileprovider').
知道为什么找不到 fileprovider.xml 吗?
在 https://en.delphipraxis.net/topic/1361-android-how-to-call-a-tjintent/
找到了来自 Dave Nottage 的解决方案
在 Delphi 10.3 和更新版本中,提供程序部分不需要手动添加到 AndroidManifest.template.xml。
更改项目选项,(right-click 在项目上,然后是 select 选项)。
在应用程序->授权列表中,勾选安全文件共享。
如果提供商部分是手动添加到 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 阅读器 phone 可以找到该文件,但它们无法打开它。我可以导航到下载文件夹并使用相同的查看器打开文件,所以看起来我的应用程序中仍然存在一些权限问题。
我正在尝试创建 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 }
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.0\CatalogRepository\AndroidSDK-2525-22.0.42600.6491\build-tools.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.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:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\classes"' (错误 1)
[PAClient 错误] 错误:E2312 C:\Projects\Rad\JavaTest1\Android\Debug\TestPermissions\AndroidManifest.xml:38: 错误:错误:找不到与给定名称匹配的资源(在 'resource' 处,值为 ' @xml/fileprovider').
知道为什么找不到 fileprovider.xml 吗?
在 https://en.delphipraxis.net/topic/1361-android-how-to-call-a-tjintent/
找到了来自 Dave Nottage 的解决方案在 Delphi 10.3 和更新版本中,提供程序部分不需要手动添加到 AndroidManifest.template.xml。
更改项目选项,(right-click 在项目上,然后是 select 选项)。
在应用程序->授权列表中,勾选安全文件共享。
如果提供商部分是手动添加到 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 阅读器 phone 可以找到该文件,但它们无法打开它。我可以导航到下载文件夹并使用相同的查看器打开文件,所以看起来我的应用程序中仍然存在一些权限问题。