{*******************************************************} { } { Helpers for Android } { } { Copyright (C) 2020 KngStr } { } { Some Code from Kastri Free of DelphiWorlds, Thanks } { } {*******************************************************} unit ksAndroid.Helpers; interface uses Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.App, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net; type TAndroidHelperEx = record private class function GetJActivity: JActivity; static; class function GetJContext: JContext; static; public const ICE_CREAM_SANDWICH = 14; ICE_CREAM_SANDWICH_MR1 = 15; JELLY_BEAN = 16; JELLY_BEAN_MR1 = 17; JELLY_BEAN_MR2 = 18; KITKAT = 19; KITKAT_MR1 = 20; LOLLIPOP = 21; LOLLIPOP_MR1 = 22; MARSHMALLOW = 23; NOUGAT = 24; NOUGAT_MR1 = 25; OREO = 26; OREO_MR1 = 27; PIE = 28; Q = 29; /// /// Checks if both build and target are greater or equal to the tested value /// class function CheckBuildAndTarget(const AValue: Integer): Boolean; static; /// /// Returns the equivalent of "AndroidClass.class" /// class function GetClass(const APackageClassName: string): Jlang_Class; static; /// /// Returns the application default icon ID /// class function GetDefaultIconID: Integer; static; /// /// Returns a URI to the notification sound /// class function GetDefaultNotificationSound: Jnet_Uri; static; /// /// Returns target Sdk version /// class function GetTargetSdkVersion: Integer; static; /// /// Returns installed Sdk version /// class function GetBuildSdkVersion: Integer; static; /// /// Returns whether the activity is running foreground /// /// /// Useful from within a service to determine whether or not the service needs to run in foreground mode /// class function IsActivityForeground: Boolean; static; /// /// Converts file to uri, using FileProvider if target API >= 24 /// /// /// Use this only when accessing files with an "external" URI /// class function UriFromFile(const AFile: JFile): Jnet_Uri; static; /// /// Converts filename to uri, using FileProvider if target API >= 24 /// /// /// Use this only when accessing files with an "external" URI /// class function UriFromFileName(const AFileName: string): Jnet_Uri; static; /// Returns Java Application Context class property Context: JContext read GetJContext; /// Returns Java Application Activity /// An exception will be launched if there is no activity, for example a Service class property Activity: JActivity read GetJActivity; /// Returns Application package name class function GetPackageName: string; static; end; implementation uses Androidapi.Helpers, Androidapi.JNI.Os, Androidapi.JNI.Support, Androidapi.JNI.Media, Androidapi.JNI.Provider; { TAndroidHelperEx } class function TAndroidHelperEx.CheckBuildAndTarget(const AValue: Integer): Boolean; begin Result := (GetBuildSdkVersion >= AValue) and (GetTargetSdkVersion >= AValue); end; class function TAndroidHelperEx.GetBuildSdkVersion: Integer; begin Result := TJBuild_VERSION.JavaClass.SDK_INT; end; class function TAndroidHelperEx.GetClass(const APackageClassName: string): Jlang_Class; begin Result := TJLang_Class.JavaClass.forName(StringToJString(APackageClassName), True, TAndroidHelper.Context.getClassLoader); end; class function TAndroidHelperEx.GetDefaultIconID: Integer; begin Result := TAndroidHelper.Context.getApplicationInfo.icon; end; class function TAndroidHelperEx.GetDefaultNotificationSound: Jnet_Uri; begin Result := TJRingtoneManager.JavaClass.getDefaultUri(TJRingtoneManager.JavaClass.TYPE_NOTIFICATION); end; class function TAndroidHelperEx.GetJActivity: JActivity; begin Result := {$IF CompilerVersion > 27} TAndroidHelper.Activity {$ELSE} SharedActivity {$ENDIF} end; class function TAndroidHelperEx.GetJContext: JContext; begin Result := {$IF CompilerVersion > 27} TAndroidHelper.Context; {$ELSE} SharedActivityContext; {$ENDIF} end; class function TAndroidHelperEx.GetPackageName: string; begin Result := JStringToString(Context.getPackageName); end; class function TAndroidHelperEx.GetTargetSdkVersion: Integer; var LApplicationInfo: JApplicationInfo; begin LApplicationInfo := TAndroidHelper.Context.getPackageManager.getApplicationInfo(TAndroidHelper.Context.getPackageName, 0); Result := LApplicationInfo.targetSdkVersion; end; class function TAndroidHelperEx.IsActivityForeground: Boolean; var LService: JObject; LRunningApps: JList; LAppInfo: JActivityManager_RunningAppProcessInfo; I: Integer; begin Result := False; LService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.ACTIVITY_SERVICE); LRunningApps := TJActivityManager.Wrap(TAndroidHelper.JObjectToID(LService)).getRunningAppProcesses; for I := 0 to LRunningApps.size - 1 do begin LAppInfo := TJActivityManager_RunningAppProcessInfo.Wrap(TAndroidHelper.JObjectToID(LRunningApps.get(I))); if LAppInfo.importance = 100 then begin if LAppInfo.importanceReasonComponent <> nil then begin if LAppInfo.importanceReasonComponent.getPackageName.equals(TAndroidHelper.Context.getPackageName) then Exit(True); end else if LRunningApps.size = 1 then Exit(True); end; end; end; class function TAndroidHelperEx.UriFromFile(const AFile: JFile): Jnet_Uri; var LAuthority: JString; begin if CheckBuildAndTarget(NOUGAT) then begin LAuthority := StringToJString(JStringToString(TAndroidHelper.Context.getApplicationContext.getPackageName) + '.fileprovider'); Result := TJFileProvider.JavaClass.getUriForFile(TAndroidHelper.Context, LAuthority, AFile); end else Result := TJnet_uri.JavaClass.fromFile(AFile); end; class function TAndroidHelperEx.UriFromFileName(const AFileName: string): Jnet_Uri; begin Result := UriFromFile(TJFile.JavaClass.init(StringToJString(AFileName))); end; end.