| 
					
				 | 
			
			
				@@ -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
 
			 |