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

相关推荐
找藉口是失败者的习惯13 分钟前
从传统到未来:Android XML布局 与 Jetpack Compose的全面对比
android·xml
Jinkey1 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
大白要努力!3 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟4 小时前
Android音频采集
android·音视频
小白也想学C5 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程5 小时前
初级数据结构——树
android·java·数据结构
闲暇部落7 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
code bean9 小时前
【工控】线扫相机小结 第四篇
数码相机·工控·工业相机
诸神黄昏EX9 小时前
Android 分区相关介绍
android
大白要努力!10 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle