《delphi XE开发微信支付Android获取手机存储权限、Android获取短信权限》
一、概述
二、源代码:
unit uAndoidCommon;
//ANDROID:interface
{$IFDEF ANDROID}usesSystem.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;
typeLOnRequestPermissionsResult= 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>varFCAMERA, 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 stringprocedure LoadPermissionRequestResult(const APermissions: TArray<string>;const AGrantResults: TArray<TPermissionStatus>);procedure DisplayRationale(const APermissions: TArray<string>;const APostRationaleProc: TProc);{$ENDIF ANDROID}
implementationuses MySJGY;{$IFDEF ANDROID}
procedure LoadPermissionRequestResult(const APermissions: TArray<string>;const AGrantResults: TArray<TPermissionStatus>);//:权限请求的处理结果:
var I: Integer;//:请求权限类型的次数
beginFNotGrantResultMsg.Clear;if PermissionsService.IsEveryPermissionGranted(APermissions) thenbeginif MyForm.Name='FormZhuce' thenbegin//(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 elsebeginfor I := Low(APermissions) to High(APermissions) do //APermissionsbeginif not (AGrantResults[I] = TPermissionStatus.Granted) thenbeginif APermissions[I].Contains(FCamera) thenif not FNotGrantResultMsg.Text.Contains('相机') thenFNotGrantResultMsg.Add('●您未允许访问手机相机,无法启用相机拍照' + sLineBreak);// FREAD_EXTERNAL_STORAGE FWRITE_EXTERNAL_STORAGEif APermissions[I].Contains(FREAD_EXTERNAL_STORAGE)or APermissions[I].Contains(FWRITE_EXTERNAL_STORAGE)thenif not FNotGrantResultMsg.Text.Contains('存储') thenFNotGrantResultMsg.Add('●您未允许访问手机存储,无法保存图片等媒体'+ sLineBreak);//FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSHif 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)thenbeginif not FNotGrantResultMsg.Text.Contains('短信') thenFNotGrantResultMsg.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为truebegin //:授权未通过就给提示//:需要处理本IF有问题end, TVirtualKeyboardType.Default, $FFF7946F, '确定', '', 3); // 设置了横线颜色,上中下分别对应123,默认值为3end;end; //:取授权未通过或通过的提示信息end;end;procedure DisplayRationale(const APermissions: TArray<string>;const APostRationaleProc: TProc);
//:向用户显示请求权限的理由var I: Integer;
beginFRationaleMsg.Clear;if not PermissionsService.IsEveryPermissionGranted(APermissions) thenfor I := Low(APermissions) to High(APermissions) dobeginif notPermissionsService.IsPermissionGranted(APermissions[I]) thenbeginif APermissions[I].Contains(FCamera) thenif not FRationaleMsg.Text.Contains('相机') thenFRationaleMsg.Add('●App将会提示您:"'+Application.Title+'"需要使用相机,您是否允许?意思是要访问你的手机相机,这样才可以启用相机拍照' + sLineBreak);// FREAD_EXTERNAL_STORAGE FWRITE_EXTERNAL_STORAGEif APermissions[I].Contains(FREAD_EXTERNAL_STORAGE)or APermissions[I].Contains(FWRITE_EXTERNAL_STORAGE)thenif not FRationaleMsg.Text.Contains('存储') thenFRationaleMsg.Add('●App将会提示您:"'+Application.Title+'"需要使用存储权限,您是否允许?意思是要访问你的手机媒体库,这样才可以保存必要的图片'+ sLineBreak);//FREAD_SMS,FSEND_SMS,FRECEIVE_SMS,FRECEIVE_MMS,FBROADCAST_SMS,FRECEIVE_WAP_PUSHif 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)thenif not FRationaleMsg.Text.Contains('短信') thenFRationaleMsg.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为取消按钮beginif aResult = true then // 点击了确定按钮beginAPostRationaleProc;end;if aResult = false then // 点击了取消按钮begin//end;end, TVirtualKeyboardType.Default, $FFF7946F,'确认', '取消', 3 ); //:设置了横线颜色,3:上中下分别对应123,默认值为3end; //System.Permissionsfunction 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 thenif length(RequestPermissions)>0 thenfor RequestPermissionsLenth := Low(RequestPermissions) to High(RequestPermissions) dobeginif (RequestPermissions[RequestPermissionsLenth])='发手机短消息' thenbegin //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;exceptend;end;if (RequestPermissions[RequestPermissionsLenth])='广播手机短消息' thenbegin //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;exceptend;end;if (RequestPermissions[RequestPermissionsLenth])='收手机短消息' thenbegin //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;exceptend;end;if (RequestPermissions[RequestPermissionsLenth])='收手机彩信' thenbegin //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;exceptend;end;if (RequestPermissions[RequestPermissionsLenth])='读手机短信' thenbegin //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;exceptend;end;if (RequestPermissions[RequestPermissionsLenth])='接收WAP推送' thenbegin //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;exceptend;end;if (RequestPermissions[RequestPermissionsLenth])='相机' thenbegintryFCAMERA := JStringToString(TJManifest_permission.JavaClass.CAMERA);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1]:= FCAMERA;exceptend;end;{if (RequestPermissions[RequestPermissionsLenth])='前台服务安装应用' thenbegintryFINSTANT_APP_FOREGROUND_SERVICE := JStringToString(TJManifest_permission.JavaClass.INSTANT_APP_FOREGROUND_SERVICE);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := FINSTANT_APP_FOREGROUND_SERVICE;exceptend;end;if (RequestPermissions.Trim)='安装应用' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.REQUEST_INSTALL_PACKAGES);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='全局搜索' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.GLOBAL_SEARCH);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end; }//管理文档:if (RequestPermissions[RequestPermissionsLenth])='管理文档' thenbegintryFMANAGE_DOCUMENTS := JStringToString(TJManifest_permission.JavaClass.MANAGE_DOCUMENTS);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := FMANAGE_DOCUMENTS;exceptend;end;//存储:if (RequestPermissions[RequestPermissionsLenth])='读取文件' thenbegintryFREAD_EXTERNAL_STORAGE := JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := FREAD_EXTERNAL_STORAGE;exceptend;end;if (RequestPermissions[RequestPermissionsLenth])='写入文件' thenbegintryFWRITE_EXTERNAL_STORAGE := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := FWRITE_EXTERNAL_STORAGE;exceptend;end;{if (RequestPermissions.Trim)='读取手机状态' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.READ_PHONE_STATE);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='INTERNET' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.INTERNET);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='网络状态' thenbegintry//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;exceptend;end;if (RequestPermissions.Trim)='WIFI状态' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.ACCESS_WIFI_STATE);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='在其他应用上层显示' thenbegin //比如:点播播放器悬浮窗权限tryLPermission := JStringToString(TJManifest_permission.JavaClass.SYSTEM_ALERT_WINDOW);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='允许访问通知策略' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.ACCESS_NOTIFICATION_POLICY);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='请求绑定通知监听服务' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.BIND_NOTIFICATION_LISTENER_SERVICE);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='允许一个APP伴侣程序在后台运行' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.REQUEST_COMPANION_RUN_IN_BACKGROUND);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='允许一个APP伴侣程序在后台使用数据' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='写系统配置' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.WRITE_SETTINGS);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='绑定条件提供者服务' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.BIND_CONDITION_PROVIDER_SERVICE);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end;if (RequestPermissions.Trim)='绑定设备管理' thenbegintryLPermission := JStringToString(TJManifest_permission.JavaClass.BIND_DEVICE_ADMIN);SetLength(MyPermissions, Length(MyPermissions)+1);MyPermissions[Length(MyPermissions)-1] := LPermission;exceptend;end; //}end;exceptend;// 调用方法:动态请求所有程序需要用到的权限,根据需要您可以减少:// 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) dobeginif PermissionsService.IsPermissionGranted (MyPermissions[LGrantedPermissionsLength] )=false thenbeginSetLength(LNotGrantedPermissions, Length(LNotGrantedPermissions)+1);LNotGrantedPermissions[Length(LNotGrantedPermissions)-1] := MyPermissions[LGrantedPermissionsLength];end;end;//返回哪些权限没有通过://IntToStr(Length(LNotGrantedPermissions));if Length(LNotGrantedPermissions)>0 thenResult:=LNotGrantedPermissions else Result:=[];end;{$ENDIF ANDROID}initialization
{$IFDEF ANDROID}if not Assigned(FRationaleMsg) thenFRationaleMsg:= TStringList.Create; //:权限申请的理由项目if not Assigned(FNotGrantResultMsg) thenFNotGrantResultMsg:= TStringList.Create; //:未通过权限申请的项目if not Assigned(FGrantedResultMsg) thenFGrantedResultMsg:= TStringList.Create; //:通过权限申请的项目
{$ENDIF ANDROID}
finalization
{$IFDEF ANDROID}if Assigned(FRationaleMsg) thenFRationaleMsg.DisposeOf; //:权限申请的理由项目if Assigned(FNotGrantResultMsg) thenFNotGrantResultMsg.DisposeOf; //:未通过权限申请的项目if Assigned(FGrantedResultMsg) thenFGrantedResultMsg.DisposeOf; //:通过权限申请的项目
{$ENDIF ANDROID}
end.