在需要权限的时候: begin TPermissionsService.DefaultService.RequestPermissions( ['android.permission.WRITE_EXTERNAL_STORAGE'],//例:拉取写储存权限 procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray) begin if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then begin //拉取权限成功 end; end, procedure(const APermissions: TClassicStringDynArray; const APostRationaleProc: TProc) begin TDialogService.ShowMessage('需要权限', procedure(const AResult: TModalResult) begin //拉取权限失败 end) end); end;
in fact, you dont needs create this layout to "require" or "show permissions message" as in RAD HELP show:
you can use many others ways, depend of necessity! For example, you dont needs any iteration with permission (be verify or show message) then, just ask directly to system.
my "RequirePermission" on Android:
procedure TForm1.RequestPermissions(aPermissions: System.TArray<string>; aGrantResults: System.TArray<tPermissionStatus>); begin PermissionsService.RequestPermissions( aPermissions {array of permissions}, RequestPermissionsResultProc {procedure to analise the permission given}, RationaleProc {procedure to verify the posssible error messages} );
if you dont need any iteration to show the error to user, then, RationaleProc can be "nil"
procedure TForm1.RationaleProc(const aPermissions: System.TArray<string>; const RationalePostProc: tProc); begin Memo1.Lines.Add('RationaleProc'); // You never see this one. end;
procedure TForm1.RequestPermissionsResultProc(const aPermissions: System.TArray<string>; const aGrantResults: System.TArray<tPermissionStatus>); var i: integer; s: string; begin RunMyProcedureAnyWay; // no needs verify nothing just run-me end;
the rest is with "Android O.S." it is who take care about the user accepted the permissions or not!!! not your app!!
in your project, you can just mark the permissions used in your app to generate the "Android manifest"
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
basically, you can use "Tethering" components on Delphi to create the communication between 2 or more devices... -- 1 or more app server -- "n" apps clients (App server including)
1) TetheringManager -> to find and to do the connection! --> just 1 needs ask the connection to "pair it" with other -----> do the authentication, etc...
2) TetheringAppProfile -> used to send/receive datas
3) who share the "resource" use: Kind.SHARE ...who use the "resource" use: Kind.MIRROR - to reflects in other app
4) exists 2 types of "resources": ...a) Persistents: create in "design-time" ...b) Transients : create in code-source
any way, the resources should exists on "receiver-APP", and to be used in "sender-APP", because you needs verify if the "resource" sended exists on app-Receiver!
or be: --- if App1 have resource named "SomeInfo", then, App2 can send any info for him!
ex.: App2- send a message to App1
if TetheringAppProfile1.SendString(TetheringManager1.RemoteProfiles.First, 'ReplyText1', Edit1.Text) then...
here, "ReplyText1" is a resource that should exists on "App1" and it should be "string" type, because "Edit1.Text" is a string!
on App1: ... resource "Persistent" -- Resources[0]Received(...) (Resources Editor ) procedure TForm2.TetheringAppProfile1Resources0ResourceReceived(const Sender: TObject; const AResource: TRemoteResource); var LText: string; begin LText := AResource.Value.AsString; // it wait for a resource "string", in this case I have just one named "ReplyText1" end;
... resource "Transient" -- resourceReceived(...) procedure TForm1.TetheringAppProfile1ResourceReceived(const Sender: TObject; const AResource: TRemoteResource); ....
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3