我需要一个跨平台的函数来使用设备上的任何应用程序打开一个文件,该应用程序可以打开相关的文件类型,类似于WinAPI函数ShellExecute
。使用我在堆栈溢出上找到的各种代码示例,我终于得到了下面的代码,它用Delphi10.3编译。
uses
{$ifdef Android}
FMX.Helpers.Android, AndroidAPI.Helpers,
AndroidApi.JNI.GraphicsContentViewText,
AndroidApi.JNI.Net, AndroidApi.JNI.JavaTypes;
{$endif Android}
{$ifDef MSWindows}
Winapi.ShellAPI, Winapi.Windows;
{$endif MSWindows}
procedure OpenFile(FilePathname: string; DisplayError: Boolean);
const
COption= 0;
var
Extension: string;
{$ifdef Android}
Intent: JIntent;
URI: Jnet_Uri;
{$endif Android}
Result: integer;
begin
Extension:= LowerCase(ExtractFileExt(FilePathname));
{$ifdef Android}
URI := TJnet_Uri.JavaClass.parse(StringToJString('file:///' + FilePathname));
Intent:= TJIntent.Create;
Intent.setFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
case COption of
0: Intent.setData(URI);
1:
if Extension= '.pdf' then
Intent.setDataAndType(URI,StringToJString('application/pdf'))
else if Extension= '.txt' then
Intent.setDataAndType(URI,StringToJString('text/*'));
end;
try
SharedActivity.startActivity(Intent);
except
on E: Exception do
begin
if DisplayError then
ShowMessage('Error: ' + E.Message);
end;
end;
{$endif Android}
{$ifdef MSWindows}
Result:= ShellExecute(0, 'Open', PChar(FilePathname), '', '', SW_SHOWNORMAL);
{$endif MSWindows}
end;
将此功能应用于Android 9设备上SD卡上的本地.PDF文件,将引发以下异常:
file:////SDCard/test.pdf
android.os.FileUriExposedException:通过Intent.getData()暴露在应用程序之外的android.os.FileUriExposedException
我在StackOverflow上找到了解决这个问题的以下线程:
但是,必须声明和使用继承自Java类文件提供程序的类的想法,才能访问特定的文件或文件夹,并使其他应用程序能够访问它,然后将其记录在AndroidManifest.xml中,这种想法似乎过于复杂,特别是考虑到SD卡中的所有文件从定义上来说都是公开的。
因此,我的问题是:
增编:
从这篇文章的链接中,我找到了Dave的以下代码:
procedure OpenPDFA(const AFileName: string);
var
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);
end;
然而,在Delphi编译器中,类TJFileProvider
被标记为未声明的标识符。我的代码中的uses
列表似乎与Dave的代码相同。那么TJFileProvider在哪里声明的呢?
发布于 2022-04-10 23:53:18
我已经将我的项目从Delphi10.4迁移到Delphi11.1,TJFileProvider也被标记为一个未声明的标识符。
TJcontent_FileProvider.JavaClass.getUriForFile(....)
而不是
TJFileProvider.JavaClass.getUriForFile(.)
我希望这能帮到你
https://stackoverflow.com/questions/59390991
复制相似问题