123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- unit Unit1;
- interface
- uses
- System.Messaging,
- {$IF DEFINED(ANDROID) AND (RTLVersion >= 33)}
- Androidapi.JNI.Os,
- System.Permissions,
- {$ENDIF}
- System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
- FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
- FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo;
- type
- TForm1 = class(TForm)
- mmo1: TMemo;
- btn1: TButton;
- btn2: TButton;
- btn3: TButton;
- btn4: TButton;
- chkAllowMultiSelect: TCheckBox;
- procedure btn2Click(Sender: TObject);
- procedure btn1Click(Sender: TObject);
- procedure btn3Click(Sender: TObject);
- procedure btn4Click(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure FormShow(Sender: TObject);
- private
- { Private declarations }
- {$IF DEFINED(ANDROID) AND (RTLVersion >= 33)}
- procedure PermissionsCheck;
- procedure PermissionsResultHandler(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>);
- {$ENDIF}
- procedure DoReceivedImagePath(const Sender: TObject; const M: TMessage);
- procedure DoCancelReceivingImage(const Sender: TObject; const M: TMessage);
- public
- { Public declarations }
- end;
- var
- Form1: TForm1;
- implementation
- {$R *.fmx}
- uses
- {$IFDEF ANDROID}
- Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Provider,
- Androidapi.JNI.JavaTypes, Androidapi.JNI.App, Androidapi.JNI.Net,
- Androidapi.Helpers, ksAndroid.Helpers,
- FMX.Platform.Android,
- {$ENDIF}
- FMX.Platform;
- type
- 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;
- var
- FOpenFileMessageID: Integer = 0;
- FOpenFileCallback: TOpenFileCallback = nil;
- FOpenFileEvent: TOpenFileEvent = nil;
- FOpenFileAction: JString = nil;
- // 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;
- 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
- Exit;
- LCode := TMessageResultNotification(M).ResultCode;
- FileName := '';
- LList := nil;
- {$IFDEF DEBUG}
- if LCode = TJActivity.JavaClass.RESULT_CANCELED then
- Log.d('---HandleActivityMessage-RESULT_CANCELED');
- if LCode = TJActivity.JavaClass.RESULT_FIRST_USER then
- Log.d('---HandleActivityMessage-RESULT_FIRST_USER');
- {$ENDIF}
- if LCode = TJActivity.JavaClass.RESULT_OK then begin
- if TMessageResultNotification(M).Value <> nil then begin
- 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}
- Log.d('---HandleActivityMessage-Value:nil');
- {$ENDIF}
- end;
- end;
- {$IFDEF DEBUG}
- Log.d('---HandleActivityMessage-ResultCode:%d-', [LCode]);
- {$ENDIF}
- if Assigned(FOpenFileCallback) then
- FOpenFileCallback(LCode, FileName, LList);
- if Assigned(FOpenFileEvent) then
- FOpenFileEvent(LCode, FileName, LList);
- if Assigned(LList) then
- FreeAndNil(LList);
- if FOpenFileMessageID <> 0 then begin
- TMessageManager.DefaultManager.Unsubscribe(TMessageResultNotification, FOpenFileMessageID);
- FOpenFileMessageID := 0;
- FOpenFileCallback := nil;
- FOpenFileEvent := nil;
- end;
- end;
- function OpenFileDialog(AOpenFileCallback: TOpenFileCallback; AOpenFileEvent: TOpenFileEvent;
- AExt, ADir: string; AData: Jnet_Uri; AAllowMultiSelect: Boolean): Boolean;
- var
- LIntent: JIntent;
- LType: string;
- begin
- Result := False;
- LType := '';
- if (LType = '') or (AExt = '*.*') or (AExt = '*') then
- LType := ''
- else if Pos('/', AExt) > 0 then
- LType := AExt
- else
- LType := JStringToString(TAndroidHelperEx.GetMimeType(AExt));
- if LType = '' then
- LType := '*/*';
- if FOpenFileAction = nil then //默认值
- FOpenFileAction := TJIntent.JavaClass.ACTION_GET_CONTENT;
- LIntent := TJIntent.JavaClass.init(FOpenFileAction);
- LIntent.setType(StringToJString(LType));
- if AAllowMultiSelect then
- LIntent.putExtra(TJIntent.JavaClass.EXTRA_ALLOW_MULTIPLE, true);
- if not FOpenFileAction.equals(TJIntent.JavaClass.ACTION_PICK) then
- LIntent.addCategory(TJIntent.JavaClass.CATEGORY_OPENABLE);
- if AData <> nil then
- LIntent.setData(AData)
- else if ADir <> '' then
- LIntent.setData(TAndroidHelperEx.UriParse(ADir));
- if FOpenFileMessageID = 0 then begin
- FOpenFileMessageID := TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification, HandleActivityMessage);
- FOpenFileCallback := AOpenFileCallback;
- FOpenFileEvent := AOpenFileEvent;
- end;
- try
- try
- //Result := TAndroidHelperEx.StartActivity(TJIntent.JavaClass.createChooser(Intent, StrToJCharSequence(ATitle)), FILE_SELECT_CODE)
- Result := TAndroidHelperEx.StartActivity(LIntent, FILE_SELECT_CODE);
- except
- raise Exception.Create('File Manager not found');
- end;
- finally
- Form1.mmo1.Lines.Add(Format('OpenFileDialog:%s', [BoolToStr(Result, True)]));
- end;
- end;
- procedure TForm1.btn1Click(Sender: TObject);
- begin
- //Intent.setData(TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI) // 这个可以用来限定APP,比如这个就是 图库
- //Intent.setData(TJContactsContract_Contacts.JavaClass.CONTENT_URI) // 联系人,不指定这个的话会直接取消
- FOpenFileAction := TJIntent.JavaClass.ACTION_PICK;
- OpenFileDialog(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,
- nil, '*/*', '', TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI, chkAllowMultiSelect.IsChecked
- )
- end;
- procedure TForm1.btn2Click(Sender: TObject);
- begin
- FOpenFileAction := TJIntent.JavaClass.ACTION_GET_CONTENT;
- OpenFileDialog(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,
- nil, '*/*', '', nil, chkAllowMultiSelect.IsChecked
- )
- end;
- procedure TForm1.btn3Click(Sender: TObject);
- begin
- FOpenFileAction := TJIntent.JavaClass.ACTION_OPEN_DOCUMENT;
- OpenFileDialog(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,
- nil, '*/*', '', nil, chkAllowMultiSelect.IsChecked
- )
- end;
- procedure TForm1.btn4Click(Sender: TObject);
- var
- FSize: TSize;
- begin
- FSize.cx := TCanvasManager.DefaultCanvas.GetAttribute(TCanvasAttribute.MaxBitmapSize);
- FSize.cy := TCanvasManager.DefaultCanvas.GetAttribute(TCanvasAttribute.MaxBitmapSize);
- MainActivity.getFMXMediaLibrary.takeImageFromLibrary(FSize.Width, FSize.Height, False);
- end;
- procedure TForm1.DoCancelReceivingImage(const Sender: TObject; const M: TMessage);
- begin
- if (M is TMessageCancelReceivingImage) then
- mmo1.Lines.Add('TMessageCancelReceivingImage');
- end;
- procedure TForm1.DoReceivedImagePath(const Sender: TObject; const M: TMessage);
- begin
- if (M is TMessageReceivedImagePath) then
- mmo1.Lines.Add(Format('TMessageReceivedImagePath: %s', [(M as TMessageReceivedImagePath).Value]));
- end;
- procedure TForm1.FormCreate(Sender: TObject);
- begin
- TMessageManager.DefaultManager.SubscribeToMessage(TMessageCancelReceivingImage, DoCancelReceivingImage);
- TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedImagePath, DoReceivedImagePath);
- end;
- procedure TForm1.FormDestroy(Sender: TObject);
- begin
- TMessageManager.DefaultManager.Unsubscribe(TMessageReceivedImagePath, DoReceivedImagePath);
- TMessageManager.DefaultManager.Unsubscribe(TMessageCancelReceivingImage, DoCancelReceivingImage);
- end;
- procedure TForm1.FormShow(Sender: TObject);
- begin
- {$IF DEFINED(ANDROID) AND (RTLVersion >= 33)}
- PermissionsCheck;
- {$ENDIF}
- end;
- {$IF DEFINED(ANDROID) AND (RTLVersion >= 33)}
- procedure TForm1.PermissionsCheck;
- begin
- if TJBuild_VERSION.JavaClass.SDK_INT >= 23 then
- PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.CAMERA),
- JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE),
- JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE)], PermissionsResultHandler);
- end;
- procedure TForm1.PermissionsResultHandler(const APermissions: TArray<string>;
- const AGrantResults: TArray<TPermissionStatus>);
- begin
- if PermissionsService.IsEveryPermissionGranted(
- [JStringToString(TJManifest_permission.JavaClass.CAMERA),
- JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE),
- JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE)]) then
- mmo1.Lines.Add('Permission granted')
- else
- mmo1.Lines.Add('Permission not granted');
- end;
- {$ENDIF}
- end.
|