mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-16 14:46:44 +02:00
Don't wait for foreground if install is silent
This commit is contained in:
@ -49,7 +49,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
|
||||||
applicationId "dev.imranr.obtainium"
|
applicationId "dev.imranr.obtainium"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||||
|
@ -7,6 +7,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:android_intent_plus/flag.dart';
|
import 'package:android_intent_plus/flag.dart';
|
||||||
import 'package:android_package_installer/android_package_installer.dart';
|
import 'package:android_package_installer/android_package_installer.dart';
|
||||||
|
import 'package:android_package_manager/android_package_manager.dart';
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -29,6 +30,8 @@ import 'package:http/http.dart';
|
|||||||
import 'package:android_intent_plus/android_intent.dart';
|
import 'package:android_intent_plus/android_intent.dart';
|
||||||
import 'package:flutter_archive/flutter_archive.dart';
|
import 'package:flutter_archive/flutter_archive.dart';
|
||||||
|
|
||||||
|
final pm = AndroidPackageManager();
|
||||||
|
|
||||||
class AppInMemory {
|
class AppInMemory {
|
||||||
late App app;
|
late App app;
|
||||||
double? downloadProgress;
|
double? downloadProgress;
|
||||||
@ -322,16 +325,39 @@ class AppsProvider with ChangeNotifier {
|
|||||||
.isNotEmpty;
|
.isNotEmpty;
|
||||||
|
|
||||||
Future<bool> canInstallSilently(App app) async {
|
Future<bool> canInstallSilently(App app) async {
|
||||||
return false;
|
if (app.apkUrls.length > 1) {
|
||||||
// TODO: Uncomment the below if silent updates are ever figured out
|
// Manual API selection means silent install is not possible
|
||||||
// // NOTE: This is unreliable - try to get from OS in the future
|
return false;
|
||||||
// if (app.apkUrls.length > 1) {
|
}
|
||||||
// return false;
|
|
||||||
// }
|
var osInfo = await DeviceInfoPlugin().androidInfo;
|
||||||
// var osInfo = await DeviceInfoPlugin().androidInfo;
|
String? installerPackageName;
|
||||||
// return app.installedVersion != null &&
|
try {
|
||||||
// osInfo.version.sdkInt >= 30 &&
|
installerPackageName = osInfo.version.sdkInt >= 30
|
||||||
// osInfo.version.release.compareTo('12') >= 0;
|
? (await pm.getInstallSourceInfo(packageName: app.id))
|
||||||
|
?.installingPackageName
|
||||||
|
: (await pm.getInstallerPackageName(packageName: app.id));
|
||||||
|
} catch (e) {
|
||||||
|
// Probably not installed - ignore
|
||||||
|
}
|
||||||
|
if (installerPackageName != obtainiumId) {
|
||||||
|
// If we did not install the app (or it isn't installed), silent install is not possible
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var targetSDK;
|
||||||
|
try {
|
||||||
|
targetSDK = (await pm.getPackageInfo(packageName: app.id))
|
||||||
|
?.applicationInfo
|
||||||
|
?.targetSdkVersion;
|
||||||
|
} catch (e) {
|
||||||
|
// Weird if you get here - ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// The OS must also be new enough and the APK should target a new enough API
|
||||||
|
return osInfo.version.sdkInt >= 30 &&
|
||||||
|
targetSDK != null &&
|
||||||
|
targetSDK >= // https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(int)
|
||||||
|
(osInfo.version.sdkInt - 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> waitForUserToReturnToForeground(BuildContext context) async {
|
Future<void> waitForUserToReturnToForeground(BuildContext context) async {
|
||||||
@ -359,8 +385,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
zipFile: File(filePath), destinationDir: Directory(destinationPath));
|
zipFile: File(filePath), destinationDir: Directory(destinationPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> installXApkDir(DownloadedXApkDir dir,
|
Future<void> installXApkDir(DownloadedXApkDir dir) async {
|
||||||
{bool silent = false}) async {
|
|
||||||
// We don't know which APKs in an XAPK are supported by the user's device
|
// We don't know which APKs in an XAPK are supported by the user's device
|
||||||
// So we try installing all of them and assume success if at least one installed
|
// So we try installing all of them and assume success if at least one installed
|
||||||
// If 0 APKs installed, throw the first install error encountered
|
// If 0 APKs installed, throw the first install error encountered
|
||||||
@ -373,8 +398,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
if (file.path.toLowerCase().endsWith('.apk')) {
|
if (file.path.toLowerCase().endsWith('.apk')) {
|
||||||
try {
|
try {
|
||||||
somethingInstalled = somethingInstalled ||
|
somethingInstalled = somethingInstalled ||
|
||||||
await installApk(DownloadedApk(dir.appId, file),
|
await installApk(DownloadedApk(dir.appId, file));
|
||||||
silent: silent);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logs.add(
|
logs.add(
|
||||||
'Could not install APK from XAPK \'${file.path}\': ${e.toString()}');
|
'Could not install APK from XAPK \'${file.path}\': ${e.toString()}');
|
||||||
@ -394,8 +418,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> installApk(DownloadedApk file, {bool silent = false}) async {
|
Future<bool> installApk(DownloadedApk file) async {
|
||||||
// TODO: Use 'silent' when/if ever possible
|
|
||||||
var newInfo = await PackageArchiveInfo.fromPath(file.file.path);
|
var newInfo = await PackageArchiveInfo.fromPath(file.file.path);
|
||||||
AppInfo? appInfo;
|
AppInfo? appInfo;
|
||||||
try {
|
try {
|
||||||
@ -571,7 +594,6 @@ class AppsProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
bool willBeSilent = await canInstallSilently(
|
bool willBeSilent = await canInstallSilently(
|
||||||
apps[downloadedFile?.appId ?? downloadedDir!.appId]!.app);
|
apps[downloadedFile?.appId ?? downloadedDir!.appId]!.app);
|
||||||
willBeSilent = false; // TODO: Remove this when silent updates work
|
|
||||||
if (!(await settingsProvider?.getInstallPermission(enforce: false) ??
|
if (!(await settingsProvider?.getInstallPermission(enforce: false) ??
|
||||||
true)) {
|
true)) {
|
||||||
throw ObtainiumError(tr('cancelled'));
|
throw ObtainiumError(tr('cancelled'));
|
||||||
@ -584,9 +606,9 @@ class AppsProvider with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
if (downloadedFile != null) {
|
if (downloadedFile != null) {
|
||||||
await installApk(downloadedFile, silent: willBeSilent);
|
await installApk(downloadedFile);
|
||||||
} else {
|
} else {
|
||||||
await installXApkDir(downloadedDir!, silent: willBeSilent);
|
await installXApkDir(downloadedDir!);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
apps[id]?.downloadProgress = null;
|
apps[id]?.downloadProgress = null;
|
||||||
|
@ -26,6 +26,15 @@ packages:
|
|||||||
url: "https://github.com/ImranR98/android_package_installer"
|
url: "https://github.com/ImranR98/android_package_installer"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
|
android_package_manager:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "."
|
||||||
|
ref: master
|
||||||
|
resolved-ref: "5f58196561734d0f499bb844cdb43e7762a8f019"
|
||||||
|
url: "https://github.com/ImranR98/android_package_manager"
|
||||||
|
source: git
|
||||||
|
version: "0.5.4"
|
||||||
animations:
|
animations:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
10
pubspec.yaml
10
pubspec.yaml
@ -1,5 +1,5 @@
|
|||||||
name: obtainium
|
name: obtainium
|
||||||
description: A new Flutter project.
|
description: Get Android App Updates Directly From the Source.
|
||||||
|
|
||||||
# The following line prevents the package from being accidentally published to
|
# The following line prevents the package from being accidentally published to
|
||||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||||
@ -55,9 +55,13 @@ dependencies:
|
|||||||
git:
|
git:
|
||||||
url: https://github.com/ImranR98/android_package_installer
|
url: https://github.com/ImranR98/android_package_installer
|
||||||
ref: main
|
ref: main
|
||||||
|
android_package_manager:
|
||||||
|
git:
|
||||||
|
url: https://github.com/ImranR98/android_package_manager
|
||||||
|
ref: master
|
||||||
share_plus: ^7.0.0
|
share_plus: ^7.0.0
|
||||||
installed_apps: ^1.3.1
|
installed_apps: ^1.3.1 # TODO: Remove when android_package_manager supports getting icon as UInt8List and versionCode
|
||||||
package_archive_info: ^0.1.0
|
package_archive_info: ^0.1.0 # TODO: Remove when android_package_manager supports getting versionCode
|
||||||
android_alarm_manager_plus: ^3.0.0
|
android_alarm_manager_plus: ^3.0.0
|
||||||
sqflite: ^2.2.0+3
|
sqflite: ^2.2.0+3
|
||||||
easy_localization: ^3.0.1
|
easy_localization: ^3.0.1
|
||||||
|
Reference in New Issue
Block a user