mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-25 20:03:44 +02:00 
			
		
		
		
	Probably fixed
This commit is contained in:
		| @@ -105,8 +105,6 @@ dependencies { | |||||||
|     implementation "dev.rikka.hidden:compat:$hidden_api_version" |     implementation "dev.rikka.hidden:compat:$hidden_api_version" | ||||||
|     compileOnly "dev.rikka.hidden:stub:$hidden_api_version" |     compileOnly "dev.rikka.hidden:stub:$hidden_api_version" | ||||||
|     implementation "org.lsposed.hiddenapibypass:hiddenapibypass:4.3" |     implementation "org.lsposed.hiddenapibypass:hiddenapibypass:4.3" | ||||||
|  |  | ||||||
|     implementation "com.github.topjohnwu.libsu:core:5.2.2" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3] | ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3] | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ import android.os.Build | |||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
| import android.os.Process | import android.os.Process | ||||||
| import androidx.annotation.NonNull | import androidx.annotation.NonNull | ||||||
| import com.topjohnwu.superuser.Shell |  | ||||||
| import dev.imranr.obtainium.util.IIntentSenderAdaptor | import dev.imranr.obtainium.util.IIntentSenderAdaptor | ||||||
| import dev.imranr.obtainium.util.IntentSenderUtils | import dev.imranr.obtainium.util.IntentSenderUtils | ||||||
| import dev.imranr.obtainium.util.PackageInstallerUtils | import dev.imranr.obtainium.util.PackageInstallerUtils | ||||||
| @@ -23,13 +22,15 @@ import io.flutter.plugin.common.MethodChannel.Result | |||||||
| import java.io.IOException | import java.io.IOException | ||||||
| import java.util.concurrent.CountDownLatch | import java.util.concurrent.CountDownLatch | ||||||
| import org.lsposed.hiddenapibypass.HiddenApiBypass | import org.lsposed.hiddenapibypass.HiddenApiBypass | ||||||
|  | import kotlinx.coroutines.async | ||||||
|  | import kotlinx.coroutines.GlobalScope | ||||||
| import rikka.shizuku.Shizuku | import rikka.shizuku.Shizuku | ||||||
| import rikka.shizuku.Shizuku.OnRequestPermissionResultListener | import rikka.shizuku.Shizuku.OnRequestPermissionResultListener | ||||||
| import rikka.shizuku.ShizukuBinderWrapper | import rikka.shizuku.ShizukuBinderWrapper | ||||||
|  |  | ||||||
| class MainActivity: FlutterActivity() { | class MainActivity: FlutterActivity() { | ||||||
|     private var nativeChannel: MethodChannel? = null |     private var nativeChannel: MethodChannel? = null | ||||||
|     private val SHIZUKU_PERMISSION_REQUEST_CODE = (10..200).random() |     private val SHIZUKU_PERMISSION_REQUEST_CODE = 1492 | ||||||
|  |  | ||||||
|     private fun shizukuCheckPermission(result: Result) { |     private fun shizukuCheckPermission(result: Result) { | ||||||
|         try { |         try { | ||||||
| @@ -43,7 +44,7 @@ class MainActivity: FlutterActivity() { | |||||||
|                 Shizuku.requestPermission(SHIZUKU_PERMISSION_REQUEST_CODE) |                 Shizuku.requestPermission(SHIZUKU_PERMISSION_REQUEST_CODE) | ||||||
|                 result.success(-2) |                 result.success(-2) | ||||||
|             } |             } | ||||||
|         } catch (_: Exception) {  // If shizuku not running |         } catch (_: Exception) {  // If shizuku binder not found | ||||||
|             result.success(-1) |             result.success(-1) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -56,7 +57,7 @@ class MainActivity: FlutterActivity() { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun shizukuInstallApk(apkFileUri: String, result: Result) { |     private suspend fun shizukuInstallApk(apkFileUri: String, result: Result) { | ||||||
|         val uri = Uri.parse(apkFileUri) |         val uri = Uri.parse(apkFileUri) | ||||||
|         var res = false |         var res = false | ||||||
|         var session: PackageInstaller.Session? = null |         var session: PackageInstaller.Session? = null | ||||||
| @@ -129,22 +130,6 @@ class MainActivity: FlutterActivity() { | |||||||
|         result.success(res) |         result.success(res) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun rootCheckPermission(result: Result) { |  | ||||||
|         Shell.getShell(Shell.GetShellCallback( |  | ||||||
|             fun(shell: Shell) { |  | ||||||
|                 result.success(shell.isRoot) |  | ||||||
|             } |  | ||||||
|         )) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun rootInstallApk(apkFilePath: String, result: Result) { |  | ||||||
|         Shell.sh("pm install -r -t " + apkFilePath).submit { out -> |  | ||||||
|             val builder = StringBuilder() |  | ||||||
|             for (data in out.getOut()) { builder.append(data) } |  | ||||||
|             result.success(builder.toString().endsWith("Success")) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { |     override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { | ||||||
|         super.configureFlutterEngine(flutterEngine) |         super.configureFlutterEngine(flutterEngine) | ||||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||||||
| @@ -160,14 +145,9 @@ class MainActivity: FlutterActivity() { | |||||||
|                 result.success(res) |                 result.success(res) | ||||||
|             } else if (call.method == "checkPermissionShizuku") { |             } else if (call.method == "checkPermissionShizuku") { | ||||||
|                 shizukuCheckPermission(result) |                 shizukuCheckPermission(result) | ||||||
|             } else if (call.method == "checkPermissionRoot") { |  | ||||||
|                 rootCheckPermission(result) |  | ||||||
|             } else if (call.method == "installWithShizuku") { |             } else if (call.method == "installWithShizuku") { | ||||||
|                 val apkFileUri: String? = call.argument("apkFileUri") |                 val apkFileUri: String = call.argument("apkFileUri")!! | ||||||
|                 shizukuInstallApk(apkFileUri!!, result) |                 GlobalScope.async { shizukuInstallApk(apkFileUri, result) } | ||||||
|             } else if (call.method == "installWithRoot") { |  | ||||||
|                 val apkFilePath: String? = call.argument("apkFilePath") |  | ||||||
|                 rootInstallApk(apkFilePath!!, result) |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -280,9 +280,7 @@ | |||||||
|     "supportFixedAPKURL": "Support fixed APK URLs", |     "supportFixedAPKURL": "Support fixed APK URLs", | ||||||
|     "selectX": "Select {}", |     "selectX": "Select {}", | ||||||
|     "parallelDownloads": "Allow parallel downloads", |     "parallelDownloads": "Allow parallel downloads", | ||||||
|     "installMethod": "Installation method", |     "useShizuku": "Use Shizuku or Sui to install", | ||||||
|     "normal": "Normal", |  | ||||||
|     "root": "Root", |  | ||||||
|     "shizukuBinderNotFound": "Сompatible Shizuku service wasn't found", |     "shizukuBinderNotFound": "Сompatible Shizuku service wasn't found", | ||||||
|     "useSystemFont": "Use the system font", |     "useSystemFont": "Use the system font", | ||||||
|     "systemFontError": "Error loading the system font: {}", |     "systemFontError": "Error loading the system font: {}", | ||||||
|   | |||||||
| @@ -281,9 +281,7 @@ | |||||||
|     "supportFixedAPKURL": "Поддержка фиксированных URL-адресов APK", |     "supportFixedAPKURL": "Поддержка фиксированных URL-адресов APK", | ||||||
|     "selectX": "Выбрать {}", |     "selectX": "Выбрать {}", | ||||||
|     "parallelDownloads": "Разрешить параллельные загрузки", |     "parallelDownloads": "Разрешить параллельные загрузки", | ||||||
|     "installMethod": "Метод установки", |     "useShizuku": "Использовать Shizuku или Sui для установки", | ||||||
|     "normal": "Нормальный", |  | ||||||
|     "root": "Суперпользователь", |  | ||||||
|     "shizukuBinderNotFound": "Совместимый сервис Shizuku не найден", |     "shizukuBinderNotFound": "Совместимый сервис Shizuku не найден", | ||||||
|     "useSystemFont": "Использовать системный шрифт", |     "useSystemFont": "Использовать системный шрифт", | ||||||
|     "systemFontError": "Ошибка загрузки системного шрифта: {}", |     "systemFontError": "Ошибка загрузки системного шрифта: {}", | ||||||
|   | |||||||
| @@ -30,29 +30,6 @@ class _SettingsPageState extends State<SettingsPage> { | |||||||
|       settingsProvider.initializeSettings(); |       settingsProvider.initializeSettings(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     var installMethodDropdown = DropdownButtonFormField( |  | ||||||
|         decoration: InputDecoration(labelText: tr('installMethod')), |  | ||||||
|         value: settingsProvider.installMethod, |  | ||||||
|         items: [ |  | ||||||
|           DropdownMenuItem( |  | ||||||
|             value: InstallMethodSettings.normal, |  | ||||||
|             child: Text(tr('normal')), |  | ||||||
|           ), |  | ||||||
|           const DropdownMenuItem( |  | ||||||
|             value: InstallMethodSettings.shizuku, |  | ||||||
|             child: Text('Shizuku'), |  | ||||||
|           ), |  | ||||||
|           DropdownMenuItem( |  | ||||||
|             value: InstallMethodSettings.root, |  | ||||||
|             child: Text(tr('root')), |  | ||||||
|           ) |  | ||||||
|         ], |  | ||||||
|         onChanged: (value) { |  | ||||||
|           if (value != null) { |  | ||||||
|             settingsProvider.installMethod = value; |  | ||||||
|           } |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|     var themeDropdown = DropdownButtonFormField( |     var themeDropdown = DropdownButtonFormField( | ||||||
|         decoration: InputDecoration(labelText: tr('theme')), |         decoration: InputDecoration(labelText: tr('theme')), | ||||||
|         value: settingsProvider.theme, |         value: settingsProvider.theme, | ||||||
| @@ -363,7 +340,29 @@ class _SettingsPageState extends State<SettingsPage> { | |||||||
|                                     }) |                                     }) | ||||||
|                               ], |                               ], | ||||||
|                             ), |                             ), | ||||||
|                             installMethodDropdown, |                             height16, | ||||||
|  |                             Row( | ||||||
|  |                               mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                               children: [ | ||||||
|  |                                 Flexible(child: Text(tr('useShizuku'))), | ||||||
|  |                                 Switch( | ||||||
|  |                                     value: settingsProvider.useShizuku, | ||||||
|  |                                     onChanged: (useShizuku) { | ||||||
|  |                                       if (useShizuku) { | ||||||
|  |                                         NativeFeatures.checkPermissionShizuku().then((resCode) { | ||||||
|  |                                           settingsProvider.useShizuku = resCode == 1; | ||||||
|  |                                           if (resCode == 0) { | ||||||
|  |                                             showError(ObtainiumError(tr('cancelled')), context); | ||||||
|  |                                           } else if (resCode == -1) { | ||||||
|  |                                             showError(ObtainiumError(tr('shizukuBinderNotFound')), context); | ||||||
|  |                                           } | ||||||
|  |                                         }); | ||||||
|  |                                       } else { | ||||||
|  |                                         settingsProvider.useShizuku = false; | ||||||
|  |                                       } | ||||||
|  |                                     }) | ||||||
|  |                               ], | ||||||
|  |                             ), | ||||||
|                             height32, |                             height32, | ||||||
|                             Text( |                             Text( | ||||||
|                               tr('sourceSpecific'), |                               tr('sourceSpecific'), | ||||||
|   | |||||||
| @@ -547,8 +547,7 @@ class AppsProvider with ChangeNotifier { | |||||||
|         !(await canDowngradeApps())) { |         !(await canDowngradeApps())) { | ||||||
|       throw DowngradeError(); |       throw DowngradeError(); | ||||||
|     } |     } | ||||||
|     if (needsBGWorkaround && |     if (needsBGWorkaround) { | ||||||
|         settingsProvider.installMethod == InstallMethodSettings.normal) { |  | ||||||
|       // The below 'await' will never return if we are in a background process |       // The below 'await' will never return if we are in a background process | ||||||
|       // To work around this, we should assume the install will be successful |       // To work around this, we should assume the install will be successful | ||||||
|       // So we update the app's installed version first as we will never get to the later code |       // So we update the app's installed version first as we will never get to the later code | ||||||
| @@ -560,20 +559,14 @@ class AppsProvider with ChangeNotifier { | |||||||
|           attemptToCorrectInstallStatus: false); |           attemptToCorrectInstallStatus: false); | ||||||
|     } |     } | ||||||
|     int? code; |     int? code; | ||||||
|     switch (settingsProvider.installMethod) { |     if (!settingsProvider.useShizuku) { | ||||||
|       case InstallMethodSettings.normal: |  | ||||||
|       code = await AndroidPackageInstaller.installApk( |       code = await AndroidPackageInstaller.installApk( | ||||||
|           apkFilePath: file.file.path); |           apkFilePath: file.file.path); | ||||||
|       case InstallMethodSettings.shizuku: |     } else { | ||||||
|       code = (await NativeFeatures.installWithShizuku( |       code = (await NativeFeatures.installWithShizuku( | ||||||
|           apkFileUri: file.file.uri.toString())) |           apkFileUri: file.file.uri.toString())) | ||||||
|           ? 0 |           ? 0 | ||||||
|           : 1; |           : 1; | ||||||
|       case InstallMethodSettings.root: |  | ||||||
|         code = |  | ||||||
|             (await NativeFeatures.installWithRoot(apkFilePath: file.file.path)) |  | ||||||
|                 ? 0 |  | ||||||
|                 : 1; |  | ||||||
|     } |     } | ||||||
|     bool installed = false; |     bool installed = false; | ||||||
|     if (code != null && code != 0 && code != 3) { |     if (code != null && code != 0 && code != 3) { | ||||||
| @@ -732,25 +725,19 @@ class AppsProvider with ChangeNotifier { | |||||||
|         } |         } | ||||||
|         var appId = downloadedFile?.appId ?? downloadedDir!.appId; |         var appId = downloadedFile?.appId ?? downloadedDir!.appId; | ||||||
|         bool willBeSilent = await canInstallSilently(apps[appId]!.app); |         bool willBeSilent = await canInstallSilently(apps[appId]!.app); | ||||||
|         switch (settingsProvider.installMethod) { |         if (!settingsProvider.useShizuku) { | ||||||
|           case InstallMethodSettings.normal: |           if (!(await settingsProvider.getInstallPermission(enforce: false))) { | ||||||
|             if (!(await settingsProvider.getInstallPermission( |  | ||||||
|                 enforce: false))) { |  | ||||||
|             throw ObtainiumError(tr('cancelled')); |             throw ObtainiumError(tr('cancelled')); | ||||||
|           } |           } | ||||||
|           case InstallMethodSettings.shizuku: |         } else { | ||||||
|           int code = await NativeFeatures.checkPermissionShizuku(); |           int code = await NativeFeatures.checkPermissionShizuku(); | ||||||
|             if (code == -1) { |           if (code == 0) { | ||||||
|  |             throw ObtainiumError(tr('cancelled')); | ||||||
|  |           } else if (code == -1) { | ||||||
|             throw ObtainiumError(tr('shizukuBinderNotFound')); |             throw ObtainiumError(tr('shizukuBinderNotFound')); | ||||||
|             } else if (code == 0) { |  | ||||||
|               throw ObtainiumError(tr('cancelled')); |  | ||||||
|             } |  | ||||||
|           case InstallMethodSettings.root: |  | ||||||
|             if (!(await NativeFeatures.checkPermissionRoot())) { |  | ||||||
|               throw ObtainiumError(tr('cancelled')); |  | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         if (!willBeSilent && context != null) { |         if (!willBeSilent && context != null && !settingsProvider.useShizuku) { | ||||||
|           // ignore: use_build_context_synchronously |           // ignore: use_build_context_synchronously | ||||||
|           await waitForUserToReturnToForeground(context); |           await waitForUserToReturnToForeground(context); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -59,17 +59,8 @@ class NativeFeatures { | |||||||
|     return res; |     return res; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static Future<bool> checkPermissionRoot() async { |  | ||||||
|     return await _channel.invokeMethod('checkPermissionRoot'); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static Future<bool> installWithShizuku({required String apkFileUri}) async { |   static Future<bool> installWithShizuku({required String apkFileUri}) async { | ||||||
|     return await _channel.invokeMethod( |     return await _channel.invokeMethod( | ||||||
|         'installWithShizuku', {'apkFileUri': apkFileUri}); |         'installWithShizuku', {'apkFileUri': apkFileUri}); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static Future<bool> installWithRoot({required String apkFilePath}) async { |  | ||||||
|     return await _channel.invokeMethod( |  | ||||||
|         'installWithRoot', {'apkFilePath': apkFilePath}); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,8 +18,6 @@ String obtainiumTempId = 'imranr98_obtainium_${GitHub().hosts[0]}'; | |||||||
| String obtainiumId = 'dev.imranr.obtainium'; | String obtainiumId = 'dev.imranr.obtainium'; | ||||||
| String obtainiumUrl = 'https://github.com/ImranR98/Obtainium'; | String obtainiumUrl = 'https://github.com/ImranR98/Obtainium'; | ||||||
|  |  | ||||||
| enum InstallMethodSettings { normal, shizuku, root } |  | ||||||
|  |  | ||||||
| enum ThemeSettings { system, light, dark } | enum ThemeSettings { system, light, dark } | ||||||
|  |  | ||||||
| enum ColourSettings { basic, materialYou } | enum ColourSettings { basic, materialYou } | ||||||
| @@ -61,13 +59,12 @@ class SettingsProvider with ChangeNotifier { | |||||||
|     notifyListeners(); |     notifyListeners(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   InstallMethodSettings get installMethod { |   bool get useShizuku{ | ||||||
|     return InstallMethodSettings.values[ |     return prefs?.getBool('useShizuku') ?? false; | ||||||
|         prefs?.getInt('installMethod') ?? InstallMethodSettings.normal.index]; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   set installMethod(InstallMethodSettings t) { |   set useShizuku(bool useShizuku) { | ||||||
|     prefs?.setInt('installMethod', t.index); |     prefs?.setBool('useShizuku', useShizuku); | ||||||
|     notifyListeners(); |     notifyListeners(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user