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