Explorar el Código

add InstallPackage & GetMimeType

KngStr hace 5 años
padre
commit
fa15747d5e
Se han modificado 1 ficheros con 66 adiciones y 23 borrados
  1. 66 23
      ksAndroid.Helpers.pas

+ 66 - 23
ksAndroid.Helpers.pas

@@ -16,6 +16,7 @@ unit ksAndroid.Helpers;
 interface
 
 uses
+  System.SysUtils,
   Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.App,
   Androidapi.JNI.JavaTypes, Androidapi.JNI.Net;
 
@@ -80,14 +81,14 @@ type
     /// <remarks>
     ///   Use this only when accessing files with an "external" URI
     /// </remarks>
-    class function UriFromFile(const AFile: JFile): Jnet_Uri; static;
+    class function UriFromFile(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 UriFromFileName(const AFileName: string): Jnet_Uri; static;
+    class function UriFromFile(const AFileName: string; const AAuthority: string = ''): Jnet_Uri; overload; static;
 
     /// <summary>Returns Java Application Context</summary>
     class property Context: JContext read GetJContext;
@@ -106,12 +107,19 @@ type
 
     /// <summary>Returns Application package name</summary>
     class function GetPackageName: string; static;
+    /// <summary>Returns MimeType from filename</summary>
+    class function GetMimeType(AFileName: string): JString; 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;
 
@@ -122,10 +130,9 @@ type
 implementation
 
 uses
-  Androidapi.Helpers, Androidapi.JNIBridge,
-  Androidapi.JNI.Os, Androidapi.JNI.Support,
-  Androidapi.JNI.Media, Androidapi.JNI.Provider,
-  FMX.Helpers.Android;
+  Androidapi.JNIBridge, Androidapi.JNI.Os, Androidapi.JNI.Support,
+  Androidapi.JNI.Media, Androidapi.JNI.Provider, Androidapi.JNI.Webkit,
+  FMX.Helpers.Android, Androidapi.Helpers;
 
 { TAndroidHelperEx }
 
@@ -187,6 +194,24 @@ begin
 {$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));
+end;
+
 class function TAndroidHelperEx.GetPackageName: string;
 begin
   Result := JStringToString(Context.getPackageName);
@@ -202,8 +227,8 @@ end;
 
 class function TAndroidHelperEx.HasAssocApp(const Intent: JIntent): Boolean;
 begin
-  Result :=  TAndroidHelper.Activity.getPackageManager.queryIntentActivities(
-    Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0;
+  Result :=  Activity.getPackageManager.queryIntentActivities(Intent,
+    TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0;
 end;
 
 class function TAndroidHelperEx.HasAssocApp(const URI: string): Boolean;
@@ -217,6 +242,26 @@ begin
   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(UriFromFile(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;
@@ -227,13 +272,10 @@ 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
+  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.importance = 100 then begin
+      if LAppInfo.importanceReasonComponent <> nil then begin
         if LAppInfo.importanceReasonComponent.getPackageName.equals(Context.getPackageName) then
           Exit(True);
       end
@@ -248,7 +290,7 @@ begin
   Result := False;
   try
     //只有异常是可靠的,返回值判定不对
-    Result := Context.getPackageManager.getPackageInfo(StringToJString(S),
+    Result := Context.getPackageManager.getPackageInfo(StringToJString(APackage),
       TJPackageManager.JavaClass.GET_ACTIVITIES) = nil;
     Result := True;
   except
@@ -258,8 +300,7 @@ end;
 class function TAndroidHelperEx.KeepScreen(AOn: Boolean): Boolean;
 begin
   CallInUIThreadAndWaitFinishing(
-    procedure
-    begin
+    procedure begin
       if AOn then
         SharedActivity.getWindow.addFlags(
           TJWindowManager_LayoutParams.JavaClass.FLAG_KEEP_SCREEN_ON)
@@ -289,22 +330,24 @@ begin
   end;
 end;
 
-class function TAndroidHelperEx.UriFromFile(const AFile: JFile): Jnet_Uri;
+class function TAndroidHelperEx.UriFromFile(const AFile: JFile; const AAuthority: string): Jnet_Uri;
 var
   LAuthority: JString;
 begin
-  if CheckBuildAndTarget(NOUGAT) then
-  begin
-    LAuthority := StringToJString(JStringToString(Context.getApplicationContext.getPackageName) + '.fileprovider');
+  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.UriFromFileName(const AFileName: string): Jnet_Uri;
+class function TAndroidHelperEx.UriFromFile(const AFileName, AAuthority: string): Jnet_Uri;
 begin
-  Result := UriFromFile(TJFile.JavaClass.init(StringToJString(AFileName)));
+  Result := UriFromFile(TJFile.JavaClass.init(StringToJString(AFileName)), AAuthority);
 end;
 
 end.