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选择项生效,生成正确的配置文件,不然,不会生成配置文件,有朋友遇到过。

相关推荐
阿巴斯甜15 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker16 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952717 小时前
Andorid Google 登录接入文档
android
黄林晴18 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android