|
@@ -15,6 +15,7 @@ type
|
|
|
btn2: TButton;
|
|
|
btn3: TButton;
|
|
|
btn4: TButton;
|
|
|
+ chkAllowMultiSelect: TCheckBox;
|
|
|
procedure btn2Click(Sender: TObject);
|
|
|
procedure btn1Click(Sender: TObject);
|
|
|
procedure btn3Click(Sender: TObject);
|
|
@@ -46,8 +47,8 @@ uses
|
|
|
FMX.Platform;
|
|
|
|
|
|
type
|
|
|
- TOpenFileCallback = reference to procedure(const ACode: Integer; const APath: string);
|
|
|
- TOpenFileEvent = procedure (const ACode: Integer; const APath: string) of object;
|
|
|
+ TOpenFileCallback = reference to procedure(const ACode: Integer; const APath: string; const APathes: TStrings);
|
|
|
+ TOpenFileEvent = procedure (const ACode: Integer; const APath: string; const APathes: TStrings) of object;
|
|
|
|
|
|
const
|
|
|
FILE_SELECT_CODE = 0;
|
|
@@ -57,11 +58,15 @@ var
|
|
|
FOpenFileEvent: TOpenFileEvent;
|
|
|
FAction: JString;
|
|
|
|
|
|
+// https://stackoverflow.com/questions/31002388/android-intent-extra-allow-multiple-allows-only-single-picking
|
|
|
procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);
|
|
|
var
|
|
|
+ I: Integer;
|
|
|
LCode: Integer;
|
|
|
FileName:string;
|
|
|
- URI: Jnet_Uri;
|
|
|
+ LURI: Jnet_Uri;
|
|
|
+ LClipData: JClipData;
|
|
|
+ LList: TStringList;
|
|
|
begin
|
|
|
if (not Assigned(M)) or (not (M is TMessageResultNotification))
|
|
|
or (TMessageResultNotification(M).RequestCode <> FILE_SELECT_CODE) then
|
|
@@ -69,6 +74,7 @@ begin
|
|
|
|
|
|
LCode := TMessageResultNotification(M).ResultCode;
|
|
|
FileName := '';
|
|
|
+ LList := nil;
|
|
|
|
|
|
{$IFDEF DEBUG}
|
|
|
if LCode = TJActivity.JavaClass.RESULT_CANCELED then
|
|
@@ -79,14 +85,30 @@ begin
|
|
|
|
|
|
if LCode = TJActivity.JavaClass.RESULT_OK then begin
|
|
|
if TMessageResultNotification(M).Value <> nil then begin
|
|
|
- URI := TMessageResultNotification(M).Value.getData;
|
|
|
-
|
|
|
- if URI <> nil then
|
|
|
- FileName := TAndroidHelperEx.FileFromUri(URI)
|
|
|
- {$IFDEF DEBUG}
|
|
|
- else
|
|
|
- Log.d('---HandleActivityMessage-URI:nil');
|
|
|
- {$ENDIF}
|
|
|
+ with TMessageResultNotification(M).Value do begin
|
|
|
+ LURI := getData;
|
|
|
+ if LURI <> nil then
|
|
|
+ FileName := TAndroidHelperEx.FileFromUri(LURI)
|
|
|
+ else begin
|
|
|
+ LClipData := getClipData;
|
|
|
+ if LClipData <> nil then begin
|
|
|
+ LList := TStringList.Create;
|
|
|
+ for I := 0 to LClipData.getItemCount - 1 do begin
|
|
|
+ LURI := LClipData.getItemAt(I).getUri;
|
|
|
+ if LURI <> nil then
|
|
|
+ LList.Add(TAndroidHelperEx.FileFromUri(LURI))
|
|
|
+ {$IFDEF DEBUG}
|
|
|
+ else
|
|
|
+ Log.d('---HandleActivityMessage-getClipData.getItemAt(%d).getUri:nil', [I]);
|
|
|
+ {$ENDIF}
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ {$IFDEF DEBUG}
|
|
|
+ else
|
|
|
+ Log.d('---HandleActivityMessage-getData & getClipData:nil');
|
|
|
+ {$ENDIF}
|
|
|
+ end;
|
|
|
+ end;
|
|
|
end
|
|
|
else begin
|
|
|
{$IFDEF DEBUG}
|
|
@@ -100,9 +122,12 @@ begin
|
|
|
{$ENDIF}
|
|
|
|
|
|
if Assigned(FOpenFileCallback) then
|
|
|
- FOpenFileCallback(LCode, FileName);
|
|
|
+ FOpenFileCallback(LCode, FileName, LList);
|
|
|
if Assigned(FOpenFileEvent) then
|
|
|
- FOpenFileEvent(LCode, FileName);
|
|
|
+ FOpenFileEvent(LCode, FileName, LList);
|
|
|
+
|
|
|
+ if Assigned(LList) then
|
|
|
+ FreeAndNil(LList);
|
|
|
|
|
|
if FMessageChooserID <> 0 then begin
|
|
|
TMessageManager.DefaultManager.Unsubscribe(TMessageResultNotification, FMessageChooserID);
|
|
@@ -112,7 +137,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-function OpenFileDialog(AExt, ADir: string; AData: Jnet_Uri = nil; AOpenFileCallback: TOpenFileCallback = nil; AOpenFileEvent: TOpenFileEvent = nil): Boolean;
|
|
|
+function OpenFileDialog(AExt, ADir: string; AData: Jnet_Uri = nil; AAllowMultiSelect: Boolean = False; AOpenFileCallback: TOpenFileCallback = nil; AOpenFileEvent: TOpenFileEvent = nil): Boolean;
|
|
|
var
|
|
|
LIntent: JIntent;
|
|
|
LType: string;
|
|
@@ -132,7 +157,9 @@ begin
|
|
|
|
|
|
LIntent := TJIntent.JavaClass.init(FAction);
|
|
|
LIntent.setType(StringToJString(LType));
|
|
|
- //Intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); 多选
|
|
|
+
|
|
|
+ if AAllowMultiSelect then
|
|
|
+ LIntent.putExtra(TJIntent.JavaClass.EXTRA_ALLOW_MULTIPLE, true);
|
|
|
|
|
|
if not FAction.equals(TJIntent.JavaClass.ACTION_PICK) then
|
|
|
LIntent.addCategory(TJIntent.JavaClass.CATEGORY_OPENABLE);
|
|
@@ -165,10 +192,12 @@ begin
|
|
|
//Intent.setData(TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI) // 这个可以用来限定APP,比如这个就是 图库
|
|
|
//Intent.setData(TJContactsContract_Contacts.JavaClass.CONTENT_URI) // 联系人,不指定这个的话会直接取消
|
|
|
FAction := TJIntent.JavaClass.ACTION_PICK;
|
|
|
- OpenFileDialog('*/*', '', TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI,
|
|
|
- procedure(const ACode: Integer; const APath: string) begin
|
|
|
+ OpenFileDialog('*/*', '', TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI, chkAllowMultiSelect.IsChecked,
|
|
|
+ procedure(const ACode: Integer; const APath: string; const APathes: TStrings) begin
|
|
|
if APath <> '' then
|
|
|
mmo1.Lines.Add(APath)
|
|
|
+ else if Assigned(APathes) then
|
|
|
+ mmo1.Lines.AddStrings(APathes)
|
|
|
else
|
|
|
mmo1.Lines.Add(Format('Error code: %d', [ACode]));
|
|
|
end
|
|
@@ -178,10 +207,12 @@ end;
|
|
|
procedure TForm1.btn2Click(Sender: TObject);
|
|
|
begin
|
|
|
FAction := TJIntent.JavaClass.ACTION_GET_CONTENT;
|
|
|
- OpenFileDialog('*/*', '', nil,
|
|
|
- procedure(const ACode: Integer; const APath: string) begin
|
|
|
+ OpenFileDialog('*/*', '', nil, chkAllowMultiSelect.IsChecked,
|
|
|
+ procedure(const ACode: Integer; const APath: string; const APathes: TStrings) begin
|
|
|
if APath <> '' then
|
|
|
mmo1.Lines.Add(APath)
|
|
|
+ else if Assigned(APathes) then
|
|
|
+ mmo1.Lines.AddStrings(APathes)
|
|
|
else
|
|
|
mmo1.Lines.Add(Format('Error code: %d', [ACode]));
|
|
|
end
|
|
@@ -191,10 +222,12 @@ end;
|
|
|
procedure TForm1.btn3Click(Sender: TObject);
|
|
|
begin
|
|
|
FAction := TJIntent.JavaClass.ACTION_OPEN_DOCUMENT;
|
|
|
- OpenFileDialog('*/*', '', nil,
|
|
|
- procedure(const ACode: Integer; const APath: string) begin
|
|
|
+ OpenFileDialog('*/*', '', nil, chkAllowMultiSelect.IsChecked,
|
|
|
+ procedure(const ACode: Integer; const APath: string; const APathes: TStrings) begin
|
|
|
if APath <> '' then
|
|
|
mmo1.Lines.Add(APath)
|
|
|
+ else if Assigned(APathes) then
|
|
|
+ mmo1.Lines.AddStrings(APathes)
|
|
|
else
|
|
|
mmo1.Lines.Add(Format('Error code: %d', [ACode]));
|
|
|
end
|