我需要一个跨平台的函数来打开一个文件,使用在设备上注册的任何应用程序能够打开相关的文件类型,沿着Windows中的WinAPI函数
ShellExecute
的思路。使用我在Stack-overflow上找到的各种代码例子,我最终得到了以下代码,它可以用Delphi 10.3编译。
在安卓9设备上对SD卡上的本地.PDF文件应用此功能,会出现以下异常。
android.os.FileUriExposedException: file:////SDCard/test.pdf exposed 通过Intent.getData()在应用程序之外。
我在StackOverflow上发现了以下解决这个问题的主题。
android.os.FileUriExposedException: file:///storage/emulated/0/test.txt通过Intent.getData()暴露在App之外。
然而,必须声明和使用一个继承自Java类File-provider的类,以便对一个特定的文件或文件夹进行访问,并使其能够被其他应用程序访问,然后将此记录在 AndroidManifest.xml 似乎过于复杂了,特别是考虑到SD卡中的所有文件根据定义都是公开的。
因此,我的问题是。
在Delphi FMX中是否有更简单的方法来处理这个问题? 10.3+?
如果没有,如何在Delphi中创建一个继承自Java类的Object Pascal类?如果能提供一个代码例子就更好了。
从这个帖子的链接中,我找到了Dave Nottage的以下代码。
procedure OpenPDFA(const AFileName: string);
LIntent: JIntent;
LAuthority: JString;
LUri: Jnet_Uri;
begin
LAuthority := StringToJString(JStringToString(TAndroidHelper.Context.getApplicationContext.getPackageName) + '.fileprovider');
LUri := TJFileProvider.JavaClass.getUriForFile(TAndroidHelper.Context, LAuthority, TJFile.JavaClass.init(StringToJString(AFileName)));
LIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW);
LIntent.setDataAndType(LUri, StringToJString('application/pdf'));
LIntent.setFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
TAndroidHelper.Activity.startActivity(LIntent);
然而,类TJFileProvider
在Delphi编译器中被标记为一个未声明的标识符。我代码中的uses
列表似乎与Dave Nottage的代码相同。那么,TJFileProvider是在哪里声明的?