123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680 |
- {*******************************************************}
- { }
- { Helpers for Android }
- { }
- { Copyright (C) 2020 KngStr }
- { }
- { Some Code from }
- { Kastri Free of DelphiWorlds }
- { QDAC of swish }
- { Thanks }
- { }
- {*******************************************************}
- unit ksAndroid.Helpers;
- interface
- uses
- System.SysUtils, Androidapi.JNIBridge,
- 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;
- class function GetJActivityManager: JActivityManager; 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;
- /// <summary>
- /// Checks if both build and target are greater or equal to the tested value
- /// </summary>
- class function CheckBuildAndTarget(const AValue: Integer): Boolean; static;
- /// <summary>
- /// Returns the equivalent of "AndroidClass.class"
- /// </summary>
- class function GetClass(const APackageClassName: string): Jlang_Class; static;
- /// <summary>
- /// Returns the application default icon ID
- /// </summary>
- class function GetDefaultIconID: Integer; static;
- /// <summary>
- /// Returns a URI to the notification sound
- /// </summary>
- class function GetDefaultNotificationSound: Jnet_Uri; static;
- /// <summary>
- /// Returns target Sdk version
- /// </summary>
- class function GetTargetSdkVersion: Integer; static;
- /// <summary>
- /// Returns installed Sdk version
- /// </summary>
- class function GetBuildSdkVersion: Integer; static;
- /// <summary>
- /// Returns whether the activity is running foreground
- /// </summary>
- /// <remarks>
- /// Useful from within a service to determine whether or not the service needs to run in foreground mode
- /// </remarks>
- class function IsActivityForeground: Boolean; static;
- /// <summary>
- /// Get column data from uri
- /// </summary>
- class function GetColumnAsString(const AUri: Jnet_Uri; const AColumn: JString; ASelection: JString = nil;
- ASelectionArgs: TJavaObjectArray<JString> = nil; ASortOrder: JString = nil): string; static;
- /// <summary>
- /// Get data column data from uri
- /// </summary>
- class function GetDataColumnAsString(const AUri: Jnet_Uri; ASelection: JString = nil;
- ASelectionArgs: TJavaObjectArray<JString> = nil; ASortOrder: JString = nil): string; static;
- /// <summary>
- /// Converts uri to file path
- /// </summary>
- class function FileFromUri(const AUri: Jnet_Uri): string; overload; static;
- /// <summary>
- /// Converts file to uri, without FileProvider
- /// </summary>
- class function UriFromFile(const AFile: JFile): Jnet_Uri; overload; static;
- /// <summary>
- /// Converts file to uri, without FileProvider
- /// </summary>
- class function UriFromFile(const AFileName: string): Jnet_Uri; overload; static;
- /// <summary>
- /// Converts file to uri, using FileProvider if target API >= 24
- /// </summary>
- /// <remarks>
- /// Use this only when accessing files with an "external" URI
- /// </remarks>
- class function SharedUriFromFile(const AFile: JFile; const AAuthority: string = ''): Jnet_Uri; overload; static;
- /// <summary>
- /// Converts filename to uri, using FileProvider if target API >= 24
- /// </summary>
- /// <remarks>
- /// Use this only when accessing files with an "external" URI
- /// </remarks>
- class function SharedUriFromFile(const AFileName: string; const AAuthority: string = ''): Jnet_Uri; overload; static;
- /// <summary>
- /// TJnet_Uri.JavaClass.parse
- /// </summary>
- class function UriParse(const S: string): Jnet_Uri; overload; static;
- /// <summary>
- /// TJnet_Uri.JavaClass.parse
- /// </summary>
- class function UriParse(const S: JString): Jnet_Uri; overload; static;
- /// <summary>Returns Java Application Context</summary>
- class property Context: JContext read GetJContext;
- /// <summary>Returns Java Application Activity</summary>
- /// <remarks>An exception will be launched if there is no activity, for example a Service</remarks>
- class property Activity: JActivity read GetJActivity;
- /// <summary>Returns Java Application Activity Manager</summary>
- class property ActivityManager: JActivityManager read GetJActivityManager;
- /// <remarks>Need reorder tasks permission</remarks>
- class procedure BringAppToFront; static;
- /// <remarks>Need reorder tasks permission</remarks>
- class procedure SendAppToBack; static;
- /// <summary>Call a Java Activity</summary>
- class function StartActivity(Intent: JIntent; const Code: Integer = -1): Boolean; static;
- /// <summary>Check HasAssocApp and Call a Java Activity</summary>
- class function CheckAndStartActivity(Intent: JIntent; const Code: Integer = -1): Boolean; static;
- /// <summary>Returns Application package name</summary>
- class function GetPackageName: string; static;
- /// <summary>Returns Application package label</summary>
- class function GetPackageLabel: string; static;
- /// <summary>Returns MimeType from filename</summary>
- class function GetMimeType(AFileName: string): JString; static;
- /// <summary>Returns Primary SDCard path</summary>
- class function GetSDCardPath: string; static;
- /// <summary>Checks if there is at least one application capable of receiving the intent.</summary>
- class function HasAssocApp(const URI: string): Boolean; overload; static;
- /// <summary>Checks if there is at least one application capable of receiving the intent.</summary>
- class function HasAssocApp(const Intent: JIntent): Boolean; overload; static;
- /// <summary>Install an android package: xxx.apk</summary>
- /// <remarks>
- /// <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
- /// </remarks>
- class function InstallPackage(const AFileName: string; const AAuthority: string = ''): Boolean; static;
- /// <summary>Check if an application is installed</summary>
- class function IsAppInstalled(const APackage: string): Boolean; static;
- /// <summary>Add/Cear FLAG_KEEP_SCREEN_ON</summary>
- class function KeepScreen(AOn: Boolean): Boolean; static;
- end;
- implementation
- uses
- {$IFDEF DEBUG}FMX.Types,{$ENDIF}
- Androidapi.JNI.Os, Androidapi.JNI.Support,
- Androidapi.JNI.Media, Androidapi.JNI.Provider, Androidapi.JNI.Webkit,
- Androidapi.Helpers, FMX.Helpers.Android, System.IOUtils;
- { TAndroidHelperEx }
- class procedure TAndroidHelperEx.BringAppToFront;
- begin
- ActivityManager.moveTaskToFront(Activity.getTaskId, TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
- end;
- class function TAndroidHelperEx.CheckAndStartActivity(Intent: JIntent;
- const Code: Integer): Boolean;
- begin
- Result := (Intent <> nil) and HasAssocApp(Intent);
- if not Result then
- Exit;
- Result := TAndroidHelperEx.StartActivity(Intent, Code);
- end;
- class function TAndroidHelperEx.CheckBuildAndTarget(const AValue: Integer): Boolean;
- begin
- Result := (GetBuildSdkVersion >= AValue) and (GetTargetSdkVersion >= AValue);
- end;
- (*
- * >=4.4
- * uri=content://com.android.providers.media.documents/document/image%3A293502
- * uri=file:///storage/emulated/0/temp_photo.jpg
- * uri=content://media/external/images/media/193968
- * <4.4
- * uri=content://media/external/images/media/13
- * third party
- * content://com.speedsoftware.explorer.fileprovider/root/storage/emulated/0/Android/data/com.lifan.qspsy/files/cache/thumb/F6AB021A6BBCEFC3B942625FBA2E6ADE/7.jpg
- * content://com.tencent.mtt.fileprovider/QQBrowser/Movies/BVR_2019_10_14_10_52_29_trimq.mp4
- * content://com.estrongs.files/storage/emulated/0/DCIM/360%E8%A1%8C%E8%BD%A6%E8%AE%B0%E5%BD%95%E4%BB%AA/2018_02_11_14_16_40_ABAC1BB6.mp4
- *
- * 参考文献
- * https://github.com/coltoscosmin/FileUtils/blob/master/FileUtils.java
- * https://github.com/DB-BOY/FileChoose/blob/master/app/src/main/java/cn/dbboy/filechoose/FileUtil.java
- * https://www.jianshu.com/p/c5f207f8cce6
- * https://blog.csdn.net/chengfu116/article/details/74923161
- * https://www.cnblogs.com/epmouse/p/5421048.html
- *
- * 暂未实现
- * 安卓10好像完全没有获取真实路径的机会
- * 安卓7/8/9貌似有些机型还是不行,只能是获取内容后在自己可读写的区域存一份儿
- * 如果是获取内容而不是path的话,就不需要用这里了,单独搞个api更好
- *)
- class function TAndroidHelperEx.FileFromUri(const AUri: Jnet_Uri): string;
- function GetUriByType(S: string): Jnet_Uri;
- begin
- if SameText(S, 'image') then
- Result := TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI
- else if SameText(S, 'video') then
- Result := TJVideo_Media.JavaClass.EXTERNAL_CONTENT_URI
- else if SameText(S, 'audio') then
- Result := TJAudio_Media.JavaClass.EXTERNAL_CONTENT_URI
- else
- Result := nil;
- end;
- function GetDocId(var ADocId, AType, AId: string): Boolean;
- var
- LJString: JString;
- LArr: TArray<string>;
- begin
- Result := False;
- LJString := TJDocumentsContract.JavaClass.getDocumentId(AUri);
- if LJString = nil then
- Exit;
- ADocId := JStringToString(LJString);
- if ADocId = '' then
- Exit;
- LArr := ADocId.Split([':']);
- if Length(LArr) < 2 then begin
- AType := '';
- AId := ADocId;
- end
- else begin
- AType := LArr[0];
- AId := LArr[1];
- end;
- Result := AId <> '';
- end;
- var
- LSdCard, LPath: string;
- LAuthority, LScheme, LDocId, LType, LId: string;
- LSelection: JString;
- LUri: Jnet_Uri;
- LArr: TArray<string>;
- I: Integer;
- iId: Int64;
- begin
- Result := '';
- if AUri = nil then
- Exit;
- LSdCard := GetSDCardPath;
- LAuthority := JStringToString(AUri.getAuthority().toString);
- LScheme := JStringToString(AUri.getScheme());
- {$IFDEF DEBUG}
- Log.d('---TAndroidHelperEx.FileFromUri-AUri:%s', [JStringToString(AUri.toString)]);
- Log.d('---TAndroidHelperEx.FileFromUri-AUri.Authority:%s-LScheme:%s', [LAuthority, LScheme]);
- {$ENDIF}
- if CheckBuildAndTarget(KITKAT) and TJDocumentsContract.JavaClass.isDocumentUri(Context, AUri) then begin
- if not GetDocId(LDocId, LType, LId) then
- Exit;
- {$IFDEF DEBUG}
- Log.d('---TAndroidHelperEx.FileFromUri-LDocId:%s-LType:%s-LId:%s', [LDocId, LType, LId]);
- {$ENDIF}
- if SameText(LAuthority, 'com.android.externalstorage.documents') then begin
- if SameText(LType, 'primary') then
- Result := TPath.Combine(LSdCard, LId)
- else if SameText(LType, 'home') then
- Result := TPath.Combine(TPath.GetSharedDocumentsPath, LId)
- {$IFDEF DEBUG}
- else
- Log.d('---TAndroidHelperEx.FileFromUri-Unkown externalstorage-LDocId:%s-LType:%s-LId:%s', [LDocId, LType, LId]);
- {$ENDIF}
- end
- else if SameText(LAuthority, 'com.android.providers.media.documents') then begin
- LSelection := StringToJString('_id=' + LId);
- LUri := GetUriByType(LType);
- if LUri <> nil then
- Result := GetDataColumnAsString(LUri, LSelection);
- end else if SameText(LAuthority, 'com.android.providers.downloads.documents') then begin
- if SameText(LType, 'raw') then
- Result := Copy(LDocId, 5)
- //else if GetBuildSdkVersion < OREO then begin // 有人说O的时候不需要自己解析,但测试锤子手机7.1,不行
- else begin
- SetLength(LArr, 2);
- LArr[0] := 'content://downloads/public_downloads';
- LArr[1] := 'content://downloads/my_downloads';
- //LArr[2] := 'content://downloads/all_downloads'; // 这个貌似没权限
- iId := StrToInt64Def(LId, -1);
- for I := 0 to Length(LArr) - 1 do begin
- LUri := TJContentUris.JavaClass.withAppendedId(UriParse(LArr[I]), iId);
- if LUri <> nil then
- try
- Result := GetDataColumnAsString(LUri);
- if Result <> '' then
- Break;
- except
- on E: Exception do begin
- {$IFDEF DEBUG}
- Log.d('---TAndroidHelperEx.FileFromUri Error: [%s]%s', [E.ClassName, E.Message]);
- {$ENDIF}
- end;
- end;
- end;
- end;
- //else
- if Result = '' then
- Result := GetDataColumnAsString(AUri);
- end
- {$IFDEF DEBUG}
- else
- Log.d('---TAndroidHelperEx.FileFromUri-Unkown DocumentUri-');
- {$ENDIF}
- end else if SameText(LScheme, 'content') then begin
- // Return the remote address
- if SameText(LAuthority, 'com.google.android.apps.photos.content') then
- Result := JStringToString(AUri.getLastPathSegment())
- else if SameText(LAuthority, 'com.tencent.mtt.fileprovider') then begin
- LPath := JStringToString(AUri.getPath());
- if Pos('/QQBrowser/', LPath) = 1 then begin // /QQBrowser/XXX
- LPath := TPath.Combine(LSdCard, Copy(LPath, 12));
- if FileExists(LPath) then
- Result := LPath;
- end;
- end
- else if SameText(LAuthority, 'com.speedsoftware.explorer.fileprovider') then begin
- LPath := JStringToString(AUri.getPath());
- if Pos('/root/', LPath) = 1 then
- Result := Copy(LPath, 6);
- end
- else if SameText(LAuthority, 'com.estrongs.files') then
- Result := JStringToString(AUri.getPath())
- else
- Result := GetDataColumnAsString(AUri);
- end
- else if SameText(LScheme, 'file') then
- Result := JStringToString(AUri.getPath())
- {$IFDEF DEBUG}
- else
- Log.d('---TAndroidHelperEx.FileFromUri-Unkown Uri-');
- {$ENDIF}
- 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, Context.getClassLoader);
- end;
- class function TAndroidHelperEx.GetColumnAsString(const AUri: Jnet_Uri; const AColumn: JString;
- ASelection: JString; ASelectionArgs: TJavaObjectArray<JString>; ASortOrder: JString): string;
- var
- LCursor: JCursor;
- LIndex: Integer;
- LPojection: TJavaObjectArray<JString>;
- begin
- Result := '';
- if AUri = nil then
- Exit;
- LPojection := TJavaObjectArray<JString>.Create(1);
- LPojection.Items[0] := AColumn;
- LCursor := Context.getContentResolver().query(AUri, LPojection, ASelection, ASelectionArgs, ASortOrder);
- if LCursor = nil then begin
- {$IFDEF DEBUG}
- Log.d('---TAndroidHelperEx.GetColumnAsString-LCursor = nil-');
- {$ENDIF}
- Exit;
- end;
- try
- LIndex := LCursor.getColumnIndex(AColumn);
- if (LIndex > -1) and LCursor.moveToFirst then
- Result := JStringToString(LCursor.getString(LIndex))
- {$IFDEF DEBUG}
- else
- Log.d('---TAndroidHelperEx.GetColumnAsString-LIndex:%d-', [LIndex]);
- {$ENDIF}
- finally
- LCursor.close;
- end;
- end;
- class function TAndroidHelperEx.GetDataColumnAsString(const AUri: Jnet_Uri;
- ASelection: JString; ASelectionArgs: TJavaObjectArray<JString>;
- ASortOrder: JString): string;
- begin
- Result := GetColumnAsString(AUri, StringToJString('_data'), ASelection, ASelectionArgs, ASortOrder);
- end;
- class function TAndroidHelperEx.GetDefaultIconID: Integer;
- begin
- Result := 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.GetJActivityManager: JActivityManager;
- var
- AService: JObject;
- begin
- AService := Context.getSystemService(TJContext.JavaClass.ACTIVITY_SERVICE);
- Result := TJActivityManager.Wrap((AService as ILocalObject).GetObjectID);
- end;
- class function TAndroidHelperEx.GetJContext: JContext;
- begin
- Result :=
- {$IF CompilerVersion > 27}
- TAndroidHelper.Context;
- {$ELSE}
- SharedActivityContext;
- {$ENDIF}
- end;
- class function TAndroidHelperEx.GetMimeType(AFileName: string): JString;
- var
- LExt: string;
- LTypeMap: JMimeTypeMap;
- begin
- Result := nil;
- if AFileName = '' then
- Exit;
- LExt := LowerCase(ExtractFileExt(AFileName));
- if Length(LExt) < 2 then
- Exit;
- LExt := Copy(LExt, 1);
- LTypeMap := TJMimeTypeMap.JavaClass.getSingleton();
- if LTypeMap = nil then
- Exit;
- Result := LTypeMap.getMimeTypeFromExtension(StringToJString(LExt));
- if Result <> nil then
- Result := Result.trim();
- end;
- class function TAndroidHelperEx.GetPackageLabel: string;
- var
- LApplicationInfo: JApplicationInfo;
- LLabel: JCharSequence;
- begin
- Result := '';
- try
- LApplicationInfo := Context.getPackageManager.getApplicationInfo(Context.getPackageName, 0);
- if LApplicationInfo <> nil then begin
- LLabel := Context.getPackageManager.getApplicationLabel(LApplicationInfo);
- if LLabel <> nil then
- Result := JCharSequenceToStr(LLabel);
- end;
- except
- end;
- end;
- class function TAndroidHelperEx.GetPackageName: string;
- begin
- Result := JStringToString(Context.getPackageName);
- end;
- class function TAndroidHelperEx.GetSDCardPath: string;
- var
- sPath: string;
- begin
- Result := '';
- sPath := System.IOUtils.TPath.GetSharedDocumentsPath;
- if Pos(PathDelim, sPath) = 0 then
- Exit;
- Result := ExtractFilePath(ExcludeTrailingPathDelimiter(sPath));
- end;
- class function TAndroidHelperEx.GetTargetSdkVersion: Integer;
- var
- LApplicationInfo: JApplicationInfo;
- begin
- try
- LApplicationInfo := Context.getPackageManager.getApplicationInfo(Context.getPackageName, 0);
- if LApplicationInfo <> nil then
- Result := LApplicationInfo.targetSdkVersion
- else
- Result := -1;
- except
- Result := -1;
- end;
- end;
- class function TAndroidHelperEx.HasAssocApp(const Intent: JIntent): Boolean;
- var
- LList: JList;
- begin
- Result := False;
- if Intent = nil then
- Exit;
- Result := Intent.resolveActivityInfo(Activity.getPackageManager(),
- TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY) <> nil;
- // Android 6+ APP LINK closed Will cause list is null.
- // Activity with <action android:name="android.intent.action.VIEW" />
- // 被第三方软件套用的时候,比如应用隐藏大师,会导致这里size不正确
- // LList := Activity.getPackageManager.queryIntentActivities(Intent,
- // TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY);
- // Result := (LList = nil) or (LList.size > 0);
- end;
- class function TAndroidHelperEx.HasAssocApp(const URI: string): Boolean;
- var
- Intent: JIntent;
- begin
- Result := False;
- if URI = '' then
- Exit;
- Intent := TJIntent.Create;
- Intent.setData(UriParse(URI));
- Intent.setAction(StringToJString('android.intent.action.VIEW'));
- Result := HasAssocApp(Intent);
- end;
- class function TAndroidHelperEx.InstallPackage(const AFileName, AAuthority: string): Boolean;
- var
- LIntent: JIntent;
- begin
- Result := False;
- if Trim(AFileName) = '' then
- Exit;
- LIntent := TJIntent.Create;
- if CheckBuildAndTarget(OREO) then
- LIntent.setAction(TJIntent.JavaClass.ACTION_INSTALL_PACKAGE)
- else
- LIntent.setAction(TJIntent.JavaClass.ACTION_VIEW);
- // 没有这个也可以安装成功,但是安装成功后的成功页面,也就是,完成/打开 会无法显示
- LIntent.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
- LIntent.setDataAndType(SharedUriFromFile(AFileName, AAuthority),
- StringToJString('application/vnd.android.package-archive'));
- LIntent.addFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
- Result := StartActivity(LIntent);
- end;
- class function TAndroidHelperEx.IsActivityForeground: Boolean;
- var
- LService: JObject;
- LRunningApps: JList;
- LAppInfo: JActivityManager_RunningAppProcessInfo;
- I: Integer;
- begin
- Result := False;
- LService := 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(Context.getPackageName) then
- Exit(True);
- end
- else if LRunningApps.size = 1 then
- Exit(True);
- end;
- end;
- end;
- class function TAndroidHelperEx.IsAppInstalled(const APackage: string): Boolean;
- begin
- Result := False;
- try
- //只有异常是可靠的,返回值判定不对
- Result := Context.getPackageManager.getPackageInfo(StringToJString(APackage),
- TJPackageManager.JavaClass.GET_ACTIVITIES) = nil;
- Result := True;
- except
- end;
- end;
- class function TAndroidHelperEx.KeepScreen(AOn: Boolean): Boolean;
- begin
- CallInUIThreadAndWaitFinishing(
- procedure begin
- if AOn then
- SharedActivity.getWindow.addFlags(
- TJWindowManager_LayoutParams.JavaClass.FLAG_KEEP_SCREEN_ON)
- else
- SharedActivity.getWindow.clearFlags(
- TJWindowManager_LayoutParams.JavaClass.FLAG_KEEP_SCREEN_ON);
- end);
- end;
- class procedure TAndroidHelperEx.SendAppToBack;
- begin
- //SharedActivityManager.moveTaskToBack(Activity.getTaskId, TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
- Activity.moveTaskToBack(True);
- end;
- class function TAndroidHelperEx.StartActivity(Intent: JIntent; const Code: Integer): Boolean;
- begin
- Result := False;
- if Code = -1 then
- Activity.startActivity(Intent)
- else
- Activity.startActivityForResult(Intent, Code);
- Result := True;
- end;
- class function TAndroidHelperEx.UriParse(const S: JString): Jnet_Uri;
- begin
- Result := TJnet_Uri.JavaClass.parse(S);
- end;
- class function TAndroidHelperEx.UriParse(const S: string): Jnet_Uri;
- begin
- Result := UriParse(StringToJString(S));
- end;
- class function TAndroidHelperEx.UriFromFile(const AFileName: string): Jnet_Uri;
- begin
- Result := UriFromFile(TJFile.JavaClass.init(StringToJString(AFileName)));
- end;
- class function TAndroidHelperEx.UriFromFile(const AFile: JFile): Jnet_Uri;
- begin
- Result := TJnet_uri.JavaClass.fromFile(AFile);
- end;
- class function TAndroidHelperEx.SharedUriFromFile(const AFile: JFile; const AAuthority: string): Jnet_Uri;
- var
- LAuthority: JString;
- begin
- if CheckBuildAndTarget(NOUGAT) then begin
- if AAuthority <> '' then
- LAuthority := StringToJString(AAuthority)
- else
- LAuthority := Context.getApplicationContext.getPackageName.concat(StringToJString('.fileprovider'));
- Result := TJFileProvider.JavaClass.getUriForFile(Context, LAuthority, AFile);
- end
- else
- Result := TJnet_uri.JavaClass.fromFile(AFile);
- end;
- class function TAndroidHelperEx.SharedUriFromFile(const AFileName, AAuthority: string): Jnet_Uri;
- begin
- Result := SharedUriFromFile(TJFile.JavaClass.init(StringToJString(AFileName)), AAuthority);
- end;
- end.
|