欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限

程序员文章站 2022-06-24 20:04:28
《delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限》一、概述二、源代码:unit uAndoidCommon;//ANDROID:interface{$IFDEF ANDROID}uses System.Permissions //:系统权限 ,System.SysUtils ,System.UITypes //:权限结果需引用TModalResult ,System.Classes //:线程及匿名.....

delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限

https://download.csdn.net/download/pulledup/12683637

一、概述

在上一篇delphi XE关于微信公众号支付及微信零钱支付的便捷解决方案中,我们需要针对Android系统成功获取响应的权限后回调需要执行的事件或方法。本文主要讲解具体实现方法。

实现效果如下:

delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限


delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限


delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限


delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限


delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限

权限不完全具备时,再次申请权限时,不会将已申请通过的权限重复提请审批:


delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限

delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限


delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限


二、android授权源代码

unit uAndoidCommon;
//ANDROID:

interface
{$IFDEF ANDROID}

uses
  System.Permissions //:系统权限
  ,System.SysUtils

  ,System.UITypes    //:权限结果需引用TModalResult
  ,System.Classes    //:线程及匿名线程
  ,System.Threading  //:系统多线程单元,本例用于调用IFuture
  ,System.SyncObjs   //:线程等待的同步对象单元
  //,System.Android.Permissions

  ,Androidapi.Helpers
  ,Androidapi.JNI.JavaTypes
  ,Androidapi.JNI.Os        //:权限字符串在其中定义

  ,FMX.Types
  ,FMX.DialogService //:权限请求的处理结果及权限请求处理后若需对用户进行显示:需引用异步对话框TDialogService.ShowMessage
  ,FMX.Forms  ,FMX.Objects
  ,FMX.helpers.Android
  ,FMX.Memo
  ,FMX.MediaLibrary.Actions
  ,FMX.StdActns  ,FMX.ActnList
  ;
type
  LOnRequestPermissionsResult= reference to procedure(const APermissions: TArray<string>;
    const AGrantResults: TArray<TPermissionStatus>);//: TRequestPermissionsResultProc;
  LOnDisplayRationale = reference to procedure(const APermissions: TArray<string>; const APostRationaleProc: TProc);//: TDisplayRationaleProc;

  ///<summary>Android请求权限的全局变量:</summary>
  var
    FCAMERA, FINSTANT_APP_FOREGROUND_SERVICE,
    FMANAGE_DOCUMENTS, FREAD_EXTERNAL_STORAGE, FWRITE_EXTERNAL_STORAGE,
    FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH //:收发短消息
    :string;
    FRationaleMsg: TStringList;      //:权限申请的理由项目
    FNotGrantResultMsg: TStringList; //:未通过权限申请的项目
    FGrantedResultMsg: TStringList;  //:通过权限申请的项目

    FAllRequestPermissionsGranted:Boolean=true;
    MyForm:TForm;
  ///<summary>Andoid请求某一系统权限:</summary>
  function AndoidRequestPermissions(const AForm: TForm;
    const RequestPermissions:TArray<string>
    ): TArray<string>;  //Array of string
  procedure LoadPermissionRequestResult(
    const APermissions: TArray<string>;
    const AGrantResults: TArray<TPermissionStatus>);
  procedure DisplayRationale(
    const APermissions: TArray<string>;
    const APostRationaleProc: TProc);

{$ENDIF ANDROID}
implementation

uses MySJGY;

{$IFDEF ANDROID}
procedure LoadPermissionRequestResult(
  const APermissions: TArray<string>;
  const AGrantResults: TArray<TPermissionStatus>);
    //:权限请求的处理结果:
var I: Integer;//:请求权限类型的次数
begin
  FNotGrantResultMsg.Clear;
  if PermissionsService.IsEveryPermissionGranted(APermissions) then
  begin
    if MyForm.Name='FormZhuce' then
    begin
      //(MyForm.FindComponent('Memo1') as TMemo).Lines.Add('返回窗体的Memo1啦');
      //(MyForm.FindComponent('Rect_ExecTakePhotoFromLibrary') as TRectangle).OnClick(MyForm as TObject);
      (MyForm.FindComponent('TakePhotoFromLibraryAction1') as TTakePhotoFromLibraryAction).Execute;
    end;
  end else
  begin
    for I := Low(APermissions) to High(APermissions) do //APermissions
    begin
      if not (AGrantResults[I] = TPermissionStatus.Granted)  then
      begin
        if APermissions[I].Contains(FCamera) then
          if not FNotGrantResultMsg.Text.Contains('相机') then
            FNotGrantResultMsg.Add('●您未允许访问手机相机,无法启用相机拍照' + sLineBreak);

        // FREAD_EXTERNAL_STORAGE FWRITE_EXTERNAL_STORAGE
        if APermissions[I].Contains(FREAD_EXTERNAL_STORAGE)
          or APermissions[I].Contains(FWRITE_EXTERNAL_STORAGE)
        then
          if not FNotGrantResultMsg.Text.Contains('存储') then
            FNotGrantResultMsg.Add('●您未允许访问手机存储,无法保存图片等媒体'+ sLineBreak);

        //FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH
        if APermissions[I].Contains(FREAD_SMS)
          or APermissions[I].Contains(FSEND_SMS)
          or APermissions[I].Contains(FRECEIVE_SMS)
          or APermissions[I].Contains(FRECEIVE_MMS)
          or APermissions[I].Contains(FBROADCAST_SMS)
          or APermissions[I].Contains(FRECEIVE_WAP_PUSH)
        then
        begin
          if not FNotGrantResultMsg.Text.Contains('短信') then
            FNotGrantResultMsg.Add('●您未允许使用手机短信相关功能'+ sLineBreak);
        end;

        if (I=High(APermissions)) and (FNotGrantResultMsg.Text.Trim<>'') then
          //:授权通过后要执行的事件或过程:这里是打开媒体库供用户选择:
            //:由本函数返回值来控制,这里并不需要做处理
        SJGY.ShowDialog(
          MyForm, //'循环次数:'+I.ToString+
          FNotGrantResultMsg.Text, //:上面定义的未通过机主授权的权限提示
          '未授权提示', '提示', // 调用对话框   aType:提示,输入,选择,编辑共4种
          procedure(aResult: Boolean; astr: string) // aStr为空 aResult为true
          begin //:授权未通过就给提示
            //:需要处理本IF有问题
          end, TVirtualKeyboardType.Default, $FFF7946F, '确定', '', 3); // 设置了横线颜色,上中下分别对应123,默认值为3

      end;
    end; //:取授权未通过或通过的提示信息
  end;

end;

procedure DisplayRationale(
  const APermissions: TArray<string>;
  const APostRationaleProc: TProc);
//:向用户显示请求权限的理由
  var I: Integer;
begin
  FRationaleMsg.Clear;
  if not PermissionsService.IsEveryPermissionGranted(APermissions) then
  for I := Low(APermissions) to High(APermissions) do
  begin
    if not
      PermissionsService.IsPermissionGranted(APermissions[I]) then
    begin

      if APermissions[I].Contains(FCamera) then
        if not FRationaleMsg.Text.Contains('相机') then
           FRationaleMsg.Add('●App将会提示您:"'+Application.Title+'"需要使用相机,您是否允许?意思是要访问你的手机相机,这样才可以启用相机拍照' + sLineBreak);
      // FREAD_EXTERNAL_STORAGE FWRITE_EXTERNAL_STORAGE
      if APermissions[I].Contains(FREAD_EXTERNAL_STORAGE)
        or APermissions[I].Contains(FWRITE_EXTERNAL_STORAGE)
      then
        if not FRationaleMsg.Text.Contains('存储') then
          FRationaleMsg.Add('●App将会提示您:"'+Application.Title+'"需要使用存储权限,您是否允许?意思是要访问你的手机媒体库,这样才可以保存必要的图片'+ sLineBreak);
      //FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH
      if APermissions[I].Contains(FREAD_SMS)
        or APermissions[I].Contains(FSEND_SMS)
        or APermissions[I].Contains(FRECEIVE_SMS)
        or APermissions[I].Contains(FRECEIVE_MMS)
        or APermissions[I].Contains(FBROADCAST_SMS)
        or APermissions[I].Contains(FRECEIVE_WAP_PUSH)
      then
        if not FRationaleMsg.Text.Contains('短信') then
          FRationaleMsg.Add('●App将会提示您:"'+Application.Title+'"需要使用短信权限,您是否允许?意思是要请求使用手机短信,这样才可使用短信相关功能'+ sLineBreak);
    end;
  end;

  SJGY.ShowDialog(
    MyForm,
    '选择"确认"后,需要您通过权限提示以便于:'+sLineBreak+sLineBreak
      +FRationaleMsg.Text,//:上面定义的请求权限的理由
    '请您回答',
    '选择', // 调用对话框   aType:提示,输入,选择,编辑共4种
    procedure(aResult: Boolean; astr: string) // aStr返回输入的内容 aResult返回点击了哪个按钮:true为确定按钮,false为取消按钮
    begin
      if aResult = true then // 点击了确定按钮
      begin
        APostRationaleProc;
      end;

      if aResult = false then // 点击了取消按钮
      begin
        //
      end;
    end, TVirtualKeyboardType.Default, $FFF7946F,
    '确认', '取消', 3 ); //:设置了横线颜色,3:上中下分别对应123,默认值为3

end; //System.Permissions

function AndoidRequestPermissions(const AForm: TForm;
  const RequestPermissions:TArray<string>
  ): TArray<string>;  //Array of string
var LhashCode:Integer;
  LPermission:string;
  ///<summary>Android请求权限的全局变量:</summary>
  MyPermissions: TArray<String>;    //:需要请求的内部权限数组
  RequestPermissionsLenth :Integer; //:需要请求的内部权限数
  LGrantResults: TArray<TPermissionStatus>;
var LRequestPermissions: TArray<string>;
  LResultStrOfRequestPermissions:string;
  LResultAllOfRequestPermissions:Boolean;

  var LGrantedPermissionsLength:Integer;   //:实际通过请求的内部权限数
      LNotGrantedPermissions: TArray<String>; //:实际未通过请求的内部权限数组
begin
//Androidapi.JNI.Os //:权限字符串在其中定义
  LRequestPermissions:=RequestPermissions;
  try
    //Pos('读文件',RequestPermissions)>0 //:System.SysUtils.TStringHelper
    //if (RequestPermissions.Trim).IndexOf('摄像头',0,length((RequestPermissions.Trim)))>=0 then
    if length(RequestPermissions)>0 then
    for RequestPermissionsLenth := Low(RequestPermissions) to High(RequestPermissions) do
    begin
      if (RequestPermissions[RequestPermissionsLenth])='发手机短消息' then
      begin //FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH //:收发短消息
        try //读手机短信,发手机短消息,收手机短消息,收手机彩信,广播手机短消息,接收WAP推送
          FSEND_SMS := JStringToString(
            TJManifest_permission.JavaClass
            .SEND_SMS);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1]:= FSEND_SMS;
        except
        end;
      end;
      if (RequestPermissions[RequestPermissionsLenth])='广播手机短消息' then
      begin //FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH //:收发短消息
        try //读手机短信,发手机短消息,收手机短消息,收手机彩信,广播手机短消息,接收WAP推送
          FBROADCAST_SMS := JStringToString(
            TJManifest_permission.JavaClass
            .BROADCAST_SMS);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1]:= FBROADCAST_SMS;
        except
        end;
      end;
      if (RequestPermissions[RequestPermissionsLenth])='收手机短消息' then
      begin //FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH //:收发短消息
        try //读手机短信,发手机短消息,收手机短消息,收手机彩信,广播手机短消息,接收WAP推送
          FRECEIVE_SMS := JStringToString(
            TJManifest_permission.JavaClass
            .RECEIVE_SMS);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1]:= FRECEIVE_SMS;
        except
        end;
      end;
      if (RequestPermissions[RequestPermissionsLenth])='收手机彩信' then
      begin //FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH //:收发短消息
        try //读手机短信,发手机短消息,收手机短消息,收手机彩信,广播手机短消息,接收WAP推送
          FRECEIVE_MMS := JStringToString(
            TJManifest_permission.JavaClass
            .RECEIVE_MMS);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1]:= FRECEIVE_MMS;
        except
        end;
      end;
      if (RequestPermissions[RequestPermissionsLenth])='读手机短信' then
      begin //FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH //:收发短消息
        try //读手机短信,发手机短消息,收手机短消息,收手机彩信,广播手机短消息,接收WAP推送
          FREAD_SMS := JStringToString(
            TJManifest_permission.JavaClass
            .READ_SMS);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1]:= FREAD_SMS;
        except
        end;
      end;
      if (RequestPermissions[RequestPermissionsLenth])='接收WAP推送' then
      begin //FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSH //:收发短消息
        try //读手机短信,发手机短消息,收手机短消息,收手机彩信,广播手机短消息,接收WAP推送
          FRECEIVE_WAP_PUSH := JStringToString(
            TJManifest_permission.JavaClass
            .RECEIVE_WAP_PUSH);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1]:= FRECEIVE_WAP_PUSH;
        except
        end;
      end;
      if (RequestPermissions[RequestPermissionsLenth])='相机' then
      begin
        try
          FCAMERA := JStringToString(
            TJManifest_permission.JavaClass
            .CAMERA);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1]:= FCAMERA;
        except
        end;
      end;
      {
      if (RequestPermissions[RequestPermissionsLenth])='前台服务安装应用' then
      begin
        try
          FINSTANT_APP_FOREGROUND_SERVICE := JStringToString(
            TJManifest_permission.JavaClass
            .INSTANT_APP_FOREGROUND_SERVICE);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := FINSTANT_APP_FOREGROUND_SERVICE;
        except
        end;
      end;
      if (RequestPermissions.Trim)='安装应用' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .REQUEST_INSTALL_PACKAGES);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='全局搜索' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .GLOBAL_SEARCH);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;   }
      //管理文档:
      if (RequestPermissions[RequestPermissionsLenth])='管理文档' then
      begin
        try
          FMANAGE_DOCUMENTS := JStringToString(
            TJManifest_permission.JavaClass
            .MANAGE_DOCUMENTS);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := FMANAGE_DOCUMENTS;
        except
        end;
      end;
      //存储:
      if (RequestPermissions[RequestPermissionsLenth])='读取文件' then
      begin
        try
          FREAD_EXTERNAL_STORAGE := JStringToString(
            TJManifest_permission.JavaClass
            .READ_EXTERNAL_STORAGE);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := FREAD_EXTERNAL_STORAGE;
        except
        end;
      end;
      if (RequestPermissions[RequestPermissionsLenth])='写入文件' then
      begin
        try
          FWRITE_EXTERNAL_STORAGE := JStringToString(
            TJManifest_permission.JavaClass
            .WRITE_EXTERNAL_STORAGE);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := FWRITE_EXTERNAL_STORAGE;
        except
        end;
      end;

      {
      if (RequestPermissions.Trim)='读取手机状态' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .READ_PHONE_STATE);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='INTERNET' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .INTERNET);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='网络状态' then
      begin
        try
          //LhashCode:=JObjectClass(
            //TJManifest_permission.JavaClass
            //._GetACCESS_NETWORK_STATE ).init.hashCode;
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .ACCESS_NETWORK_STATE);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='WIFI状态' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .ACCESS_WIFI_STATE);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='在其他应用上层显示' then
      begin       //比如:点播播放器悬浮窗权限
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .SYSTEM_ALERT_WINDOW);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='允许访问通知策略' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .ACCESS_NOTIFICATION_POLICY);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='请求绑定通知监听服务' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .BIND_NOTIFICATION_LISTENER_SERVICE);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='允许一个APP伴侣程序在后台运行' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .REQUEST_COMPANION_RUN_IN_BACKGROUND);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='允许一个APP伴侣程序在后台使用数据' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .REQUEST_COMPANION_USE_DATA_IN_BACKGROUND);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='写系统配置' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .WRITE_SETTINGS);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='绑定条件提供者服务' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .BIND_CONDITION_PROVIDER_SERVICE);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end;
      if (RequestPermissions.Trim)='绑定设备管理' then
      begin
        try
          LPermission := JStringToString(
            TJManifest_permission.JavaClass
            .BIND_DEVICE_ADMIN);
          SetLength(MyPermissions, Length(MyPermissions)+1);
          MyPermissions[Length(MyPermissions)-1] := LPermission;
        except
        end;
      end; //}
    end;

  except
  end;

  // 调用方法:动态请求所有程序需要用到的权限,根据需要您可以减少:
  // PermissionsService.RequestPermissions([FPermissionCAMERA, FPermissionREAD_EXTERNAL_STORAGE, FPermissionWRITE_EXTERNAL_STORAGE, FPermissionREAD_PHONE_STATE, FPermissionACCESS_NETWORK_STATE,
  // FPermissionBLUETOOTH_ADMIN, FPermissionBLUETOOTH, FPermissionACCESS_WIFI_STATE, FPermissionVIBRATE, FPermissionRECORD_AUDIO, FPermissionRECEIVE_SMS, FPermissionCALL_PHONE, FPermissionREAD_SMS,
  // FPermissionACCESS_FINE_LOCATION, FPermissionINSTALL_PACKAGES, FPermissionINTERNET, FPermissionSEND_SMS, FPermissionWRITE_CONTACTS, FPermissionACCESS_LOCATION_EXTRA_COMMANDS,
  // FPermissionREAD_PHONE_NUMBERS, FPermissionREAD_CONTACTS], nil, nil);

    /// <summary>Request one or more permissions</summary>
    /// <remarks>Any permissions that are not currently granted will be requested.
    /// Beforehand, a rationale may be displayed to the user if:
    /// <para>  i)APermissions: TArray<string>:
    ///a rationale string has been set for the permission in question</para>
    /// <para> ii)AOnRequestPermissionsResult: TRequestPermissionsResultEvent:
    /// the OS deems it appropriate (we're requesting a permission again that was previously denied)</para>
    /// <para>iii)AOnDisplayRationale: TDisplayRationaleEvent:
    /// a rationale display routine is passed in</para>
    /// The rationale handler must display the passed in rationale string
    ///asynchronously and not block the thread.
    /// <para>This overload takes an event handler method.</para></remarks>
    ///<summary>请求一个或多个权限</summary>
    ///<备注>将请求当前未授予的任何权限。
    ///在以下情况下,可以事先向用户显示基本原理:
    ///<para>i)已经为相关权限设置了基本原理字符串</para>
    ///<para>ii)操作系统认为合适(我们再次请求之前被拒绝的许可)</para>
    ///<para>iii)一个基本原理显示程序被传入</para>
    ///基本原理处理程序必须异步显示传入的基本原理字符串,并且不能阻塞线程。
    ///<para>此重载采用事件处理程序方法。</para></remarks>

//  CallInUIThreadAndWaitFinishing(
//  procedure
//  begin
//    PermissionsService.RequestPermissions(
//      MyPermissions,nil,nil);
  MyForm:=AForm;
  PermissionsService.RequestPermissions(
    MyPermissions,LoadPermissionRequestResult,DisplayRationale);
//  end);
//  PermissionsService.RequestPermissions(
//    MyPermissions,LoadPermissionRequestResult,DisplayRationale);
//  IntToStr(Length(MyPermissions));
//  if Length(MyPermissions)>0 then
//    Result:=MyPermissions else Result:=[];

  //LGrantedPermissionsLength:Integer; //:实际通过请求的内部权限数
    //LNotGrantedPermissions: TArray<String>; //:实际未通过请求的内部权限数组
    LNotGrantedPermissions:=nil;
    for LGrantedPermissionsLength := Low(MyPermissions) to High(MyPermissions) do
    begin
      if PermissionsService.IsPermissionGranted (
          MyPermissions[LGrantedPermissionsLength] )
        =false then
      begin
        SetLength(LNotGrantedPermissions, Length(LNotGrantedPermissions)+1);
        LNotGrantedPermissions[Length(LNotGrantedPermissions)-1] := MyPermissions[LGrantedPermissionsLength];
      end;

    end;
    //返回哪些权限没有通过:
    //IntToStr(Length(LNotGrantedPermissions));
    if Length(LNotGrantedPermissions)>0 then
      Result:=LNotGrantedPermissions else Result:=[];

end;

{$ENDIF ANDROID}

initialization
{$IFDEF ANDROID}
  if not Assigned(FRationaleMsg) then
    FRationaleMsg:= TStringList.Create;      //:权限申请的理由项目
  if not Assigned(FNotGrantResultMsg) then
    FNotGrantResultMsg:= TStringList.Create; //:未通过权限申请的项目
  if not Assigned(FGrantedResultMsg) then
    FGrantedResultMsg:= TStringList.Create;  //:通过权限申请的项目
{$ENDIF ANDROID}
finalization
{$IFDEF ANDROID}
  if Assigned(FRationaleMsg) then
    FRationaleMsg.DisposeOf;      //:权限申请的理由项目
  if Assigned(FNotGrantResultMsg) then
    FNotGrantResultMsg.DisposeOf; //:未通过权限申请的项目
  if Assigned(FGrantedResultMsg) then
    FGrantedResultMsg.DisposeOf;  //:通过权限申请的项目
{$ENDIF ANDROID}
end.

三、调用方法:

3.1、调用方

 {$IFDEF ANDROID}
        //:请求存储权限:并不包含'管理文档'
          //:只需2项权限:READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE
          //LPermissions:=['管理文档','读取文件','写入文件','读手机短信'];
        LPermissions:=['读取文件','写入文件','读手机短信'];
        FNotGrantedPermissions:=nil;
        FNotGrantedPermissions:=
        AndoidRequestPermissions(
          (self as TForm),
          LPermissions
        );
      {$ENDIF ANDROID}

3.2、调用并获取Android权限后需要处理的结果事件或方法

由调用方的调用代码中传入(self as TForm),在“二、android授权源码源代码"中:

///<summary>Andoid请求某一系统权限:</summary>
function AndoidRequestPermissions(const AForm: TForm;
  const RequestPermissions:TArray<string>
  ): TArray<string>;
//var .....
begin
    //.....

  MyForm:=AForm;
  PermissionsService.RequestPermissions(
    MyPermissions,LoadPermissionRequestResult,DisplayRationale);

    //....

end;



procedure LoadPermissionRequestResult(
  const APermissions: TArray<string>;
  const AGrantResults: TArray<TPermissionStatus>);
    //:权限请求的处理结果:
//var I: Integer;//:请求权限类型的次数
begin

  FNotGrantResultMsg.Clear;
  if PermissionsService.IsEveryPermissionGranted(APermissions) then
  begin
    if MyForm.Name='FormZhuce' then
    begin
      //(MyForm.FindComponent('Memo1') as TMemo).Lines.Add('返回窗体的Memo1啦');
      //(MyForm.FindComponent('Rect_ExecTakePhotoFromLibrary') as TRectangle).OnClick(MyForm as TObject);
      (MyForm.FindComponent('TakePhotoFromLibraryAction1') as TTakePhotoFromLibraryAction).Execute;
    end;
  end else 
//......
  end;

end;

本文地址:https://blog.csdn.net/pulledup/article/details/107773589