首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Delphi FMX打开本地文件的函数在Android平台上失败

Delphi FMX打开本地文件的函数在Android平台上失败
EN

Stack Overflow用户
提问于 2019-12-18 11:24:19
回答 1查看 2.3K关注 0票数 1

我需要一个跨平台的函数来使用设备上的任何应用程序打开一个文件,该应用程序可以打开相关的文件类型,类似于WinAPI函数ShellExecute。使用我在堆栈溢出上找到的各种代码示例,我终于得到了下面的代码,它用Delphi10.3编译。

代码语言:javascript
运行
复制
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上找到了解决这个问题的以下线程:

android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

但是,必须声明和使用继承自Java类文件提供程序的类的想法,才能访问特定的文件或文件夹,并使其他应用程序能够访问它,然后将其记录在AndroidManifest.xml中,这种想法似乎过于复杂,特别是考虑到SD卡中的所有文件从定义上来说都是公开的。

因此,我的问题是:

  • 是否有一种更简单的方法来处理Delphi 10.3+中的这个问题?如果没有,如何在Delphi中创建对象Pascal类,继承一个Java类?一个代码示例是appreciated.

增编:

从这篇文章的链接中,我找到了Dave的以下代码:

代码语言:javascript
运行
复制
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在哪里声明的呢?

EN

回答 1

Stack Overflow用户

发布于 2022-04-10 23:53:18

我已经将我的项目从Delphi10.4迁移到Delphi11.1,TJFileProvider也被标记为一个未声明的标识符。

TJcontent_FileProvider.JavaClass.getUriForFile(....)

而不是

TJFileProvider.JavaClass.getUriForFile(.)

我希望这能帮到你

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59390991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档