delphi android打开外部文件,报错android.os.FileUriExposedException解决方法

Android 7.0强制启用了被称作 StrictMode的策略,带来的影响就是你的App对外无法暴露file://类型的URI了。

如果你使用Intent 携带这样的URI 去打开外部App(比如:打开系统相机拍照),那么会抛出FileUriExposedException异常。

Delphi 为Android项目提供了Secure File Sharing选择项,默认是False。这一项是设置什么呢?

原来,Android 7及以后的版本,为了加强OS的安全性,不允许一个app访问其他app的文件,为了解决这个问题,将Secure File Sharing设置为True

完整代码如下:

Delphi 复制代码
unit Unit1;

interface

uses
   System.SysUtils, System.Types, System.UITypes, System.Classes,
   System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics,
   FMX.Dialogs, FMX.Controls.Presentation,
   {$IFDEF ANDROID}
   Androidapi.JNI.Support, Androidapi.JNI.GraphicsContentViewText,
   Androidapi.JNI.Net, Androidapi.JNI.Os, Androidapi.JNI.JavaTypes,
   Androidapi.Helpers,
   {$ENDIF}
   FMX.StdCtrls;

type
   TForm1 = class(TForm)
      Button1: TButton;
      procedure Button1Click(Sender: TObject);
   private
      { Private declarations }
   public
      { Public declarations }
   end;

var
   Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
   aUrl: string;
   {$IFDEF ANDROID}
   Intent: JIntent;
   Data: Jnet_Uri;
   {$ENDIF}
begin
   var path: string := '/sdcard/test.jpg';
   if FileExists(path) then
   begin
      {$IFDEF ANDROID}
      Intent := TJIntent.Create;
      Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
      if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.N then
      begin
         var lFile: JFile := TJFile.JavaClass.init(StringToJString(path));
         Intent.setFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
         Data := TJcontent_FileProvider.JavaClass.getUriForFile(TAndroidHelper.Context, StringToJString('com.junwei.JWMeeting.fileprovider'), lFile);  //将这个com.junwei.JWMeeting 换成您的程序包
      end
      else
         Data := TJnet_Uri.JavaClass.parse(StringToJString('file://' + path));

      Intent.setDataAndType(Data, StringToJString('image/*'));
      try
         TAndroidHelper.Activity.startActivity(Intent);
      except
         on E: Exception do
         begin
            ShowMessage(E.Message)
         end;
      end;
      {$ENDIF ANDROID}
   end
   else
   begin
      ShowMessage('不存在文件:' + path)
   end;

end;

end.

后记:如果你的项目是用旧版delphi建的,如10.2,那么,需要在10.3.1下重建这个项目,才能确保Secure File Sharing选择项生效,生成正确的配置文件,不然,不会生成配置文件,有朋友遇到过。

相关推荐
xiangpanf4 小时前
Laravel 10.x重磅升级:五大核心特性解析
android
robotx7 小时前
安卓线程相关
android
消失的旧时光-19437 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon8 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon8 小时前
VSYNC 信号完整流程2
android
dalancon8 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户69371750013849 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android10 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才10 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶11 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle