Compare commits

..

11 Commits

Author SHA1 Message Date
Imran
0e2a0b65ec Merge pull request #1990 from ImranR98/dev
- Improved XAPK Support (#682)
- Custom user-agent for APKMirror (as per feedback in #1973)
- Minor change to German translation (#1986)
2024-11-23 16:31:46 -05:00
Imran Remtulla
5b79f399d1 Minor change to German translation (#1986) 2024-11-23 16:29:10 -05:00
Imran Remtulla
2961d5ac17 Merge remote-tracking branch 'origin/main' into dev 2024-11-23 16:27:21 -05:00
Imran Remtulla
4af4160aaa Increment version 2024-11-23 16:27:11 -05:00
Imran Remtulla
327f73cc9e More changes for XAPK support (#682) 2024-11-23 16:26:11 -05:00
Imran Remtulla
e82170fec6 Improved XAPK Support (#682) 2024-11-23 16:05:02 -05:00
Imran Remtulla
8922b1c048 Custom user-agent for APKMirror (as per feedback in #1973) 2024-11-23 15:26:58 -05:00
Imran
e9550c6ff0 Merge pull request #1980 from Hamster45105/wiki-links
Update wiki links
2024-11-23 01:53:07 -05:00
Hamish
890c3682c4 Update wiki links 2024-11-23 17:17:04 +11:00
Imran
a2c38968e1 Merge pull request #1977 from summoner001/main
Update hu.json
2024-11-15 13:14:29 -05:00
summoner001
a9c3ee4c54 Update hu.json
Correcting translation.
2024-11-15 14:34:01 +01:00
11 changed files with 91 additions and 42 deletions

View File

@@ -7,7 +7,7 @@ Get Android app updates straight from the source.
Obtainium allows you to install and update apps directly from their releases pages, and receive notifications when new releases are made available. Obtainium allows you to install and update apps directly from their releases pages, and receive notifications when new releases are made available.
More info: More info:
- [Obtainium Wiki](https://github.com/ImranR98/Obtainium/wiki) - [Obtainium Wiki](https://wiki.obtainium.imranr.dev/) ([repository](https://github.com/ImranR98/Obtainium-Wiki))
- [AppVerifier](https://github.com/soupslurpr/AppVerifier) - App verification tool (recommended, integrates with Obtainium) - [AppVerifier](https://github.com/soupslurpr/AppVerifier) - App verification tool (recommended, integrates with Obtainium)
- [apps.obtainium.imranr.dev](https://apps.obtainium.imranr.dev/) - Crowdsourced app configurations ([repository](https://github.com/ImranR98/apps.obtainium.imranr.dev)) - [apps.obtainium.imranr.dev](https://apps.obtainium.imranr.dev/) - Crowdsourced app configurations ([repository](https://github.com/ImranR98/apps.obtainium.imranr.dev))
- [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0) - Original motivation for this app - [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0) - Original motivation for this app

View File

@@ -114,7 +114,7 @@
"light": "Hell", "light": "Hell",
"followSystem": "System folgen", "followSystem": "System folgen",
"followSystemThemeExplanation": "Das Folgen des Systemthemes ist unter Android < 10 nur mit Hilfe von Drittanbieterapps möglich", "followSystemThemeExplanation": "Das Folgen des Systemthemes ist unter Android < 10 nur mit Hilfe von Drittanbieterapps möglich",
"useBlackTheme": "Pure Black Dark Theme verwenden", "useBlackTheme": "Rein schwarzen Hintergrund verwenden",
"appSortBy": "App sortieren nach", "appSortBy": "App sortieren nach",
"authorName": "Autor/Name", "authorName": "Autor/Name",
"nameAuthor": "Name/Autor", "nameAuthor": "Name/Autor",

View File

@@ -213,7 +213,7 @@
"releaseDateAsVersion": "Használja a kiadás dátumát verzió-karakterláncként", "releaseDateAsVersion": "Használja a kiadás dátumát verzió-karakterláncként",
"releaseTitleAsVersion": "Használja a kiadás címét verzió-karakterláncként", "releaseTitleAsVersion": "Használja a kiadás címét verzió-karakterláncként",
"releaseDateAsVersionExplanation": "Ezt a beállítást csak olyan alkalmazásoknál szabad használni, ahol a verzió-érzékelés nem működik megfelelően, de elérhető a kiadás dátuma.", "releaseDateAsVersionExplanation": "Ezt a beállítást csak olyan alkalmazásoknál szabad használni, ahol a verzió-érzékelés nem működik megfelelően, de elérhető a kiadás dátuma.",
"changes": "Változásnapló", "changes": "Változáslista",
"releaseDate": "Kiadás dátuma", "releaseDate": "Kiadás dátuma",
"importFromURLsInFile": "Importálás fájlban található webcímből (pl. OPML)", "importFromURLsInFile": "Importálás fájlban található webcímből (pl. OPML)",
"versionDetectionExplanation": "A verzió-karakterlánc egyeztetése az rendszer által érzékelt verzióval", "versionDetectionExplanation": "A verzió-karakterlánc egyeztetése az rendszer által érzékelt verzióval",

View File

@@ -1,5 +1,5 @@
<p>Obtainium allows you to install and update Apps directly from their releases pages, and receive notifications when new releases are made available.</p> <p>Obtainium allows you to install and update Apps directly from their releases pages, and receive notifications when new releases are made available.</p>
<p>Read the <a href="https://github.com/ImranR98/Obtainium/wiki">Wiki</a></p> <p>Read the <a href="https://wiki.obtainium.imranr.dev/">Wiki</a></p>
<p> <p>
<b>Currently supported App sources:</b> <b>Currently supported App sources:</b>
</p> </p>

View File

@@ -1,5 +1,5 @@
<p>Obtainium позволяет вам устанавливать и обновлять приложения прямо с их объявлений о выпусках и получать уведомления о новых выпусках.</p> <p>Obtainium позволяет вам устанавливать и обновлять приложения прямо с их объявлений о выпусках и получать уведомления о новых выпусках.</p>
<p>Для деталей читайте <a href="https://github.com/ImranR98/Obtainium/wiki">Вики</a></p> <p>Для деталей читайте <a href="https://wiki.obtainium.imranr.dev/">Вики</a></p>
<p> <p>
<b>Поддерживаемые источники приложений:</b> <b>Поддерживаемые источники приложений:</b>
</p> </p>

View File

@@ -5,6 +5,8 @@ import 'package:html/parser.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/providers/apps_provider.dart';
import 'package:obtainium/providers/settings_provider.dart';
import 'package:obtainium/providers/source_provider.dart'; import 'package:obtainium/providers/source_provider.dart';
class APKMirror extends AppSource { class APKMirror extends AppSource {
@@ -31,6 +33,16 @@ class APKMirror extends AppSource {
]; ];
} }
@override
Future<Map<String, String>?> getRequestHeaders(
Map<String, dynamic> additionalSettings,
{bool forAPKDownload = false}) async {
return {
"User-Agent":
"Obtainium/${(await getInstalledInfo(obtainiumId))?.versionName ?? '1.0.0'}"
};
}
@override @override
String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) { String sourceSpecificStandardizeURL(String url, {bool forSelection = false}) {
RegExp standardUrlRegEx = RegExp( RegExp standardUrlRegEx = RegExp(

View File

@@ -105,11 +105,7 @@ class APKPure extends AppSource {
.map((e) => e.text.trim()) .map((e) => e.text.trim())
.map((t) => t == 'APKs' ? 'APK' : t) ?? .map((t) => t == 'APKs' ? 'APK' : t) ??
[]; [];
String type = types.isEmpty String type = types.isEmpty ? 'APK' : types.first;
? 'APK'
: types.length == 1
? types.first
: types.last;
String? dateString = apkInfo String? dateString = apkInfo
?.querySelector('div.info-bottom span.time') ?.querySelector('div.info-bottom span.time')
?.text ?.text

View File

@@ -886,7 +886,7 @@ class _SettingsPageState extends State<SettingsPage> {
), ),
IconButton( IconButton(
onPressed: () { onPressed: () {
launchUrlString('${settingsProvider.sourceUrl}/wiki', launchUrlString('https://wiki.obtainium.imranr.dev/',
mode: LaunchMode.externalApplication); mode: LaunchMode.externalApplication);
}, },
icon: const Icon(Icons.help_outline_rounded), icon: const Icon(Icons.help_outline_rounded),

View File

@@ -516,11 +516,29 @@ class AppsProvider with ChangeNotifier {
.listSync() .listSync()
.where((e) => e.path.toLowerCase().endsWith('.apk')) .where((e) => e.path.toLowerCase().endsWith('.apk'))
.toList(); .toList();
FileSystemEntity? temp;
apks.removeWhere((element) {
bool res = element.uri.pathSegments.last.startsWith(app.id);
if (res) {
temp = element;
}
return res;
});
if (temp != null) {
apks = [
temp!,
...apks,
];
}
for (var i = 0; i < apks.length; i++) { for (var i = 0; i < apks.length; i++) {
try { try {
newInfo = await pm.getPackageArchiveInfo( newInfo =
archiveFilePath: apks.first.path); await pm.getPackageArchiveInfo(archiveFilePath: apks[i].path);
break; if (newInfo != null) {
break;
}
} catch (e) { } catch (e) {
if (i == apks.length - 1) { if (i == apks.length - 1) {
rethrow; rethrow;
@@ -644,28 +662,47 @@ class AppsProvider with ChangeNotifier {
var somethingInstalled = false; var somethingInstalled = false;
try { try {
MultiAppMultiError errors = MultiAppMultiError(); MultiAppMultiError errors = MultiAppMultiError();
List<File> APKFiles = [];
for (var file in dir.extracted for (var file in dir.extracted
.listSync(recursive: true, followLinks: false) .listSync(recursive: true, followLinks: false)
.whereType<File>()) { .whereType<File>()) {
if (file.path.toLowerCase().endsWith('.apk')) { if (file.path.toLowerCase().endsWith('.apk')) {
try { APKFiles.add(file);
somethingInstalled = somethingInstalled ||
await installApk(
DownloadedApk(dir.appId, file), firstTimeWithContext,
needsBGWorkaround: needsBGWorkaround,
shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay);
} catch (e) {
logs.add(
'Could not install APK from XAPK \'${file.path}\': ${e.toString()}');
errors.add(dir.appId, e, appName: apps[dir.appId]?.name);
}
} else if (file.path.toLowerCase().endsWith('.obb')) { } else if (file.path.toLowerCase().endsWith('.obb')) {
await moveObbFile(file, dir.appId); await moveObbFile(file, dir.appId);
} }
} }
if (somethingInstalled) {
File? temp;
APKFiles.removeWhere((element) {
bool res = element.uri.pathSegments.last.startsWith(dir.appId);
if (res) {
temp = element;
}
return res;
});
if (temp != null) {
APKFiles = [
temp!,
...APKFiles,
];
}
try {
await installApk(
DownloadedApk(dir.appId, APKFiles[0]), firstTimeWithContext,
needsBGWorkaround: needsBGWorkaround,
shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay,
additionalAPKs: APKFiles.sublist(1)
.map((a) => DownloadedApk(dir.appId, a))
.toList());
somethingInstalled = true;
dir.file.delete(recursive: true); dir.file.delete(recursive: true);
} else if (errors.idsByErrorString.isNotEmpty) { } catch (e) {
logs.add('Could not install APKs from XAPK: ${e.toString()}');
errors.add(dir.appId, e, appName: apps[dir.appId]?.name);
}
if (errors.idsByErrorString.isNotEmpty) {
throw errors; throw errors;
} }
} finally { } finally {
@@ -677,7 +714,8 @@ class AppsProvider with ChangeNotifier {
Future<bool> installApk( Future<bool> installApk(
DownloadedApk file, BuildContext? firstTimeWithContext, DownloadedApk file, BuildContext? firstTimeWithContext,
{bool needsBGWorkaround = false, {bool needsBGWorkaround = false,
bool shizukuPretendToBeGooglePlay = false}) async { bool shizukuPretendToBeGooglePlay = false,
List<DownloadedApk> additionalAPKs = const []}) async {
if (firstTimeWithContext != null && if (firstTimeWithContext != null &&
settingsProvider.beforeNewInstallsShareToAppVerifier && settingsProvider.beforeNewInstallsShareToAppVerifier &&
(await getInstalledInfo('dev.soupslurpr.appverifier')) != null) { (await getInstalledInfo('dev.soupslurpr.appverifier')) != null) {
@@ -693,6 +731,7 @@ class AppsProvider with ChangeNotifier {
if (newInfo == null) { if (newInfo == null) {
try { try {
file.file.deleteSync(recursive: true); file.file.deleteSync(recursive: true);
additionalAPKs.forEach((a) => a.file.deleteSync(recursive: true));
} catch (e) { } catch (e) {
// //
} finally { } finally {
@@ -720,8 +759,10 @@ class AppsProvider with ChangeNotifier {
} }
int? code; int? code;
if (!settingsProvider.useShizuku) { if (!settingsProvider.useShizuku) {
code = var allAPKs = [file.file.path];
await AndroidPackageInstaller.installApk(apkFilePath: file.file.path); allAPKs.addAll(additionalAPKs.map((a) => a.file.path));
code = await AndroidPackageInstaller.installApk(
apkFilePath: allAPKs.join(','));
} else { } else {
code = await ShizukuApkInstaller.installAPK(file.file.uri.toString(), code = await ShizukuApkInstaller.installAPK(file.file.uri.toString(),
shizukuPretendToBeGooglePlay ? "com.android.vending" : ""); shizukuPretendToBeGooglePlay ? "com.android.vending" : "");

View File

@@ -14,7 +14,7 @@ packages:
description: description:
path: "." path: "."
ref: main ref: main
resolved-ref: ba2aa7a11edc2649d1d80c25ed9291521262f714 resolved-ref: bcad19e964d377da8816718032e5dbf6dd16ba3a
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"
@@ -449,10 +449,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_markdown name: flutter_markdown
sha256: f0e599ba89c9946c8e051780f0ec99aba4ba15895e0380a7ab68f420046fc44e sha256: "999a4e3cb3e1532a971c86d6c73a480264f6a687959d4887cb4e2990821827e4"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.4+1" version: "0.7.4+2"
flutter_plugin_android_lifecycle: flutter_plugin_android_lifecycle:
dependency: transitive dependency: transitive
description: description:
@@ -731,10 +731,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: permission_handler_html name: permission_handler_html
sha256: af26edbbb1f2674af65a8f4b56e1a6f526156bc273d0e65dd8075fab51c78851 sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.3+2" version: "0.1.3+5"
permission_handler_platform_interface: permission_handler_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -945,10 +945,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: sqflite_common name: sqflite_common
sha256: "4468b24876d673418a7b7147e5a08a715b4998a7ae69227acafaab762e0e5490" sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.4+5" version: "2.5.4+6"
sqflite_darwin: sqflite_darwin:
dependency: transitive dependency: transitive
description: description:
@@ -1145,10 +1145,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_android name: webview_flutter_android
sha256: "86c2d01c37c4578ee46560109cf2e18fb271f0d080a796f09188d0952352e057" sha256: "285cedfd9441267f6cca8843458620b5fda1af75b04f5818d0441acda5d7df19"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.1.0"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -1161,10 +1161,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_wkwebview name: webview_flutter_wkwebview
sha256: "3be297aa4ca78205abdd284cf55f168c35246c75b3079990ad8ba9d257681a30" sha256: b7e92f129482460951d96ef9a46b49db34bd2e1621685de26e9eaafd9674e7eb
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.16.2" version: "3.16.3"
win32: win32:
dependency: transitive dependency: transitive
description: description:

View File

@@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.1.31+2288 version: 1.1.32+2289
environment: environment:
sdk: '>=3.0.0 <4.0.0' sdk: '>=3.0.0 <4.0.0'