Compare commits

...

79 Commits

Author SHA1 Message Date
e8580dc1d5 Merge pull request #1257 from ImranR98/dev
Add F-Droid changelogs (#1255), Fix corrupt pt.json (#1256)
2024-01-07 21:59:17 -05:00
daffff7eb0 Add F-Droid changelogs (#1255) 2024-01-07 21:57:23 -05:00
751fda5e37 Increment version 2024-01-07 21:45:41 -05:00
1e38abc500 Fix corrupt pt.json (#1256) 2024-01-07 21:40:56 -05:00
8e7137815b Merge pull request #1254 from ImranR98/dev
URL parsing bugfix for HTML source (#1253)
2024-01-07 12:37:51 -05:00
4226ee453f Merge remote-tracking branch 'origin/main' into dev 2024-01-07 12:37:14 -05:00
568a110443 Merge pull request #1249 from LilligantMatsuri/main
Update Chinese translation
2024-01-07 12:37:00 -05:00
7fd7a6ca8d Merge pull request #1252 from jont4/main
Translation: many fixes in PT translation
2024-01-07 12:36:47 -05:00
3092c854ff Increment version 2024-01-07 12:36:20 -05:00
a9566f4b23 Remove redundant function call 2024-01-07 12:34:09 -05:00
7a5aa3c11d URL parsing bugfix for HTML source (#1253) 2024-01-07 12:33:06 -05:00
f2454bb028 Translation: many fixes in PT translation 2024-01-07 12:28:24 -03:00
2c1023a6fd Update zh.json
- Add & translate new strings
- Correct inaccurate translations

Signed-off-by: Matsuri <matsuri@vmoe.info>
2024-01-07 16:55:00 +08:00
9187ac6684 Merge pull request #1248 from ImranR98/dev
Removed Steam Source (existing apps auto-switched to HTML) (#1244) + Bugfixes
2024-01-06 23:39:11 -05:00
9640e43bc5 Upgrade packages, increment version 2024-01-06 23:38:36 -05:00
09b24b36f2 Removed Steam Source (existing apps auto-switched to HTML) (#1244) + bugfixes 2024-01-06 23:37:27 -05:00
06a761c0d0 Merge pull request #1247 from CertainBot/main
Update Spanish
2024-01-06 22:46:06 -05:00
6ff7d7fcd7 Merge pull request #1246 from bluefly000/japanese-translation
Update ja.json
2024-01-06 22:45:47 -05:00
0f27c79303 Merge pull request #1243 from pmtpro/patch-1
Update vi.json
2024-01-06 22:45:25 -05:00
9961ad081f Update Spanish
- English: new strings, typos, minor changes
- Español: strings nuevos, correcciones, algunas mejoras
2024-01-07 02:55:18 +01:00
02056b4f78 Update ja.json 2024-01-06 01:05:52 +09:00
0492588c25 Update vi.json 2024-01-04 09:26:37 +07:00
ad8463ac8b Update README.md 2024-01-03 20:28:49 -05:00
7843de240a Merge pull request #1241 from ImranR98/dev
Don't use numpad for version extraction match group
2024-01-03 20:19:18 -05:00
0037a08017 Don't use numpad for version extraction match group 2024-01-03 20:18:59 -05:00
92ba432992 Merge pull request #1240 from ImranR98/dev
- Remove reference to old plugin to avoid crashes (#1221)
- Confirmation box for link-based imports (#1232)
- Construct extracted versions from match groups (#1235)
- Fix the WebView 'cleartext' error caused by HTTP sites (#1235)
- Make GitHub's (and Codeberg's) "fallback" work with the APK filter (#1236)
- Make version extraction universal (#1237)
- HTML Bugfix (#1238)
2024-01-03 20:16:19 -05:00
3a521f4014 Update packages, increment version 2024-01-03 20:13:47 -05:00
e8bbc9799c Fix the WebView 'cleartext' error caused by HTTP sites 2024-01-03 20:11:52 -05:00
96a48b4813 Construct extracted versions from match groups (#1235) 2024-01-03 20:02:44 -05:00
355450e82d Merge duplicate version extraction code into one function 2024-01-03 19:28:45 -05:00
99307c5b0c Make version extraction universal (#1237) 2024-01-03 19:20:03 -05:00
ace8be6514 Remove reference to old plugin to avoid crashes (#1221) 2024-01-03 19:04:36 -05:00
1b538931b1 Confirmation box for link-based imports (#1232) 2024-01-03 19:03:05 -05:00
7ccd08ee2b Make GitHub's (and Codeberg's) "fallback" work with the APK filter (#1236) 2024-01-03 18:32:09 -05:00
104beed594 HTML Bugfix (#1238) 2024-01-03 18:25:02 -05:00
e8df594edb Merge pull request #1233 from iDazai/main
added missing strings in some languages, translated for DE
2024-01-03 18:06:29 -05:00
6e922a84f8 Merge pull request #1230 from re7gog/re7gog
Fixes and system font
2024-01-03 18:06:04 -05:00
b74bf86277 Corrections 2024-01-03 14:39:33 +03:00
6cbe50c9ef Update vi.json 2024-01-02 07:57:32 +01:00
14fcca040b Update tr.json 2024-01-02 07:57:21 +01:00
7bb545cff9 Update sv.json 2024-01-02 07:57:07 +01:00
f52b1a246c Update pl.json 2024-01-02 07:56:41 +01:00
273dfd89cc Update nl.json 2024-01-02 07:56:17 +01:00
52d72d287b Update ja.json 2024-01-02 07:56:01 +01:00
e8d8fcbe69 Update hu.json 2024-01-02 07:55:44 +01:00
30c6c1afd3 Update fr.json 2024-01-02 07:55:16 +01:00
c8c8093b3a Update fa.json 2024-01-02 07:55:03 +01:00
c970b2cf2e Update es.json 2024-01-02 07:54:23 +01:00
0815283d31 Update bs.json 2024-01-02 07:53:32 +01:00
55ee2d93b8 Update de.json
added missing strings and translated
2024-01-02 07:53:07 +01:00
c9e17ed42b Merge branch 'main' into re7gog 2024-01-01 18:50:24 +03:00
76a91b7fe0 Don't load font if loaded 2024-01-01 18:42:38 +03:00
f9b3169b6a Update README.md 2024-01-01 07:55:00 -05:00
4f42b5a3ee Merge pull request #1228 from ImranR98/dev
Save Search Preferences (#1226)
2023-12-31 23:42:22 -05:00
5d9645eaff Save Search Preferences (#1226) 2023-12-31 23:41:46 -05:00
c032808d82 Merge pull request #1227 from ImranR98/dev
- Add www subdomain support for various sources (#1222)
- Disable standard version detection for WhatsApp (should never have been enabled)
2023-12-31 23:29:31 -05:00
282c94266e Merge remote-tracking branch 'origin/main' into dev 2023-12-31 23:28:09 -05:00
e2f7d52bee Increment version 2023-12-31 23:27:23 -05:00
6317f0162a Disable standard version detection for WhatsApp (should never have been enabled) 2023-12-31 22:05:50 -05:00
436a6310d7 Add www subdomain support for various sources (#1222) 2023-12-31 15:59:44 -05:00
0f74195255 Replace okay with ok 2023-12-31 19:42:28 +03:00
5ba33786ab System font and newer dependencies 2023-12-31 19:33:33 +03:00
70fcfc1753 Merge remote-tracking branch 'origin/main' into dev 2023-12-30 10:50:22 -05:00
1e34048c0c Merge pull request #1218 from LilligantMatsuri/main
Update Chinese translation
2023-12-30 10:50:12 -05:00
45b1b23262 Merge pull request #1215 from oSoWoSo/cz
Update cs.json
2023-12-30 10:50:04 -05:00
07842ace4e Merge pull request #1217 from gidano/main
Update hu.json
2023-12-30 10:49:34 -05:00
8e75280093 Merge pull request #1220 from ImranR98/dev
Fix intermediate link bug (#1219)
2023-12-30 10:49:21 -05:00
029b9ef498 Fix intermediate link bug (#1219) 2023-12-30 10:49:05 -05:00
51970abce7 Update zh.json
- Add & translate new strings
- Minor improvements

Signed-off-by: Matsuri <matsuri@vmoe.info>
2023-12-30 16:55:01 +08:00
f6faa19e5f Update hu.json 2023-12-30 09:45:46 +01:00
dd7217ca54 Update cs.json 2023-12-30 04:31:05 +01:00
6e13457eb2 Merge pull request #1210 from iDazai/main
Update de.json
2023-12-29 12:44:09 -06:00
3b319ee19b Merge pull request #1206 from gidano/main
Update hu.json
2023-12-29 12:44:02 -06:00
8ea8daa811 Merge pull request #1212 from ImranR98/dev
HTML intermediate link bugfix (#1211)
2023-12-29 12:43:49 -06:00
eb29b908c2 Increment version 2023-12-29 13:43:06 -05:00
9935cb482e HTML intermediate link bugfix (#1211) 2023-12-29 13:39:56 -05:00
0d6e7181cf Update de.json 2023-12-29 17:35:25 +01:00
d225650e15 Update hu.json 2023-12-29 10:12:13 +01:00
1fc8ee6fee Fix all 2023-12-28 17:50:12 +03:00
49 changed files with 882 additions and 596 deletions

View File

@ -1,12 +1,14 @@
# ![Obtainium Icon](./assets/graphics/icon_small.png) Obtainium # ![Obtainium Icon](./assets/graphics/icon_small.png) Obtainium
[![Ceasefire Now](https://badge.techforpalestine.org/default)](https://techforpalestine.org/learn-more)
Get Android App Updates Directly From the Source. Get Android App Updates Directly 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.
Motivation: [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0) Motivation: [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0)
Wiki: [https://github.com/ImranR98/Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki) Read the Wiki: [https://github.com/ImranR98/Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki)
Currently supported App sources: Currently supported App sources:
- Open Source - General: - Open Source - General:
@ -30,8 +32,8 @@ Currently supported App sources:
- [Signal](https://signal.org/) - [Signal](https://signal.org/)
- [VLC](https://videolan.org/) - [VLC](https://videolan.org/)
- Other - App-Specific: - Other - App-Specific:
- [WhatsApp](https://whatsapp.com)
- [Telegram App](https://telegram.org) - [Telegram App](https://telegram.org)
- [Steam Mobile Apps](https://store.steampowered.com/mobile)
- [Neutron Code](https://neutroncode.com) - [Neutron Code](https://neutroncode.com)
- "HTML" (Fallback): Any other URL that returns an HTML page with links to APK files - "HTML" (Fallback): Any other URL that returns an HTML page with links to APK files

View File

@ -96,19 +96,15 @@ repositories {
} }
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
def shizuku_version = '13.1.5' def shizuku_version = '13.1.5'
implementation "dev.rikka.shizuku:api:$shizuku_version" implementation "dev.rikka.shizuku:api:$shizuku_version"
implementation "dev.rikka.shizuku:provider:$shizuku_version" implementation "dev.rikka.shizuku:provider:$shizuku_version"
def hidden_api_version = '4.1.0' def hidden_api_version = '4.3.1'
// DO NOT UPDATE Hidden API without updating the Android tools
// and do not update Android tools without updating the whole Flutter
// (also in android/build.gradle)
implementation "dev.rikka.tools.refine:runtime:$hidden_api_version" implementation "dev.rikka.tools.refine:runtime:$hidden_api_version"
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 "com.github.topjohnwu.libsu:core:5.2.2" implementation "com.github.topjohnwu.libsu:core:5.2.2"
} }

View File

@ -5,7 +5,8 @@
android:label="Obtainium" android:label="Obtainium"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"> android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
@ -44,21 +45,6 @@
<meta-data <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
<service
android:name="dev.fluttercommunity.plus.androidalarmmanager.AlarmService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false" />
<receiver
android:name="dev.fluttercommunity.plus.androidalarmmanager.AlarmBroadcastReceiver"
android:exported="false" />
<receiver
android:name="dev.fluttercommunity.plus.androidalarmmanager.RebootBroadcastReceiver"
android:enabled="false"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="dev.imranr.obtainium" android:authorities="dev.imranr.obtainium"

View File

@ -0,0 +1,44 @@
package dev.imranr.obtainium
import android.util.Xml
import org.xmlpull.v1.XmlPullParser
import java.io.File
import java.io.FileInputStream
class DefaultSystemFont {
fun get(): String {
return try {
val file = File("/system/etc/fonts.xml")
val fileStream = FileInputStream(file)
parseFontsFileStream(fileStream)
} catch (e: Exception) {
e.message ?: "Unknown fonts.xml parsing exception"
}
}
private fun parseFontsFileStream(fileStream: FileInputStream): String {
fileStream.use { stream ->
val parser = Xml.newPullParser()
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
parser.setInput(stream, null)
parser.nextTag()
return parseFonts(parser)
}
}
private fun parseFonts(parser: XmlPullParser): String {
while (!((parser.next() == XmlPullParser.END_TAG) && (parser.name == "family"))) {
if ((parser.eventType == XmlPullParser.START_TAG) && (parser.name == "font")
&& (parser.getAttributeValue(null, "style") == "normal")
&& (parser.getAttributeValue(null, "weight") == "400")) {
break
}
}
parser.next()
val fontFile = parser.text.trim()
if (fontFile == "") {
throw NoSuchFieldException("The font filename couldn't be found in fonts.xml")
}
return "/system/fonts/$fontFile"
}
}

View File

@ -22,12 +22,13 @@ import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.Result 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 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 installersChannel: MethodChannel? = null private var nativeChannel: MethodChannel? = null
private val SHIZUKU_PERMISSION_REQUEST_CODE = (10..200).random() private val SHIZUKU_PERMISSION_REQUEST_CODE = (10..200).random()
private fun shizukuCheckPermission(result: Result) { private fun shizukuCheckPermission(result: Result) {
@ -51,7 +52,7 @@ class MainActivity: FlutterActivity() {
requestCode: Int, grantResult: Int -> requestCode: Int, grantResult: Int ->
if (requestCode == SHIZUKU_PERMISSION_REQUEST_CODE) { if (requestCode == SHIZUKU_PERMISSION_REQUEST_CODE) {
val res = if (grantResult == PackageManager.PERMISSION_GRANTED) 1 else 0 val res = if (grantResult == PackageManager.PERMISSION_GRANTED) 1 else 0
installersChannel!!.invokeMethod("resPermShizuku", mapOf("res" to res)) nativeChannel!!.invokeMethod("resPermShizuku", mapOf("res" to res))
} }
} }
@ -76,7 +77,8 @@ class MainActivity: FlutterActivity() {
val params = val params =
PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
var installFlags: Int = PackageInstallerUtils.getInstallFlags(params) var installFlags: Int = PackageInstallerUtils.getInstallFlags(params)
installFlags = installFlags or 0x00000004 // PackageManager.INSTALL_ALLOW_TEST installFlags = installFlags or (0x00000002/*PackageManager.INSTALL_REPLACE_EXISTING*/
or 0x00000004 /*PackageManager.INSTALL_ALLOW_TEST*/)
PackageInstallerUtils.setInstallFlags(params, installFlags) PackageInstallerUtils.setInstallFlags(params, installFlags)
val sessionId = packageInstaller.createSession(params) val sessionId = packageInstaller.createSession(params)
val iSession = IPackageInstallerSession.Stub.asInterface( val iSession = IPackageInstallerSession.Stub.asInterface(
@ -136,7 +138,7 @@ class MainActivity: FlutterActivity() {
} }
private fun rootInstallApk(apkFilePath: String, result: Result) { private fun rootInstallApk(apkFilePath: String, result: Result) {
Shell.sh("pm install -R -t " + apkFilePath).submit { out -> Shell.sh("pm install -r -t " + apkFilePath).submit { out ->
val builder = StringBuilder() val builder = StringBuilder()
for (data in out.getOut()) { builder.append(data) } for (data in out.getOut()) { builder.append(data) }
result.success(builder.toString().endsWith("Success")) result.success(builder.toString().endsWith("Success"))
@ -145,12 +147,18 @@ class MainActivity: FlutterActivity() {
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) {
HiddenApiBypass.addHiddenApiExemptions("")
}
Shizuku.addRequestPermissionResultListener(shizukuRequestPermissionResultListener) Shizuku.addRequestPermissionResultListener(shizukuRequestPermissionResultListener)
installersChannel = MethodChannel( nativeChannel = MethodChannel(
flutterEngine.dartExecutor.binaryMessenger, "installers") flutterEngine.dartExecutor.binaryMessenger, "native")
installersChannel!!.setMethodCallHandler { nativeChannel!!.setMethodCallHandler {
call, result -> call, result ->
if (call.method == "checkPermissionShizuku") { if (call.method == "getSystemFont") {
val res = DefaultSystemFont().get()
result.success(res)
} else if (call.method == "checkPermissionShizuku") {
shizukuCheckPermission(result) shizukuCheckPermission(result)
} else if (call.method == "checkPermissionRoot") { } else if (call.method == "checkPermissionRoot") {
rootCheckPermission(result) rootCheckPermission(result)

View File

@ -1,5 +1,5 @@
buildscript { buildscript {
ext.kotlin_version = '1.7.10' ext.kotlin_version = '1.8.10'
ext { ext {
compileSdkVersion = 34 // or latest compileSdkVersion = 34 // or latest
targetSdkVersion = 34 // or latest targetSdkVersion = 34 // or latest
@ -11,9 +11,9 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.2.0' classpath "com.android.tools.build:gradle:7.4.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'dev.rikka.tools.refine:gradle-plugin:4.1.0' // Do not update! classpath "dev.rikka.tools.refine:gradle-plugin:4.3.1"
} }
} }

View File

@ -103,7 +103,6 @@
"importErrors": "Uvezi greške", "importErrors": "Uvezi greške",
"importedXOfYApps": "{} od {} aplikacija uvezeno.", "importedXOfYApps": "{} od {} aplikacija uvezeno.",
"followingURLsHadErrors": "Sljedeći URL-ovi su imali greške:", "followingURLsHadErrors": "Sljedeći URL-ovi su imali greške:",
"okay": "Dobro",
"selectURL": "Odaberite URL", "selectURL": "Odaberite URL",
"selectURLs": "Odaberite URL-ove", "selectURLs": "Odaberite URL-ove",
"pick": "Odaberi", "pick": "Odaberi",
@ -283,6 +282,11 @@
"supportFixedAPKURL": "Podržite fiksne APK URL-ove", "supportFixedAPKURL": "Podržite fiksne APK URL-ove",
"selectX": "Izaberite {}", "selectX": "Izaberite {}",
"parallelDownloads": "Allow parallel downloads", "parallelDownloads": "Allow parallel downloads",
"installMethod": "Installation method",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku is not running",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?", "one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?" "other": "Želite li ukloniti aplikacije?"

View File

@ -9,36 +9,36 @@
"placeholder": "Zástupce", "placeholder": "Zástupce",
"someErrors": "Vyskytly se nějaké chyby", "someErrors": "Vyskytly se nějaké chyby",
"unexpectedError": "Neočekávaná chyba", "unexpectedError": "Neočekávaná chyba",
"ok": "Okay", "ok": "Ok",
"and": "a", "and": "a",
"githubPATLabel": "GitHub Personal Access Token (Raises Rate Limit)", "githubPATLabel": "GitHub Personal Access Token (zvyšuje limit rychlosti)",
"includePrereleases": "includepreleases", "includePrereleases": "Zahrnout předběžné verze",
"fallbackToOlderReleases": "Fallback to older releases", "fallbackToOlderReleases": "Přechod na starší verze",
"filterReleaseTitlesByRegEx": "Názvy vydání podle regulárního výrazu\filtr", "filterReleaseTitlesByRegEx": "Filtrovat názvy verzí podle regulárního výrazu",
"invalidRegEx": "Neplatný regulární výraz", "invalidRegEx": "Neplatný regulární výraz",
"noDescription": "Žádný popis", "noDescription": "Žádný popis",
"cancel": "Zrušit", "cancel": "Zrušit",
"continue": "Pokračovat", "continue": "Pokračovat",
"requiredInBracets": "(Required)", "requiredInBracets": "(Required)",
"dropdownNoOptsError": "ERROR: DROPDOWN MUSÍ MÍT AŽ JEDNU MOŽNOST", "dropdownNoOptsError": "ERROR: DROPDOWN MUSÍ MÍT AŽ JEDNU MOŽNOST",
"color": "barva", "colour": "Barva",
"githubStarredRepos": "GitHub Starred Repos", "githubStarredRepos": "GitHub Starred Repos",
"uname": "username", "uname": "Uživatelské jméno",
"wrongArgNum": "Špatný počet předložených argumentů", "wrongArgNum": "Nesprávný počet zadaných argumentů",
"xIsTrackOnly": "{} je určeno pouze pro sledování", "xIsTrackOnly":"{} je určeno pouze pro sledování",
"source": "zdroj", "source": "Zdroj",
"app": "App", "app": "App",
"appsFromSourceAreTrackOnly": "Aplikace z tohoto zdroje jsou 'Jen sledovány'.", "appsFromSourceAreTrackOnly": "Aplikace z tohoto zdroje jsou Jen sledovány.",
"youPickedTrackOnly": "Vybrali jste možnost 'Jen sledovat'.", "youPickedTrackOnly": "Vybrali jste možnost Jen sledovat.",
"trackOnlyAppDescription": "Aplikace je sledována kvůli aktualizacím, ale Obtainium ji nebude stahovat ani instalovat.", "trackOnlyAppDescription": "Aplikace je sledována kvůli aktualizacím, ale Obtainium ji nebude stahovat ani instalovat.",
"cancelled": "Zrušeno", "cancelled": "Zrušeno",
"appAlreadyAdded": "Aplikace již přidána", "appAlreadyAdded": "Aplikace již přidána",
"alreadyUpToDateQuestion": "App already up to date?", "alreadyUpToDateQuestion": "App already up to date?",
"addApp": "Přidat aplikaci", "addApp": "Přidat aplikaci",
"appSourceURL": "zdrojová adresa URL aplikace", "appSourceURL": "Zdrojová adresa URL aplikace",
"error": "Chyba", "error": "Chyba",
"add": "Přidat", "add": "Přidat",
"searchSomeSourcesLabel": "Vyhledávání (pouze konkrétní zdroje)", "searchSomeSourcesLabel": "Vyhledávání (pouze pro určité zdroje)",
"search": "Hledat", "search": "Hledat",
"additionalOptsFor": "Další možnosti pro {}", "additionalOptsFor": "Další možnosti pro {}",
"supportedSources": "Podporované zdroje", "supportedSources": "Podporované zdroje",
@ -46,45 +46,45 @@
"searchableInBrackets": "(s možností vyhledávání)", "searchableInBrackets": "(s možností vyhledávání)",
"appsString": "Apky", "appsString": "Apky",
"noApps": "Žádné aplikace", "noApps": "Žádné aplikace",
"noAppsForFilter": "žádné aplikace pro vybraný filtr", "noAppsForFilter": "Žádné aplikace pro vybraný filtr",
"byX": "By {}", "byX": "Od {}",
"percentProgress": "Pokrok: {}%", "percentProgress": "Pokrok: {}%",
"pleaseWait": "Počkejte prosím", "pleaseWait": "Počkejte prosím",
"updateAvailable": "Aktualizace je k dispozici", "updateAvailable": "Aktualizace je k dispozici",
"estimateInBracketsShort": "(approx.)", "estimateInBracketsShort": "(approx.)",
"notInstalled": "Není nainstalováno", "notInstalled": "Není nainstalováno",
"estimateInBrackets": "(přibližně)", "estimateInBrackets": "(přibližně)",
"selectAll": "Vybrat Vše", "selectAll": "Vybrat vše",
"deselectX": "{} deselected", "deselectX": "{} deselected",
"xWillBeRemovedButRemainInstalled": "{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.", "xWillBeRemovedButRemainInstalled": "{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.",
"removeSelectedAppsQuestion": "Odebrat vybrané aplikace?", "removeSelectedAppsQuestion": "Odebrat vybrané aplikace?",
"removeSelectedApps": "Odebrat vybrané aplikace", "removeSelectedApps": "Odebrat vybrané aplikace",
"updateX": "Aktualizovat {}", "updateX": "Aktualizovat {}",
"installX": "Instalovat {}", "installX": "Instalovat {}",
"markXTrackOnlyAsUpdated": "Označit {}\n(Track-Only)\njako aktualizované", "markXTrackOnlyAsUpdated": "Označit {}\n(Jen sledované)\njako aktualizované",
"changeX": "Změnit {}", "changeX": "Změnit {}",
"installUpdateApps": "Instalovat/aktualizovat aplikace", "installUpdateApps": "Instalovat/aktualizovat aplikace",
"installUpdateSelectedApps": "Instalovat/aktualizovat vybrané aplikace", "installUpdateSelectedApps": "Instalovat/aktualizovat vybrané aplikace",
"markXSelectedAppsAsUpdated": "označit {} vybrané aplikace jako aktuální?", "markXSelectedAppsAsUpdated": "Označit {} vybrané aplikace jako aktuální?",
"no": "Ne", "no": "Ne",
"yes": "ano", "yes": "Ano",
"markSelectedAppsUpdated": "označit vybrané aplikace jako aktuální", "markSelectedAppsUpdated": "Označit vybrané aplikace jako aktuální",
"pinToTop": "Připnout nahoru", "pinToTop": "Připnout nahoru",
"unpinFromTop": "'Unpin Top'", "unpinFromTop": "Odepnout shora",
"resetInstallStatusForSelectedAppsQuestion": "Obnovit stav instalace vybraných aplikací?", "resetInstallStatusForSelectedAppsQuestion": "Obnovit stav instalace vybraných aplikací?",
"installStatusOfXWillBeResetExplanation": "Stav instalace vybraných aplikací bude resetován. To může být užitečné, pokud je verze aplikace zobrazená v Obtainium nesprávná z důvodu neúspěšných aktualizací nebo jiných problémů.", "installStatusOfXWillBeResetExplanation": "Stav instalace vybraných aplikací bude resetován. To může být užitečné, pokud je verze aplikace zobrazená v Obtainium nesprávná z důvodu neúspěšných aktualizací nebo jiných problémů.",
"shareSelectedAppURLs": "Sdílet adresy URL vybraných aplikací", "shareSelectedAppURLs": "Sdílet adresy URL vybraných aplikací",
"resetInstallStatus": "Obnovení stavu instalace", "resetInstallStatus": "Obnovit stav instalace",
"more": "more", "more": "Více",
"removeOutdatedFilter": "Odstranit filtr aplikace 'Not Current'", "removeOutdatedFilter": "Odstranit filtr Neaktuální",
"showOutdatedOnly": "Zobrazit pouze aplikace, které nejsou aktuální", "showOutdatedOnly": "Zobrazovat pouze zastaralé aplikace",
"filter": "Filtr", "filter": "Filtr",
"filterActive": "Filtr *", "filterActive": "Filtr *",
"filterApps": "Filtrovat aplikace", "filterApps": "Filtrovat aplikace",
"appName": "název aplikace", "appName": "Název aplikace",
"author": "Autor", "author": "Autor",
"upToDateApps": "Apps with current version", "upToDateApps": "Aktuální apky",
"nonInstalledApps": "Apps not installed", "nonInstalledApps": "Neinstalované apky",
"importExport": "Import/Export", "importExport": "Import/Export",
"settings": "Nastavení", "settings": "Nastavení",
"exportedTo": "Exportováno do {}", "exportedTo": "Exportováno do {}",
@ -93,76 +93,75 @@
"importedX": "Importováno {}", "importedX": "Importováno {}",
"obtainiumImport": "Obtainium Import", "obtainiumImport": "Obtainium Import",
"importFromURLList": "Import ze seznamu URL", "importFromURLList": "Import ze seznamu URL",
"searchQuery": "Search Query", "searchQuery": "Vyhledávací dotaz",
"appURLList": "App URL List", "appURLList": "Seznam adres aplikací",
"line": "line", "line": "Linka",
"searchX": "Search {}", "searchX": "Search {}",
"noResults": "Nebyly nalezeny žádné výsledky", "noResults": "Nebyly nalezeny žádné výsledky",
"importX": "Import {}", "importX": "Import {}",
"importedAppsIdDisclaimer": "Importované aplikace mohou být nesprávně zobrazeny jako \"Neinstalované\". Chcete-li to opravit, nainstalujte je znovu prostřednictvím Obtainium. To nemá vliv na data aplikací. Ovlivňuje pouze metody importu URL a třetích stran.", "importedAppsIdDisclaimer": "Importované aplikace mohou být nesprávně zobrazeny jako \"Neinstalovány\". Chcete-li to opravit, nainstalujte je znovu prostřednictvím Obtainium. To nemá vliv na data aplikací. Ovlivňuje pouze metody importu URL a třetích stran.",
"importErrors": "Import Errors", "importErrors": "Chyba importu",
"importedXOfYApps": "{}importováno {}aplikací.", "importedXOfYApps": "{}importováno z {} aplikací.",
"followingURLsHadErrors": "U následujících adres URL došlo k chybám:", "followingURLsHadErrors": "U následujících adres došlo k chybám:",
"okay": "Okay", "selectURL": "Vybrat adresu",
"selectURL": "Select URL", "selectURLs": "Select adresy",
"selectURLs": "Select URLs",
"pick": "Vybrat", "pick": "Vybrat",
"theme": "Téma", "theme": "Téma",
"dark": "Tmavé", "dark": "Tmavé",
"light": "Světlé", "light": "Světlé",
"followSystem": "Follow System", "followSystem": "Jako systém",
"obtainium": "Obtainium", "obtainium": "Obtainium",
"materialYou": "Material You", "materialYou": "Material You",
"useBlackTheme": "Použít čistě černé tmavé téma", "useBlackTheme": "Použít čistě černé tmavé téma",
"appSortBy": "Seřadit aplikaci podle", "appSortBy": "Seřadit podle",
"authorName": "autor/jméno", "authorName": "Autor/Jméno",
"nameAuthor": "jméno/autor", "nameAuthor": "Jméno/Autor",
"asAdded": "AsAdded", "asAdded": "Přidáno",
"appSortOrder": "Sort App By", "appSortOrder": "Seřadit",
"ascending": "Vzestupně", "ascending": "Vzestupně",
"descending": "Sestupně", "descending": "Sestupně",
"bgUpdateCheckInterval": "Background Update Check Interval", "bgUpdateCheckInterval": "Interval kontroly aktualizace na pozadí",
"neverManualOnly": "Nikdy - pouze ručně", "neverManualOnly": "Nikdy - pouze ručně",
"appearance": "Vzhled", "appearance": "Vzhled",
"showWebInAppView": "Zobrazit zdrojové webové stránky v zobrazení aplikace", "showWebInAppView": "Zobrazit zdrojové webové stránky v zobrazení aplikace",
"pinUpdates": "Připnout aplikace s aktualizacemi nahoře", "pinUpdates": "Připnout aplikace s aktualizacemi nahoru",
"updates": "Updates", "updates": "Updates",
"sourceSpecific": "source specific", "sourceSpecific": "Specifické pro zdroj",
"appSource": "zdroj aplikace", "appSource": "Zdroj aplikace",
"noLogs": "Žádné protokoly", "noLogs": "Žádné protokoly",
"appLogs": "App Logs", "appLogs": "Záznamy apky",
"close": "Zavřít", "close": "Zavřít",
"share": "Sdílet", "share": "Sdílet",
"appNotFound": "App not found", "appNotFound": "Aplikace nenalezena",
"obtainiumExportHyphenatedLowercase": "obtainium-export", "obtainiumExportHyphenatedLowercase": "obtainium-export",
"pickAnAPK": "Vybrat APK", "pickAnAPK": "Vybrat APK",
"appHasMoreThanOnePackage": "{} má více než jeden balíček:", "appHasMoreThanOnePackage": "{} má více než jeden balíček:",
"deviceSupportsXArch": "Vaše zařízení podporuje architekturu CPU {}.", "deviceSupportsXArch": "Vaše zařízení podporuje architekturu CPU {}.",
"deviceSupportsFollowingArchs": "Vaše zařízení podporuje následující architektury CPU:", "deviceSupportsFollowingArchs": "Vaše zařízení podporuje následující architektury CPU:",
"warning": "Varování", "warning": "Varování",
"sourceIsXButPackageFromYPrompt": "The app source is '{}' but the release package is from '{}'. Pokračovat?", "sourceIsXButPackageFromYPrompt": "Zdroj aplikace je '{}', ale balíček pro vydání je z '{}'. Pokračovat?",
"updatesAvailable": "dostupné aktualizace", "updatesAvailable": "Dostupné aktualizace",
"updatesAvailableNotifDescription": "Upozorňuje uživatele, že jsou k dispozici aktualizace pro jednu nebo více aplikací sledovaných Obtainium", "updatesAvailableNotifDescription": "Upozorňuje uživatele, že jsou k dispozici aktualizace pro jednu nebo více aplikací sledovaných Obtainium",
"noNewUpdates": "Žádné nové aktualizace.", "noNewUpdates": "Žádné nové aktualizace.",
"xHasAnUpdate": "{} má aktualizaci.", "xHasAnUpdate": "{} má aktualizaci.",
"appsUpdated": "Aplikace aktualizovány", "appsUpdated": "Aplikace aktualizovány",
"appsUpdatedNotifDescription": "Upozorňuje uživatele, že byly provedeny aktualizace jedné nebo více aplikací na pozadí", "appsUpdatedNotifDescription": "Upozornit, že byly provedeny aktualizace jedné nebo více aplikací na pozadí",
"xWasUpdatedToY": "{} byl aktualizován na {}", "xWasUpdatedToY": "{} byla aktualizována na {}",
"errorCheckingUpdates": "Chybová kontrola aktualizací", "errorCheckingUpdates": "Chyba kontroly aktualizací",
"errorCheckingUpdatesNotifDescription": "Oznámení zobrazené při neúspěšné kontrole aktualizací na pozadí", "errorCheckingUpdatesNotifDescription": "Zobrazit oznámení při neúspěšné kontrole aktualizací na pozadí",
"appsRemoved": "Odstraněné aplikace", "appsRemoved": "Odstraněné aplikace",
"appsRemovedNotifDescription": "Oznámení uživateli, že jedna nebo více aplikací byly odstraněny z důvodu chyb při načítání", "appsRemovedNotifDescription": "Oznámit, že jedna nebo více aplikací bylo odstraněno z důvodu chyb při načítání",
"xWasRemovedDueToErrorY": "{} byla odstraněna z důvodu následující chyby: {}", "xWasRemovedDueToErrorY": "{} byla odstraněna z důvodu následující chyby: {}",
"completeAppInstallation": "Dokončit instalaci aplikace", "completeAppInstallation": "Dokončit instalaci aplikace",
"obtainiumMustBeOpenToInstallApps": "Obtainium musí být otevřeno, aby bylo možné instalovat aplikace", "obtainiumMustBeOpenToInstallApps": "Obtainium musí být otevřeno, aby bylo možné instalovat aplikace",
"completeAppInstallationNotifDescription": "Vyzvat uživatele k návratu do Obtainium pro dokončení instalace aplikací", "completeAppInstallationNotifDescription": "Vyzvat k návratu do Obtainium pro dokončení instalace aplikací",
"checkingForUpdates": "Zkontrolovat aktualizace", "checkingForUpdates": "Zkontrolovat aktualizace",
"checkingForUpdatesNotifDescription": "Dočasné oznámení zobrazené při kontrole aktualizací", "checkingForUpdatesNotifDescription": "Dočasné oznámení zobrazené při kontrole aktualizací",
"pleaseAllowInstallPerm": "Povolte prosím Obtainium instalovat aplikace", "pleaseAllowInstallPerm": "Povolte prosím Obtainium instalovat aplikace",
"trackOnly": "Jen sledovat", "trackOnly": "Jen sledovat",
"errorWithHttpStatusCode": "error {}", "errorWithHttpStatusCode": "Chyba {}",
"versionCorrectionDisabled": "Oprava verze zakázána (zásuvný modul zřejmě nefunguje)", "versionCorrectionDisabled": "Oprava verze zakázána (zásuvný modul zřejmě nefunguje)",
"unknown": "Unknown", "unknown": "Neznám",
"none": "None", "none": "None",
"never": "Nikdy", "never": "Nikdy",
"latestVersionX": "Nejnovější verze: {}", "latestVersionX": "Nejnovější verze: {}",
@ -170,12 +169,12 @@
"lastUpdateCheckX": "Poslední kontrola aktualizace: {}", "lastUpdateCheckX": "Poslední kontrola aktualizace: {}",
"remove": "Odebrat", "remove": "Odebrat",
"yesMarkUpdated": "Ano, označit jako aktualizované", "yesMarkUpdated": "Ano, označit jako aktualizované",
"fdroid": "F-Droid Official", "fdroid": "Oficiální repozitář F-Droid",
"appIdOrName": "App ID or Name", "appIdOrName": "ID nebo název apky",
"appId": "App ID", "appId": "App ID",
"appWithIdOrNameNotFound": "Žádná aplikace s tímto ID nebo názvem nebyla nalezena", "appWithIdOrNameNotFound": "Žádná aplikace s tímto ID nebo názvem nebyla nalezena",
"reposHaveMultipleApps": "Repozitáře mohou obsahovat více aplikací", "reposHaveMultipleApps": "Repozitáře mohou obsahovat více aplikací",
"fdroidThirdPartyRepo": "F-Droid Third-Party Repo", "fdroidThirdPartyRepo": "F-Droid repozitář třetí strany",
"steam": "Steam", "steam": "Steam",
"steamMobile": "Steam Mobile", "steamMobile": "Steam Mobile",
"steamChat": "Steam Chat", "steamChat": "Steam Chat",
@ -183,106 +182,111 @@
"markInstalled": "Označit jako nainstalovaný", "markInstalled": "Označit jako nainstalovaný",
"update": "Aktualizovat", "update": "Aktualizovat",
"markUpdated": "Označit jako aktuální", "markUpdated": "Označit jako aktuální",
"additionalOptions": "Additional Options", "additionalOptions": "Další možnosti",
"disableVersionDetection": "Zakázat detekci verze", "disableVersionDetection": "Deaktivovat detekci verze",
"noVersionDetectionExplanation": "Tato volba by měla být použita pouze u aplikací, kde detekce verzí nefunguje správně.", "noVersionDetectionExplanation": "Tato možnost by měla být použita pouze u aplikace, kde detekce verzí nefunguje správně.",
"downloadingX": "download {}", "downloadingX": "Stáhnout {}",
"downloadNotifDescription": "Informuje uživatele o průběhu stahování aplikace", "downloadNotifDescription": "Informuje uživatele o průběhu stahování aplikace",
"noAPKFound": "Žádná APK nebyla nalezena", "noAPKFound": "Žádná APK nebyla nalezena",
"noVersionDetection": "Žádná detekce verze", "noVersionDetection": "Žádná detekce verze",
"categorize": "Kategorizovat", "categorize": "Kategorizovat",
"categories": "Kategorie", "categories": "Kategorie",
"category": "kategorie", "category": "Kategorie",
"noCategory": "Žádná kategorie", "noCategory": "Žádná kategorie",
"noCategories": "Žádné kategorie", "noCategories": "Žádné kategorie",
"deleteCategoriesQuestion": "Smazat kategorie?", "deleteCategoriesQuestion": "Smazat kategorie?",
"categoryDeleteWarning": "Všechny aplikace v odstraněných kategoriích budou nastaveny na nekategorizované.", "categoryDeleteWarning": "Všechny aplikace v odstraněných kategoriích budou nastaveny na nekategorizované.",
"addCategory": "přidat kategorii", "addCategory": "Přidat kategorii",
"label": "štítek", "label": "Štítek",
"language": "Jazyk", "language": "Jazyk",
"copiedToClipboard": "zkopírováno do schránky", "copiedToClipboard": "Zkopírováno do schránky",
"storagePermissionDenied": "povolení k ukládání odepřeno", "storagePermissionDenied": "Oprávnění k ukládání odepřeno",
"selectedCategorizeWarning": "Toto nahradí všechna stávající nastavení kategorií pro vybrané aplikace.", "selectedCategorizeWarning": "Toto nahradí všechna stávající nastavení kategorií pro vybrané aplikace.",
"filterAPKsByRegEx": "Filtrovat APK podle regulárního výrazu", "filterAPKsByRegEx": "Filtrovat APK podle regulárního výrazu",
"removeFromObtainium": "Odebrat z Obtainium", "removeFromObtainium": "Odebrat z Obtainium",
"uninstallFromDevice": "Odinstalovat ze zařízení", "uninstallFromDevice": "Odinstalovat ze zařízení",
"onlyWorksWithNonVersionDetectApps": "Funguje pouze pro aplikace s vypnutou detekcí verze.", "onlyWorksWithNonVersionDetectApps": "Funguje pouze pro aplikace s vypnutou detekcí verze.",
"releaseDateAsVersion": "Použít datum vydání jako verzi", "releaseDateAsVersion": "Použít datum vydání jako verzi",
"releaseDateAsVersionExplanation": "Tato možnost by měla být použita pouze u aplikací, u kterých detekce verze nefunguje správně, ale je k dispozici datum vydání.", "releaseDateAsVersionExplanation": "Tato možnost by měla být použita pouze u aplikace, kde detekce verzí nefunguje správně, ale je k dispozici datum vydání.",
"changes": "Změny", "changes": "Změny",
"releaseDate": "datum vydání", "releaseDate": "Datum vydání",
"importFromURLsInFile": "Importovat adresy URL ze souboru (např. OPML)", "importFromURLsInFile": "Importovat adresy URL ze souboru (např. OPML)",
"versionDetection": "detekce verze", "versionDetection": "Detekce verze",
"standardVersionDetection": "standardní detekce verze", "standardVersionDetection": "Standardní detekce verze",
"groupByCategory": "Seskupit podle kategorie", "groupByCategory": "Seskupit podle kategorie",
"autoApkFilterByArch": "Pokud je to možné, pokuste se filtrovat soubory APK podle architektury procesoru", "autoApkFilterByArch": "Pokud je to možné, pokuste se filtrovat soubory APK podle architektury procesoru",
"overrideSource": "Přepsat zdroj", "overrideSource": "Přepsat zdroj",
"dontShowAgain": "Nezobrazovat znovu", "dontShowAgain": "Nezobrazovat znovu",
"dontShowTrackOnlyWarnings": "Nezobrazovat varování pro 'Track Only'", "dontShowTrackOnlyWarnings": "Nezobrazovat varování pro 'Jen sledované'",
"dontShowAPKOriginWarnings": "Nezobrazovat varování pro původ APK", "dontShowAPKOriginWarnings": "Nezobrazovat varování pro původ APK",
"moveNonInstalledAppsToBottom": "Přesunout nenainstalované aplikace na konec zobrazení Aplikace", "moveNonInstalledAppsToBottom": "Přesunout nenainstalované aplikace na konec zobrazení Aplikace",
"gitlabPATLabel": "GitLab Personal Access Token\n(Umožňuje vyhledávání a lepší zjišťování APK)", "gitlabPATLabel": "GitLab Personal Access Token\n(Umožňuje vyhledávání a lepší zjišťování APK)",
"about": "About", "about": "O",
"requiresCredentialsInSettings": "{}: Vyžaduje další pověření (v nastavení)", "requiresCredentialsInSettings": "{}: Vyžaduje další pověření (v nastavení)",
"checkOnStart": "Zkontrolovat jednou při spuštění", "checkOnStart": "Zkontrolovat jednou při spuštění",
"tryInferAppIdFromCode": "Pokusit se určit ID aplikace ze zdrojového kódu", "tryInferAppIdFromCode": "Pokusit se určit ID aplikace ze zdrojového kódu",
"removeOnExternalUninstall": "Automaticky odstranit externě odinstalované aplikace", "removeOnExternalUninstall": "Automaticky odstranit externě odinstalované aplikace",
"pickHighestVersionCode": "Automaticky vybrat APK s kódem nejvyšší verze", "pickHighestVersionCode": "Automaticky vybrat nejvyšší verzi APK",
"checkUpdateOnDetailPage": "Zkontrolovat aktualizace při otevření stránky s podrobnostmi aplikace", "checkUpdateOnDetailPage": "Zkontrolovat aktualizaci při otevření stránky s podrobnostmi aplikace",
"disablePageTransitions": "Zakázat animace pro přechody stránek", "disablePageTransitions": "Zakázat animace pro přechody stránek",
"reversePageTransitions": "Obrátit animace pro přechody stránek", "reversePageTransitions": "Obrátit animace pro přechody stránek",
"minStarCount": "Minimální počet hvězdiček", "minStarCount": "Minimální počet hvězdiček",
"addInfoBelow": "Přidat tuto informaci na konec stránky", "addInfoBelow": "Přidat tuto informaci na konec stránky.",
"addInfoInSettings": "Přidat tuto informaci do nastavení.", "addInfoInSettings": "Přidat tuto informaci do nastavení.",
"githubSourceNote": "Omezení rychlosti GitHub lze obejít pomocí klíče API.", "githubSourceNote": "Omezení rychlosti GitHub lze obejít pomocí klíče API.",
"gitlabSourceNote": "Extrakce GitLab APK nemusí fungovat bez klíče API", "gitlabSourceNote": "Extrakce GitLab APK nemusí fungovat bez klíče API",
"sortByLastLinkSegment": "Sort by only the last segment of the link", "sortByLastLinkSegment": "Seřadit pouze podle poslední části odkazu",
"filterReleaseNotesByRegEx": "Filtrovat poznámky k vydání podle regulárního výrazu", "filterReleaseNotesByRegEx": "Filtrovat poznámky k vydání podle regulárního výrazu",
"customLinkFilterRegex": "Vlastní filtr odkazů APK podle regulárního výrazu (výchozí '.apk$')", "customLinkFilterRegex": "Vlastní filtr odkazů APK podle regulárního výrazu (výchozí '.apk$')",
"appsPossiblyUpdated": "Byly provedeny pokusy o aktualizaci aplikací", "appsPossiblyUpdated": "Byly provedeny pokusy o aktualizaci aplikací",
"appsPossiblyUpdatedNotifDescription": "Upozorňuje uživatele, že na pozadí mohly být provedeny aktualizace jedné nebo více aplikací", "appsPossiblyUpdatedNotifDescription": "Upozorňuje uživatele, že na pozadí mohly být provedeny aktualizace jedné nebo více aplikací",
"xWasPossiblyUpdatedToY": "{} mohlo být aktualizováno na {}.", "xWasPossiblyUpdatedToY":"{} mohlo být aktualizováno na {}.",
"enableBackgroundUpdates": "Povolit aktualizace na pozadí", "enableBackgroundUpdates": "Povolit aktualizace na pozadí",
"backgroundUpdateReqsExplanation": "Aktualizace na pozadí nemusí být možné pro všechny aplikace.", "backgroundUpdateReqsExplanation": "Aktualizace na pozadí nemusí být možná pro všechny aplikace.",
"backgroundUpdateLimitsExplanation": "Úspěšnost instalace na pozadí lze určit pouze v případě, že je otevřen Obtainium.", "backgroundUpdateLimitsExplanation": "Úspěšnost instalace na pozadí lze určit pouze v případě, že je otevřeno Obtainium.",
"verifyLatestTag": "Ověřit značku 'latest'", "verifyLatestTag": "Zkontrolovat značku latest",
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit", "intermediateLinkRegex": "Filtrovat mezipropojení, které by mělo být navštíveno jako první",
"filterByLinkText": "Filter links by link text", "filterByLinkText": "Filtrovat odkazy podle textu odkazu",
"intermediateLinkNotFound": "Intermediate link not found", "intermediateLinkNotFound": "Připojený odkaz nenalezen",
"intermediateLink": "Intermediate link", "intermediateLink": "Připojený odkaz",
"exemptFromBackgroundUpdates": "Vyloučit aktualizace na pozadí (pokud jsou povoleny)", "exemptFromBackgroundUpdates": "Vyloučit z aktualizací na pozadí (je-li povoleno)",
"bgUpdatesOnWiFiOnly": "Zakázat aktualizace na pozadí, pokud není přítomna Wi-Fi", "bgUpdatesOnWiFiOnly": "Deaktivovat aktualizace na pozadí, pokud není k dispozici Wi-Fi",
"autoSelectHighestVersionCode": "Automatický výběr nejvyššího kódu verze APK", "autoSelectHighestVersionCode": "Automaticky vybrat nejvyšší verzi APK",
"versionExtractionRegEx": "Version Extraction RegEx", "versionExtractionRegEx": "Extrakce verze pomocí RegEx",
"matchGroupToUse": "Match Group to Use", "matchGroupToUse": "Odpovídá použité skupině",
"highlightTouchTargets": "Zvýraznit méně zjevné cíle dotyku", "highlightTouchTargets": "Zvýraznit méně zjevné cíle dotyku",
"pickExportDir": "Vybrat adresář pro export", "pickExportDir": "Vybrat adresář pro export",
"autoExportOnChanges": "Automatický export při změnách", "autoExportOnChanges": "Automatický export při změně",
"includeSettings": "Include settings", "includeSettings": "Zahrnout nastavení",
"filterVersionsByRegEx": "Filtrovat verze podle regulárního výrazu", "filterVersionsByRegEx": "Filtrovat verze podle regulárních výrazů",
"trySelectingSuggestedVersionCode": "Zkusit vybrat navrhovaný kód verze APK", "trySelectingSuggestedVersionCode": "Zkusit vybrat navrhovanou verzi APK",
"dontSortReleasesList": "Retain release order from API", "dontSortReleasesList": "Seřadit vydání z rozhraní API",
"reverseSort": "Reverse sorting", "reverseSort": "Obrácené třídění",
"takeFirstLink": "Take first link", "takeFirstLink": "Použít první odkaz",
"skipSort": "Skip sorting", "skipSort": "Přeskočit třídění",
"debugMenu": "Debug Menu", "debugMenu": "Nabídka ladění",
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Spuštěna úloha na pozadí - zkontrolujte protokoly.",
"runBgCheckNow": "Run Background Update Check Now", "runBgCheckNow": "Spustit kontrolu aktualizací na pozadí nyní",
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page", "versionExtractWholePage": "Použít extrakci verze pomocí RegEx na celou stránku",
"installing": "Installing", "installing": "Instaluji",
"skipUpdateNotifications": "Skip update notifications", "skipUpdateNotifications": "Neposkytovat oznámení o aktualizaci",
"updatesAvailableNotifChannel": "dostupné aktualizace", "updatesAvailableNotifChannel": "Dostupné aktualizace",
"appsUpdatedNotifChannel": "Aplikace aktualizovány", "appsUpdatedNotifChannel": "Apky aktualizovány",
"appsPossiblyUpdatedNotifChannel": "Byly provedeny pokusy o aktualizaci aplikací", "appsPossiblyUpdatedNotifChannel": "Byly provedeny pokusy o aktualizace aplikací",
"errorCheckingUpdatesNotifChannel": "Chybová kontrola aktualizací", "errorCheckingUpdatesNotifChannel": "Chyba při kontrole aktualizací",
"appsRemovedNotifChannel": "Odstraněné aplikace", "appsRemovedNotifChannel": "Odstraněné apky",
"downloadingXNotifChannel": "download {}", "downloadingXNotifChannel": "Stáhnout {}",
"completeAppInstallationNotifChannel": "Dokončit instalaci aplikace", "completeAppInstallationNotifChannel": "Dokončit instalaci aplikace",
"checkingForUpdatesNotifChannel": "Zkontrolovat aktualizace", "checkingForUpdatesNotifChannel": "Zkontrolovat aktualizace",
"onlyCheckInstalledOrTrackOnlyApps": "Only check installed and Track-Only apps for updates", "onlyCheckInstalledOrTrackOnlyApps": "Na aktualizace kontrolovat pouze nainstalované aplikace a aplikace označené Track only",
"supportFixedAPKURL": "Support fixed APK URLs", "supportFixedAPKURL": "Odhadnout novější verzi na základě prvních třiceti číslic kontrolního součtu adresy URL APK, pokud není podporována jinak",
"selectX": "Select {}", "selectX": "Vybrat {}",
"parallelDownloads": "Allow parallel downloads", "parallelDownloads": "Povolit souběžné stahování",
"installMethod": "Metoda instalace",
"normal": "Normální",
"shizuku": "Shizuku",
"root": "Správce",
"shizukuBinderNotFound": "Shizuku neběží",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Odstranit Apku?", "one": "Odstranit Apku?",
"other": "Odstranit Apky?" "other": "Odstranit Apky?"
@ -292,47 +296,47 @@
"other": "Příliš mnoho požadavků (omezená rychlost) - zkuste to znovu za {} minut" "other": "Příliš mnoho požadavků (omezená rychlost) - zkuste to znovu za {} minut"
}, },
"bgUpdateGotErrorRetryInMinutes": { "bgUpdateGotErrorRetryInMinutes": {
"one": "Při kontrole aktualizace na pozadí byla zjištěna chyba {}, opakování pokusu bude naplánováno za {} minut", "one": "Při kontrole aktualizace na pozadí byla zjištěna chyba {}, opakování bude naplánováno za {} minut",
"other": "Během kontroly aktualizace na pozadí byla zjištěna chyba {}, opakování bude naplánováno za {} minut" "other": "Při kontrole aktualizací na pozadí byla zjištěna chyba {}, opakování bude naplánováno za {} minut"
}, },
"bgCheckFoundUpdatesWillNotifyIfNeeded": { "bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "Při kontrole aktualizací na pozadí nalezena {}aktualizace - v případě potřeby upozorní uživatele", "one": "Při kontrole aktualizací na pozadí nalezena {}aktualizace - v případě potřeby upozorní uživatele",
"other": "Kontrola aktualizací na pozadí našla {} aktualizací - v případě potřeby upozorní uživatele" "other": "Kontrola aktualizací na pozadí nalezla {} aktualizací - v případě potřeby upozorní uživatele"
}, },
"apps": { "apps": {
"one": "{} App", "one": "{} Apka",
"other": "{} apps" "other": "{} Apky"
}, },
"url": { "url": {
"jedna": "{} URL", "one": "{} Adresa",
"other": "{} URLs" "other": "{} Adres"
}, },
"minute": { "minute": {
"one": "{} minute", "one": "{} Minuta",
"other": "{} minutes" "other": "{} Minut"
}, },
"hour": { "hour": {
"jedna": "{} hodina", "one": "{} Hodina",
"other": "{} hours" "other": "{} Hodin"
}, },
"day": { "day": {
"jedna": "{} den", "one": "{} Den",
"other": "{} dny" "other": "{} Dnů"
}, },
"clearedNLogsBeforeXAfterY": { "clearedNLogsBeforeXAfterY": {
"one": "{n} log vymazán (před = {před}, po = {po})", "one": "{n} Záznam vymazán (před = {before}, po = {after})",
"other": "{n} logů vymazáno (před = {před}, po = {po})" "other": "{n} Záznamů vymazáno (před = {before}, po = {after})"
}, },
"xAndNMoreUpdatesAvailable": { "xAndNMoreUpdatesAvailable": {
"one": "{} a 1 další aplikace mají aktualizace.", "one": "{} a 1 další aplikace mají aktualizace.",
"other": "{} a {} další aplikace mají aktualizace." "other": "{} a {} další aplikace mají aktualizace."
}, },
"xAndNMoreUpdatesInstalled": { "xAndNMoreUpdatesInstalled": {
"one": "{} a {} další aplikace mají aktualizace.", "one": "{} a 1 další aplikace mají aktualizace.",
"další": "{} a {} další aplikace byly aktualizovány." "other": "{} a {} další aplikace byly aktualizovány."
}, },
"xAndNMoreUpdatesPossiblyInstalled": { "xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} a {} další aplikace byly možná aktualizovány", "one": "{} a 1 další aplikace možno aktualizovat",
"other": "{} a {} další aplikace mohly být aktualizovány." "other": "{} a {} další aplikace mohou být aktualizovány."
} }
} }

View File

@ -103,7 +103,6 @@
"importErrors": "Importfehler", "importErrors": "Importfehler",
"importedXOfYApps": "{} von {} Apps importiert.", "importedXOfYApps": "{} von {} Apps importiert.",
"followingURLsHadErrors": "Bei folgenden URLs traten Fehler auf:", "followingURLsHadErrors": "Bei folgenden URLs traten Fehler auf:",
"okay": "Okay",
"selectURL": "URL auswählen", "selectURL": "URL auswählen",
"selectURLs": "URLs auswählen", "selectURLs": "URLs auswählen",
"pick": "Auswählen", "pick": "Auswählen",
@ -236,7 +235,7 @@
"addInfoInSettings": "Fügen Sie diese Info in den Einstellungen hinzu.", "addInfoInSettings": "Fügen Sie diese Info in den Einstellungen hinzu.",
"githubSourceNote": "Die GitHub-Ratenbegrenzung kann mit einem API-Schlüssel umgangen werden.", "githubSourceNote": "Die GitHub-Ratenbegrenzung kann mit einem API-Schlüssel umgangen werden.",
"gitlabSourceNote": "GitLab APK-Extraktion funktioniert möglicherweise nicht ohne API-Schlüssel", "gitlabSourceNote": "GitLab APK-Extraktion funktioniert möglicherweise nicht ohne API-Schlüssel",
"sortByLastLinkSegment": "Sort by only the last segment of the link", "sortByLastLinkSegment": "Sortiere nur nach dem letzten Teil des Links",
"filterReleaseNotesByRegEx": "Versionshinweise nach regulärem Ausdruck filtern", "filterReleaseNotesByRegEx": "Versionshinweise nach regulärem Ausdruck filtern",
"customLinkFilterRegex": "Benutzerdefinierter APK Link Filter nach Regulärem Ausdruck (Standard '.apk$')", "customLinkFilterRegex": "Benutzerdefinierter APK Link Filter nach Regulärem Ausdruck (Standard '.apk$')",
"appsPossiblyUpdated": "App Aktualisierungen wurden versucht", "appsPossiblyUpdated": "App Aktualisierungen wurden versucht",
@ -247,9 +246,9 @@
"backgroundUpdateLimitsExplanation": "Der Erfolg einer Hintergrundinstallation kann nur festgestellt werden, wenn Obtainium geöffnet wird.", "backgroundUpdateLimitsExplanation": "Der Erfolg einer Hintergrundinstallation kann nur festgestellt werden, wenn Obtainium geöffnet wird.",
"verifyLatestTag": "Überprüfe das „latest“ Tag", "verifyLatestTag": "Überprüfe das „latest“ Tag",
"intermediateLinkRegex": "Filter für einen „Zwischen“-Link, der zuerst besucht werden soll", "intermediateLinkRegex": "Filter für einen „Zwischen“-Link, der zuerst besucht werden soll",
"filterByLinkText": "Filter links by link text", "filterByLinkText": "Filtere Links durch Linktext",
"intermediateLinkNotFound": "„Zwischen“-Link nicht gefunden", "intermediateLinkNotFound": "„Zwischen“-Link nicht gefunden",
"intermediateLink": "Intermediate link", "intermediateLink": "„Zwischen“-Link",
"exemptFromBackgroundUpdates": "Ausschluss von Hintergrundaktualisierungen (falls aktiviert)", "exemptFromBackgroundUpdates": "Ausschluss von Hintergrundaktualisierungen (falls aktiviert)",
"bgUpdatesOnWiFiOnly": "Hintergrundaktualisierungen deaktivieren, wenn kein WLAN vorhanden ist", "bgUpdatesOnWiFiOnly": "Hintergrundaktualisierungen deaktivieren, wenn kein WLAN vorhanden ist",
"autoSelectHighestVersionCode": "Automatisch höchste APK-Version auswählen", "autoSelectHighestVersionCode": "Automatisch höchste APK-Version auswählen",
@ -283,6 +282,11 @@
"supportFixedAPKURL": "neuere Version anhand der ersten dreißig Zahlen der Checksumme der APK URL erraten, wenn anderweitig nicht unterstützt", "supportFixedAPKURL": "neuere Version anhand der ersten dreißig Zahlen der Checksumme der APK URL erraten, wenn anderweitig nicht unterstützt",
"selectX": "Wähle {}", "selectX": "Wähle {}",
"parallelDownloads": "Erlaube parallele Downloads", "parallelDownloads": "Erlaube parallele Downloads",
"installMethod": "Installationsmethode",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku läuft nicht",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App entfernen?", "one": "App entfernen?",
"other": "Apps entfernen?" "other": "Apps entfernen?"

View File

@ -103,7 +103,6 @@
"importErrors": "Import Errors", "importErrors": "Import Errors",
"importedXOfYApps": "{} of {} Apps imported.", "importedXOfYApps": "{} of {} Apps imported.",
"followingURLsHadErrors": "The following URLs had errors:", "followingURLsHadErrors": "The following URLs had errors:",
"okay": "Okay",
"selectURL": "Select URL", "selectURL": "Select URL",
"selectURLs": "Select URLs", "selectURLs": "Select URLs",
"pick": "Pick", "pick": "Pick",
@ -287,7 +286,9 @@
"normal": "Normal", "normal": "Normal",
"shizuku": "Shizuku", "shizuku": "Shizuku",
"root": "Root", "root": "Root",
"shizukuBinderNotFound": "Shizuku is not running", "shizukuBinderNotFound": "Сompatible Shizuku service wasn't found",
"useSystemFont": "Use the system font",
"systemFontError": "Error loading the system font: {}",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remove App?", "one": "Remove App?",
"other": "Remove Apps?" "other": "Remove Apps?"

View File

@ -8,13 +8,13 @@
"functionNotImplemented": "Esta clase no ha implementado esta función", "functionNotImplemented": "Esta clase no ha implementado esta función",
"placeholder": "Espacio reservado", "placeholder": "Espacio reservado",
"someErrors": "Han ocurrido algunos errores", "someErrors": "Han ocurrido algunos errores",
"unexpectedError": "Error Inesperado", "unexpectedError": "Error inesperado",
"ok": "OK", "ok": "OK",
"and": "y", "and": "y",
"githubPATLabel": "Token Github de Acceso Personal\n(Reduce tiempos de espera)", "githubPATLabel": "Token GitHub de acceso personal\n(reduce tiempos de espera)",
"includePrereleases": "Incluir versiones preliminares", "includePrereleases": "Incluir versiones preliminares",
"fallbackToOlderReleases": "Retroceder a versiones previas", "fallbackToOlderReleases": "Retroceder a versiones previas",
"filterReleaseTitlesByRegEx": "Filtrar por título de version", "filterReleaseTitlesByRegEx": "Filtrar por título de versión",
"invalidRegEx": "Expresión inválida", "invalidRegEx": "Expresión inválida",
"noDescription": "Sin descripción", "noDescription": "Sin descripción",
"cancel": "Cancelar", "cancel": "Cancelar",
@ -25,11 +25,11 @@
"githubStarredRepos": "Repositorios favoritos GitHub", "githubStarredRepos": "Repositorios favoritos GitHub",
"uname": "Nombre de usuario", "uname": "Nombre de usuario",
"wrongArgNum": "Número de argumentos provistos inválido", "wrongArgNum": "Número de argumentos provistos inválido",
"xIsTrackOnly": "{} es de 'Solo Seguimiento'", "xIsTrackOnly": "{} es de 'Sólo seguimiento'",
"source": "Origen", "source": "Origen",
"app": "Aplicación", "app": "Aplicación",
"appsFromSourceAreTrackOnly": "Las aplicaciones de este origen son de 'Solo Seguimiento'.", "appsFromSourceAreTrackOnly": "Las aplicaciones de este origen son de 'solo seguimiento'.",
"youPickedTrackOnly": "Debe seleccionar la opción de 'Solo Seguimiento'.", "youPickedTrackOnly": "Debe seleccionar la opción de 'solo seguimiento'.",
"trackOnlyAppDescription": "Se hará el seguimiento de actualizaciones para la aplicación, pero Obtainium no será capaz de descargarla o actalizarla.", "trackOnlyAppDescription": "Se hará el seguimiento de actualizaciones para la aplicación, pero Obtainium no será capaz de descargarla o actalizarla.",
"cancelled": "Cancelado", "cancelled": "Cancelado",
"appAlreadyAdded": "Aplicación ya añadida", "appAlreadyAdded": "Aplicación ya añadida",
@ -42,7 +42,7 @@
"search": "Buscar", "search": "Buscar",
"additionalOptsFor": "Opciones Adicionales para {}", "additionalOptsFor": "Opciones Adicionales para {}",
"supportedSources": "Fuentes Soportadas", "supportedSources": "Fuentes Soportadas",
"trackOnlyInBrackets": "(Solo Seguimiento)", "trackOnlyInBrackets": "(Solo seguimiento)",
"searchableInBrackets": "(soporta búsqueda)", "searchableInBrackets": "(soporta búsqueda)",
"appsString": "Aplicaciones", "appsString": "Aplicaciones",
"noApps": "Sin Aplicaciones", "noApps": "Sin Aplicaciones",
@ -61,27 +61,27 @@
"removeSelectedApps": "Eliminar Aplicaciones Seleccionadas", "removeSelectedApps": "Eliminar Aplicaciones Seleccionadas",
"updateX": "Actualizar {}", "updateX": "Actualizar {}",
"installX": "Instalar {}", "installX": "Instalar {}",
"markXTrackOnlyAsUpdated": "Marcar {}\n(Solo Seguimiento)\ncomo Actualizada", "markXTrackOnlyAsUpdated": "Marcar {}\n(Solo seguimiento)\ncomo actualizada",
"changeX": "Cambiar {}", "changeX": "Cambiar {}",
"installUpdateApps": "Instalar/Actualizar Aplicaciones", "installUpdateApps": "Instalar/Actualizar aplicaciones",
"installUpdateSelectedApps": "Instalar/Actualizar Aplicaciones Seleccionadas", "installUpdateSelectedApps": "Instalar/Actualizar aplicaciones seleccionadas",
"markXSelectedAppsAsUpdated": "¿Marcar {} Aplicaciones Seleccionadas como Actualizadas?", "markXSelectedAppsAsUpdated": "¿Marcar {} aplicaciones seleccionadas como actualizadas?",
"no": "No", "no": "No",
"yes": "Sí", "yes": "Sí",
"markSelectedAppsUpdated": "Marcar Aplicaciones Seleccionadas como Actualizadas", "markSelectedAppsUpdated": "Marcar aplicaciones seleccionadas como actualizadas",
"pinToTop": "Fijar arriba", "pinToTop": "Fijar arriba",
"unpinFromTop": "Desfijar de arriba", "unpinFromTop": "Desfijar de arriba",
"resetInstallStatusForSelectedAppsQuestion": "¿Restuarar Estado de Instalación para las Aplicaciones Seleccionadas?", "resetInstallStatusForSelectedAppsQuestion": "¿Restuarar estado de instalación para las aplicaciones seleccionadas?",
"installStatusOfXWillBeResetExplanation": "El estado de instalación de las aplicaciones seleccionadas será restaurado.\n\nEsto puede ser de útil cuando la versión de la aplicación mostrada en Obtainium es incorrecta por actualizaciones fallidas u otros motivos.", "installStatusOfXWillBeResetExplanation": "El estado de instalación de las aplicaciones seleccionadas será restaurado.\n\nEsto puede ser de útil cuando la versión de la aplicación mostrada en Obtainium es incorrecta por actualizaciones fallidas u otros motivos.",
"shareSelectedAppURLs": "Compartir URLs de las Aplicaciones Seleccionadas", "shareSelectedAppURLs": "Compartir URLs de las aplicaciones seleccionadas",
"resetInstallStatus": "Restaurar Estado de Instalación", "resetInstallStatus": "Restaurar Estado de Instalación",
"more": "Más", "more": "Más",
"removeOutdatedFilter": "Elimiar Filtro de Aplicaciones Desactualizado", "removeOutdatedFilter": "Elimiar filtro de aplicaciones desactualizado",
"showOutdatedOnly": "Mostrar solo Aplicaciones Desactualizadas", "showOutdatedOnly": "Mostrar solo aplicaciones desactualizadas",
"filter": "Filtrar", "filter": "Filtrar",
"filterActive": "Filtrar *", "filterActive": "Filtrar *",
"filterApps": "Filtrar Actualizaciones", "filterApps": "Filtrar Actualizaciones",
"appName": "Nombre de la Aplicación", "appName": "Nombre de la aplicación",
"author": "Autor", "author": "Autor",
"upToDateApps": "Aplicaciones Actualizadas", "upToDateApps": "Aplicaciones Actualizadas",
"nonInstalledApps": "Aplicaciones No Instaladas", "nonInstalledApps": "Aplicaciones No Instaladas",
@ -103,14 +103,13 @@
"importErrors": "Errores de Importación", "importErrors": "Errores de Importación",
"importedXOfYApps": "{} de {} Aplicaciones importadas.", "importedXOfYApps": "{} de {} Aplicaciones importadas.",
"followingURLsHadErrors": "Las siguientes URLs han tenido problemas:", "followingURLsHadErrors": "Las siguientes URLs han tenido problemas:",
"okay": "Aceptar",
"selectURL": "Seleccionar URL", "selectURL": "Seleccionar URL",
"selectURLs": "Seleccionar URLs", "selectURLs": "Seleccionar URLs",
"pick": "Escoger", "pick": "Escoger",
"theme": "Tema", "theme": "Tema",
"dark": "Oscuro", "dark": "Oscuro",
"light": "Claro", "light": "Claro",
"followSystem": "Seguir al Sistema", "followSystem": "Seguir al sistema",
"obtainium": "Obtainium", "obtainium": "Obtainium",
"materialYou": "Material You", "materialYou": "Material You",
"useBlackTheme": "Negro puro en tema Oscuro", "useBlackTheme": "Negro puro en tema Oscuro",
@ -121,16 +120,16 @@
"appSortOrder": "Orden de Clasificación", "appSortOrder": "Orden de Clasificación",
"ascending": "Ascendente", "ascending": "Ascendente",
"descending": "Descendente", "descending": "Descendente",
"bgUpdateCheckInterval": "Intervalo de Comprobación de Actualizaciones en Segundo Plano", "bgUpdateCheckInterval": "Comprobación actualizaciones en segundo plano",
"neverManualOnly": "Nunca - Solo Manual", "neverManualOnly": "Nunca, solo manual",
"appearance": "Apariencia", "appearance": "Apariencia",
"showWebInAppView": "Mostrar Vista de la Web de Origen", "showWebInAppView": "Mostrar vista de la web de origen",
"pinUpdates": "Fijar Actualizaciones en la Parte Superior de la Vista de Aplicaciones", "pinUpdates": "Fijar Actualizaciones al principio",
"updates": "Actualizaciones", "updates": "Actualizaciones",
"sourceSpecific": "Fuente Específica", "sourceSpecific": "Fuente Específica",
"appSource": "Fuente de la Aplicación", "appSource": "Obtainium en GitHub",
"noLogs": "Sin Logs", "noLogs": "Sin Logs",
"appLogs": "Logs de la Aplicación", "appLogs": "Logs",
"close": "Cerrar", "close": "Cerrar",
"share": "Compartir", "share": "Compartir",
"appNotFound": "Aplicación no encontrada", "appNotFound": "Aplicación no encontrada",
@ -214,30 +213,30 @@
"importFromURLsInFile": "Importar URLs desde archivo (como OPML)", "importFromURLsInFile": "Importar URLs desde archivo (como OPML)",
"versionDetection": "Detección de Versiones", "versionDetection": "Detección de Versiones",
"standardVersionDetection": "Por versión", "standardVersionDetection": "Por versión",
"groupByCategory": "Agrupar por Categoría", "groupByCategory": "Agrupar por categoría",
"autoApkFilterByArch": "Filtrar APKs por arquitectura del procesador, si es posible", "autoApkFilterByArch": "Filtrar APKs por arquitectura del procesador (si es posible)",
"overrideSource": "Sobrescribir Fuente", "overrideSource": "Sobrescribir Fuente",
"dontShowAgain": "No mostrar de nuevo", "dontShowAgain": "No mostrar de nuevo",
"dontShowTrackOnlyWarnings": "No mostrar avisos de 'Solo Seguimiento'", "dontShowTrackOnlyWarnings": "No mostrar avisos sobre apps en 'solo seguimiento'",
"dontShowAPKOriginWarnings": "No mostrar avisos de las fuentes de las APKs", "dontShowAPKOriginWarnings": "No mostrar avisos sobre las fuentes de las APKs",
"moveNonInstalledAppsToBottom": "Mover Apps no instaladas en la Parte Inferior de la Vista de Aplicaciones", "moveNonInstalledAppsToBottom": "Mover Apps no instaladas al final",
"gitlabPATLabel": "Token GitLab de Acceso Personal\n(Habilita la Búsqueda y Mejor Detección de APKs)", "gitlabPATLabel": "Token GitLab de acceso personal\n(habilita la búsqueda y mejor detección de APKs)",
"about": "Acerca", "about": "Acerca",
"requiresCredentialsInSettings": "{}: Esto requiere credenciales adicionales (en Ajustes)", "requiresCredentialsInSettings": "{}: Esto requiere credenciales adicionales (en ajustes)",
"checkOnStart": "Comprobar actualizaciones durante el inicio", "checkOnStart": "Comprobar actualizaciones al inicio",
"tryInferAppIdFromCode": "Intentar deducir la ID de la APP por el código fuente", "tryInferAppIdFromCode": "Intentar deducir la ID de la app por el código fuente",
"removeOnExternalUninstall": "Auto eliminar Apps desinstaladas externamente", "removeOnExternalUninstall": "Auto eliminar apps desinstaladas externamente",
"pickHighestVersionCode": "Auto selección versión superior del código APK", "pickHighestVersionCode": "Auto selección versión superior del código APK",
"checkUpdateOnDetailPage": "Comprobar actualizaciones al abrir detalles de la App", "checkUpdateOnDetailPage": "Comprobar actualizaciones al abrir detalles de la app",
"disablePageTransitions": "Deshabilitar animaciones de transición de la página", "disablePageTransitions": "Deshabilitar animaciones de transición",
"reversePageTransitions": "Invertir animaciones de transición de la página", "reversePageTransitions": "Invertir animaciones de transición",
"minStarCount": "Número Mínimo de Estrellas", "minStarCount": "Número Mínimo de Estrellas",
"addInfoBelow": "Añadir esta información debajo.", "addInfoBelow": "Añadir esta información debajo.",
"addInfoInSettings": "Puede añadir esta información en Ajustes.", "addInfoInSettings": "Puede añadir esta información en Ajustes.",
"githubSourceNote": "La limitación de velocidad de GitHub puede evitarse con una clave API.", "githubSourceNote": "La limitación de velocidad de GitHub puede evitarse con una clave API.",
"gitlabSourceNote": "La extracción de APK de GitLab podría no funcionar sin una clave API.", "gitlabSourceNote": "La extracción de APK de GitLab podría no funcionar sin una clave API.",
"sortByLastLinkSegment": "Sort by only the last segment of the link", "sortByLastLinkSegment": "Sort by only the last segment of the link",
"filterReleaseNotesByRegEx": "Filtrar por notas de nersión (release notes)", "filterReleaseNotesByRegEx": "Filtrar por notas de versión (release notes)",
"customLinkFilterRegex": "Filtro personalizado de Enlace APK (por defecto '.apk$')", "customLinkFilterRegex": "Filtro personalizado de Enlace APK (por defecto '.apk$')",
"appsPossiblyUpdated": "Actualización de Apps intentada", "appsPossiblyUpdated": "Actualización de Apps intentada",
"appsPossiblyUpdatedNotifDescription": "Notifica al usuario que las actualizaciones en segundo plano podrían haberse realizado para una o más aplicaciones", "appsPossiblyUpdatedNotifDescription": "Notifica al usuario que las actualizaciones en segundo plano podrían haberse realizado para una o más aplicaciones",
@ -245,7 +244,7 @@
"enableBackgroundUpdates": "Habilitar actualizaciones en segundo plano", "enableBackgroundUpdates": "Habilitar actualizaciones en segundo plano",
"backgroundUpdateReqsExplanation": "Las actualizaciones en segundo plano pueden no estar disponibles para todas las aplicaciones.", "backgroundUpdateReqsExplanation": "Las actualizaciones en segundo plano pueden no estar disponibles para todas las aplicaciones.",
"backgroundUpdateLimitsExplanation": "El éxito de las instalaciones en segundo plano solo se puede comprobar con Obtainium abierto.", "backgroundUpdateLimitsExplanation": "El éxito de las instalaciones en segundo plano solo se puede comprobar con Obtainium abierto.",
"verifyLatestTag": "Comprueba la etiqueta 'Latest'", "verifyLatestTag": "Comprobar la etiqueta 'Latest'",
"intermediateLinkRegex": "Filtrar por enlace 'intermedio' para visitar primero", "intermediateLinkRegex": "Filtrar por enlace 'intermedio' para visitar primero",
"filterByLinkText": "Filter links by link text", "filterByLinkText": "Filter links by link text",
"intermediateLinkNotFound": "Enlace intermedio no encontrado", "intermediateLinkNotFound": "Enlace intermedio no encontrado",
@ -253,10 +252,10 @@
"exemptFromBackgroundUpdates": "Exenta de actualizciones en segundo plano (si están habilitadas)", "exemptFromBackgroundUpdates": "Exenta de actualizciones en segundo plano (si están habilitadas)",
"bgUpdatesOnWiFiOnly": "Deshabilitar las actualizaciones en segundo plano sin WiFi", "bgUpdatesOnWiFiOnly": "Deshabilitar las actualizaciones en segundo plano sin WiFi",
"autoSelectHighestVersionCode": "Auto Selección de la versionCode APK superior", "autoSelectHighestVersionCode": "Auto Selección de la versionCode APK superior",
"versionExtractionRegEx": "Versión de Extracción de RegEx", "versionExtractionRegEx": "Versión de extracción regex",
"matchGroupToUse": "Coincidir en Grupo a Usar", "matchGroupToUse": "Grupo a usar para versión de extracción regex",
"highlightTouchTargets": "Resaltar objetivos menos obvios", "highlightTouchTargets": "Resaltar objetivos menos obvios",
"pickExportDir": "Selecciona el Directorio para Exportar", "pickExportDir": "Directorio para Exportar",
"autoExportOnChanges": "Auto Exportar cuando haya cambios", "autoExportOnChanges": "Auto Exportar cuando haya cambios",
"includeSettings": "Incluir ajustes", "includeSettings": "Incluir ajustes",
"filterVersionsByRegEx": "Filtrar por Versiones", "filterVersionsByRegEx": "Filtrar por Versiones",
@ -268,21 +267,26 @@
"debugMenu": "Menu Depurar", "debugMenu": "Menu Depurar",
"bgTaskStarted": "Iniciada tarea en segundo plano - revisa los logs.", "bgTaskStarted": "Iniciada tarea en segundo plano - revisa los logs.",
"runBgCheckNow": "Ejecutar verficiación de actualizaciones en segundo plano", "runBgCheckNow": "Ejecutar verficiación de actualizaciones en segundo plano",
"versionExtractWholePage": "Aplicar la Versión de Extracción Regex a la Página Entera", "versionExtractWholePage": "Aplicar la versión de extracción regex a la página entera",
"installing": "Instalando", "installing": "Instalando",
"skipUpdateNotifications": "Omitir de notificaciones sobre actualizaciones", "skipUpdateNotifications": "No notificar sobre actualizaciones",
"updatesAvailableNotifChannel": "Actualizaciones Disponibles", "updatesAvailableNotifChannel": "Actualizaciones disponibles",
"appsUpdatedNotifChannel": "Aplicaciones Actualizadas", "appsUpdatedNotifChannel": "Aplicaciones actualizadas",
"appsPossiblyUpdatedNotifChannel": "Se ha Intentado Actualizar la Aplicación", "appsPossiblyUpdatedNotifChannel": "Se ha intentado actualizar la aplicación",
"errorCheckingUpdatesNotifChannel": "Error Buscando Actualizaciones", "errorCheckingUpdatesNotifChannel": "Error buscando actualizaciones",
"appsRemovedNotifChannel": "Aplicaciones Eliminadas", "appsRemovedNotifChannel": "Aplicaciones eliminadas",
"downloadingXNotifChannel": "Descargando {}", "downloadingXNotifChannel": "Descargando {}",
"completeAppInstallationNotifChannel": "Instalación Completa de la Aplicación", "completeAppInstallationNotifChannel": "Instalación completada",
"checkingForUpdatesNotifChannel": "Buscando Actualizaciones", "checkingForUpdatesNotifChannel": "Buscando actualizaciones",
"onlyCheckInstalledOrTrackOnlyApps": "Comprobar actualizaciones solo para apps instaladas y en seguimiento", "onlyCheckInstalledOrTrackOnlyApps": "Comprobar actualizaciones solo para apps instaladas o en seguimiento",
"supportFixedAPKURL": "Soporte para URLs fijas de APK", "supportFixedAPKURL": "Soporte para URLs fijas de APK",
"selectX": "Selecciona {}", "selectX": "Selecciona {}",
"parallelDownloads": "Permitir descargas paralelas", "parallelDownloads": "Permitir descargas paralelas",
"installMethod": "Método de instalación",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku no está operativo",
"removeAppQuestion": { "removeAppQuestion": {
"one": "¿Eliminar Aplicación?", "one": "¿Eliminar Aplicación?",
"other": "¿Eliminar Aplicaciones?" "other": "¿Eliminar Aplicaciones?"
@ -308,16 +312,16 @@
"other": "{} URLs" "other": "{} URLs"
}, },
"minute": { "minute": {
"one": "{} Minuto", "one": "{} minuto",
"other": "{} Minutos" "other": "{} minutos"
}, },
"hour": { "hour": {
"one": "{} Hora", "one": "{} hora",
"other": "{} Horas" "other": "{} horas"
}, },
"day": { "day": {
"one": "{} Día", "one": "{} día",
"other": "{} Días" "other": "{} días"
}, },
"clearedNLogsBeforeXAfterY": { "clearedNLogsBeforeXAfterY": {
"one": "Eliminado {n} log (previo a = {before}, posterior a = {after})", "one": "Eliminado {n} log (previo a = {before}, posterior a = {after})",

View File

@ -103,7 +103,6 @@
"importErrors": "خطاهای وارد کردن", "importErrors": "خطاهای وارد کردن",
"importedXOfYApps": "{} از {} برنامه وارد شد.", "importedXOfYApps": "{} از {} برنامه وارد شد.",
"followingURLsHadErrors": "آدرس های اینترنتی زیر دارای خطا بودند:", "followingURLsHadErrors": "آدرس های اینترنتی زیر دارای خطا بودند:",
"okay": "باشه",
"selectURL": "آدرس اینترنتی انتخاب شده", "selectURL": "آدرس اینترنتی انتخاب شده",
"selectURLs": "آدرس های اینترنتی انتخاب شده", "selectURLs": "آدرس های اینترنتی انتخاب شده",
"pick": "انتخاب", "pick": "انتخاب",
@ -283,6 +282,11 @@
"supportFixedAPKURL": "پشتیبانی از URL های APK ثابت", "supportFixedAPKURL": "پشتیبانی از URL های APK ثابت",
"selectX": "انتخاب کنید {}", "selectX": "انتخاب کنید {}",
"parallelDownloads": "Allow parallel downloads", "parallelDownloads": "Allow parallel downloads",
"installMethod": "Installation method",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku is not running",
"removeAppQuestion": { "removeAppQuestion": {
"one": "برنامه حذف شود؟", "one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟" "other": "برنامه ها حذف شوند؟"

View File

@ -103,7 +103,6 @@
"importErrors": "Erreurs d'importation", "importErrors": "Erreurs d'importation",
"importedXOfYApps": "{} sur {} applications importées.", "importedXOfYApps": "{} sur {} applications importées.",
"followingURLsHadErrors": "Les URL suivantes comportaient des erreurs :", "followingURLsHadErrors": "Les URL suivantes comportaient des erreurs :",
"okay": "Okay",
"selectURL": "Sélectionnez l'URL", "selectURL": "Sélectionnez l'URL",
"selectURLs": "Sélectionnez les URLs", "selectURLs": "Sélectionnez les URLs",
"pick": "Prendre", "pick": "Prendre",
@ -283,6 +282,11 @@
"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",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku is not running",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Supprimer l'application ?", "one": "Supprimer l'application ?",
"other": "Supprimer les applications ?" "other": "Supprimer les applications ?"
@ -335,4 +339,4 @@
"one": "{} and 1 more app may have been updated.", "one": "{} and 1 more app may have been updated.",
"other": "{} and {} more apps may have been updated." "other": "{} and {} more apps may have been updated."
} }
} }

View File

@ -103,7 +103,6 @@
"importErrors": "Importálási hibák", "importErrors": "Importálási hibák",
"importedXOfYApps": "{}/{} app importálva.", "importedXOfYApps": "{}/{} app importálva.",
"followingURLsHadErrors": "A következő URL-ek hibákat tartalmaztak:", "followingURLsHadErrors": "A következő URL-ek hibákat tartalmaztak:",
"okay": "Oké",
"selectURL": "Válassza ki az URL-t", "selectURL": "Válassza ki az URL-t",
"selectURLs": "Kiválasztott URL-ek", "selectURLs": "Kiválasztott URL-ek",
"pick": "Válasszon", "pick": "Válasszon",
@ -236,7 +235,7 @@
"addInfoInSettings": "Adja hozzá ezt az infót a Beállításokban.", "addInfoInSettings": "Adja hozzá ezt az infót a Beállításokban.",
"githubSourceNote": "A GitHub sebességkorlátozás elkerülhető API-kulcs használatával.", "githubSourceNote": "A GitHub sebességkorlátozás elkerülhető API-kulcs használatával.",
"gitlabSourceNote": "Előfordulhat, hogy a GitLab APK kibontása nem működik API-kulcs nélkül.", "gitlabSourceNote": "Előfordulhat, hogy a GitLab APK kibontása nem működik API-kulcs nélkül.",
"sortByLastLinkSegment": "Sort by only the last segment of the link", "sortByLastLinkSegment": "Rendezés csak a link utolsó szegmense szerint",
"filterReleaseNotesByRegEx": "Kiadási megjegyzések szűrése reguláris kifejezéssel", "filterReleaseNotesByRegEx": "Kiadási megjegyzések szűrése reguláris kifejezéssel",
"customLinkFilterRegex": "Egyéni APK hivatkozásszűrő reguláris kifejezéssel (Alapérték '.apk$')", "customLinkFilterRegex": "Egyéni APK hivatkozásszűrő reguláris kifejezéssel (Alapérték '.apk$')",
"appsPossiblyUpdated": "App frissítési kísérlet", "appsPossiblyUpdated": "App frissítési kísérlet",
@ -282,7 +281,12 @@
"onlyCheckInstalledOrTrackOnlyApps": "Csak a telepített és a csak követhető appokat ellenőrizze frissítésekért", "onlyCheckInstalledOrTrackOnlyApps": "Csak a telepített és a csak követhető appokat ellenőrizze frissítésekért",
"supportFixedAPKURL": "Támogatja a rögzített APK URL-eket", "supportFixedAPKURL": "Támogatja a rögzített APK URL-eket",
"selectX": "Kiválaszt {}", "selectX": "Kiválaszt {}",
"parallelDownloads": "Allow parallel downloads", "parallelDownloads": "Párhuzamos letöltéseket enged",
"installMethod": "Installation method",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku is not running",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?", "one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazást?" "other": "Eltávolítja az alkalmazást?"

View File

@ -103,7 +103,6 @@
"importErrors": "Errori di importazione", "importErrors": "Errori di importazione",
"importedXOfYApps": "{} app di {} importate.", "importedXOfYApps": "{} app di {} importate.",
"followingURLsHadErrors": "I seguenti URL contengono errori:", "followingURLsHadErrors": "I seguenti URL contengono errori:",
"okay": "Va bene",
"selectURL": "Seleziona l'URL", "selectURL": "Seleziona l'URL",
"selectURLs": "Seleziona gli URL", "selectURLs": "Seleziona gli URL",
"pick": "Seleziona", "pick": "Seleziona",

View File

@ -103,7 +103,6 @@
"importErrors": "インポートエラー", "importErrors": "インポートエラー",
"importedXOfYApps": "{} / {} アプリをインポートしました", "importedXOfYApps": "{} / {} アプリをインポートしました",
"followingURLsHadErrors": "以下のURLでエラーが発生しました:", "followingURLsHadErrors": "以下のURLでエラーが発生しました:",
"okay": "OK",
"selectURL": "URLを選択", "selectURL": "URLを選択",
"selectURLs": "URLを選択", "selectURLs": "URLを選択",
"pick": "選択", "pick": "選択",
@ -236,7 +235,7 @@
"addInfoInSettings": "設定でこの情報を追加してください。", "addInfoInSettings": "設定でこの情報を追加してください。",
"githubSourceNote": "GitHubのレート制限はAPIキーを使うことで回避できます。", "githubSourceNote": "GitHubのレート制限はAPIキーを使うことで回避できます。",
"gitlabSourceNote": "GitLabのAPK抽出はAPIキーがないと動作しない場合があります。", "gitlabSourceNote": "GitLabのAPK抽出はAPIキーがないと動作しない場合があります。",
"sortByLastLinkSegment": "Sort by only the last segment of the link", "sortByLastLinkSegment": "リンクの最後のセグメントのみでソートする",
"filterReleaseNotesByRegEx": "正規表現でリリースノートをフィルタリングする", "filterReleaseNotesByRegEx": "正規表現でリリースノートをフィルタリングする",
"customLinkFilterRegex": "正規表現によるカスタムリンクフィルター (デフォルト '.apk$')", "customLinkFilterRegex": "正規表現によるカスタムリンクフィルター (デフォルト '.apk$')",
"appsPossiblyUpdated": "アプリのアップデートを試行", "appsPossiblyUpdated": "アプリのアップデートを試行",
@ -246,10 +245,10 @@
"backgroundUpdateReqsExplanation": "バックグラウンドアップデートは、すべてのアプリで可能とは限りません。", "backgroundUpdateReqsExplanation": "バックグラウンドアップデートは、すべてのアプリで可能とは限りません。",
"backgroundUpdateLimitsExplanation": "バックグラウンドアップデートが成功したかどうかは、Obtainiumを起動したときにしか判断できません。", "backgroundUpdateLimitsExplanation": "バックグラウンドアップデートが成功したかどうかは、Obtainiumを起動したときにしか判断できません。",
"verifyLatestTag": "'latest'タグを確認する", "verifyLatestTag": "'latest'タグを確認する",
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit", "intermediateLinkRegex": "訪問する「中間」リンクのフィルター",
"filterByLinkText": "Filter links by link text", "filterByLinkText": "テキストでリンクをフィルタリングする",
"intermediateLinkNotFound": "中間リンクが見つかりませんでした", "intermediateLinkNotFound": "中間リンクが見つかりませんでした",
"intermediateLink": "Intermediate link", "intermediateLink": "中間リンク",
"exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)", "exemptFromBackgroundUpdates": "バックグラウンドアップデートを行わない (有効な場合)",
"bgUpdatesOnWiFiOnly": "WiFiを使用していない場合バックグラウンドアップデートを無効にする", "bgUpdatesOnWiFiOnly": "WiFiを使用していない場合バックグラウンドアップデートを無効にする",
"autoSelectHighestVersionCode": "最も高いバージョンコードのAPKを自動で選択する", "autoSelectHighestVersionCode": "最も高いバージョンコードのAPKを自動で選択する",
@ -263,8 +262,8 @@
"trySelectingSuggestedVersionCode": "提案されたバージョンコードのAPKを選択する", "trySelectingSuggestedVersionCode": "提案されたバージョンコードのAPKを選択する",
"dontSortReleasesList": "APIからのリリース順を保持する", "dontSortReleasesList": "APIからのリリース順を保持する",
"reverseSort": "逆順ソート", "reverseSort": "逆順ソート",
"takeFirstLink": "Take first link", "takeFirstLink": "最初のリンクを取得する",
"skipSort": "Skip sorting", "skipSort": "ソートをスキップする",
"debugMenu": "デバッグメニュー", "debugMenu": "デバッグメニュー",
"bgTaskStarted": "バックグラウンドタスクが開始されました - ログを確認してください。", "bgTaskStarted": "バックグラウンドタスクが開始されました - ログを確認してください。",
"runBgCheckNow": "今すぐバックグラウンドでのアップデート確認を開始する", "runBgCheckNow": "今すぐバックグラウンドでのアップデート確認を開始する",
@ -280,9 +279,14 @@
"completeAppInstallationNotifChannel": "アプリのインストールを完了する", "completeAppInstallationNotifChannel": "アプリのインストールを完了する",
"checkingForUpdatesNotifChannel": "アップデートを確認中", "checkingForUpdatesNotifChannel": "アップデートを確認中",
"onlyCheckInstalledOrTrackOnlyApps": "インストール済みのアプリと「追跡のみ」のアプリのアップデートのみを確認する", "onlyCheckInstalledOrTrackOnlyApps": "インストール済みのアプリと「追跡のみ」のアプリのアップデートのみを確認する",
"supportFixedAPKURL": "Support fixed APK URLs", "supportFixedAPKURL": "固定されたAPKURLをサポートする",
"selectX": "Select {}", "selectX": "{} 選択",
"parallelDownloads": "Allow parallel downloads", "parallelDownloads": "並行ダウンロードを許可する",
"installMethod": "インストール方法",
"normal": "通常",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizukuが起動していません",
"removeAppQuestion": { "removeAppQuestion": {
"one": "アプリを削除しますか?", "one": "アプリを削除しますか?",
"other": "アプリを削除しますか?" "other": "アプリを削除しますか?"
@ -335,4 +339,4 @@
"one": "{} とさらに 1 個のアプリがアップデートされた可能性があります。", "one": "{} とさらに 1 個のアプリがアップデートされた可能性があります。",
"other": "{} とさらに {} 個のアプリがアップデートされた可能性があります。" "other": "{} とさらに {} 個のアプリがアップデートされた可能性があります。"
} }
} }

View File

@ -103,7 +103,6 @@
"importErrors": "Import foutmeldingen", "importErrors": "Import foutmeldingen",
"importedXOfYApps": "{} van {} apps geïmporteerd.", "importedXOfYApps": "{} van {} apps geïmporteerd.",
"followingURLsHadErrors": "De volgende URL's bevatten fouten:", "followingURLsHadErrors": "De volgende URL's bevatten fouten:",
"okay": "Ok",
"selectURL": "Selecteer URL", "selectURL": "Selecteer URL",
"selectURLs": "Selecteer URL's", "selectURLs": "Selecteer URL's",
"pick": "Kies", "pick": "Kies",
@ -283,6 +282,11 @@
"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",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku is not running",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App verwijderen?", "one": "App verwijderen?",
"other": "Apps verwijderen?" "other": "Apps verwijderen?"

View File

@ -103,7 +103,6 @@
"importErrors": "Błędy importowania", "importErrors": "Błędy importowania",
"importedXOfYApps": "Zaimportowano {} z {} aplikacji.", "importedXOfYApps": "Zaimportowano {} z {} aplikacji.",
"followingURLsHadErrors": "Następujące adresy URL zawierały błędy:", "followingURLsHadErrors": "Następujące adresy URL zawierały błędy:",
"okay": "Okej",
"selectURL": "Wybierz adres URL", "selectURL": "Wybierz adres URL",
"selectURLs": "Wybierz adresy URL", "selectURLs": "Wybierz adresy URL",
"pick": "Wybierz", "pick": "Wybierz",
@ -283,6 +282,11 @@
"supportFixedAPKURL": "Obsługuj stałe adresy URL APK", "supportFixedAPKURL": "Obsługuj stałe adresy URL APK",
"selectX": "Wybierz {}", "selectX": "Wybierz {}",
"parallelDownloads": "Allow parallel downloads", "parallelDownloads": "Allow parallel downloads",
"installMethod": "Installation method",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku is not running",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Usunąć aplikację?", "one": "Usunąć aplikację?",
"few": "Usunąć aplikacje?", "few": "Usunąć aplikacje?",
@ -361,4 +365,4 @@
"many": "{} i {} innych apek mogło zostać zaktualizowanych.", "many": "{} i {} innych apek mogło zostać zaktualizowanych.",
"other": "{} i {} inne apki mogły zostać zaktualizowane." "other": "{} i {} inne apki mogły zostać zaktualizowane."
} }
} }

View File

@ -1,21 +1,21 @@
{ {
"invalidURLForSource": "URL {} inválida", "invalidURLForSource": "URL {} inválida",
"noReleaseFound": "Não foi possivel encontrar uma versão adequada", "noReleaseFound": "Não foi possível encontrar uma versão adequada",
"noVersionFound": "Não foi possivel encontrar uma versão lançada", "noVersionFound": "Não foi possível encontrar uma versão",
"urlMatchesNoSource": "URL não corresponde a uma fonte conhecida", "urlMatchesNoSource": "URL não corresponde a uma fonte conhecida",
"cantInstallOlderVersion": "Não pode instalar uma versão anterior de um App", "cantInstallOlderVersion": "Não é permitido instalar uma versão anterior de um aplicativo",
"appIdMismatch": "ID do pacote baixado não é igual ao ID do App instalado", "appIdMismatch": "ID do pacote baixado não é igual ao ID do aplicativo instalado",
"functionNotImplemented": "Esta classe não implementou essa função", "functionNotImplemented": "Esta classe não implementou essa função",
"placeholder": "Espaço Reservado", "placeholder": "Espaço reservado",
"someErrors": "Alguns Erros Ocorreram", "someErrors": "Alguns erros ocorreram",
"unexpectedError": "Erro Inesperado", "unexpectedError": "Erro inesperado",
"ok": "Ok", "ok": "OK",
"and": "e", "and": "e",
"githubPATLabel": "Token de Acceso Pessoal do GitHub (Reduz tempos de espera)", "githubPATLabel": "Token de acesso pessoal do GitHub (Reduz tempos de espera)",
"includePrereleases": "Incluir pré-lançamentos", "includePrereleases": "Incluir pré-lançamentos",
"fallbackToOlderReleases": "Retornar para versões anteriores", "fallbackToOlderReleases": "Retornar para versões anteriores",
"filterReleaseTitlesByRegEx": "Filtrar Titulos de Versões por Expressão Regular", "filterReleaseTitlesByRegEx": "Filtrar tulos de versões por expressão regular",
"invalidRegEx": "Expressão Regular Inválida", "invalidRegEx": "Expressão regular inválida",
"noDescription": "Sem descrição", "noDescription": "Sem descrição",
"cancel": "Cancelar", "cancel": "Cancelar",
"continue": "Continuar", "continue": "Continuar",
@ -25,66 +25,66 @@
"githubStarredRepos": "Favoritados no GitHub", "githubStarredRepos": "Favoritados no GitHub",
"uname": "Nome de usuário", "uname": "Nome de usuário",
"wrongArgNum": "Número de argumentos errado", "wrongArgNum": "Número de argumentos errado",
"xIsTrackOnly": "{} é 'Apenas Seguir'", "xIsTrackOnly": "{} é 'Apenas monitorar'",
"source": "Fonte", "source": "Fonte",
"app": "App", "app": "Aplicativo",
"appsFromSourceAreTrackOnly": "Os apps desta fonte são 'Apenas Seguir'.", "appsFromSourceAreTrackOnly": "Os aplicativos desta fonte são 'Apenas monitorar'.",
"youPickedTrackOnly": "Você selecionou a opção 'Apenas Seguir'.", "youPickedTrackOnly": "Você selecionou a opção 'Apenas monitorar'.",
"trackOnlyAppDescription": "Esse App vai ser seguido por atualizações, mais o Obtainium não poderá baixa-lo ou instala-lo.", "trackOnlyAppDescription": "As atualizações desse aplicativo serão monitoradas, mas o Obtainium não poderá baixá-lo ou instalá-lo.",
"cancelled": "Cancelado", "cancelled": "Cancelado",
"appAlreadyAdded": "App já adicionado", "appAlreadyAdded": "Aplicativo já adicionado",
"alreadyUpToDateQuestion": "App já atualizado?", "alreadyUpToDateQuestion": "Aplicativo já foi atualizado?",
"addApp": "Adicionar App", "addApp": "Adicionar aplicativo",
"appSourceURL": "URL de origem do App", "appSourceURL": "URL de origem do aplicativo",
"error": "Erro", "error": "Erro",
"add": "Adicionar", "add": "Adicionar",
"searchSomeSourcesLabel": "Procurar (Apenas Algumas Fontes)", "searchSomeSourcesLabel": "Procurar (Apenas algumas fontes)",
"search": "Procurar", "search": "Procurar",
"additionalOptsFor": "Opções Adicionais para {}", "additionalOptsFor": "Opções adicionais para {}",
"supportedSources": "Fontes Compatíveis", "supportedSources": "Fontes compatíveis",
"trackOnlyInBrackets": "(Apenas Seguir)", "trackOnlyInBrackets": "(Apenas monitorar)",
"searchableInBrackets": "(Pesquisável)", "searchableInBrackets": "(Pesquisável)",
"appsString": "Apps", "appsString": "Aplicativos",
"noApps": "Sem Apps", "noApps": "Não há aplicativos",
"noAppsForFilter": "Sem Apps para Filtrar", "noAppsForFilter": "Sem aplicativos para filtrar",
"byX": "Por {}", "byX": "Por {}",
"percentProgress": "Progresso: {}%", "percentProgress": "Progresso: {}%",
"pleaseWait": "Por Favor Espere", "pleaseWait": "Por favor, espere",
"updateAvailable": "Atualização Disponível", "updateAvailable": "Atualização disponível",
"estimateInBracketsShort": "(Aprox.)", "estimateInBracketsShort": "(Aprox.)",
"notInstalled": "Não Instalado", "notInstalled": "Não instalado",
"estimateInBrackets": "(Aproximado)", "estimateInBrackets": "(Aproximado)",
"selectAll": "Selecionar All", "selectAll": "Selecionar todos",
"deselectX": "Deselecionar {}", "deselectX": "Deselecionar {}",
"xWillBeRemovedButRemainInstalled": "{} sera removido do Obtainium mais permanecerá instalado no dispositivo.", "xWillBeRemovedButRemainInstalled": "{} será removido do Obtainium mais permanecerá instalado no dispositivo.",
"removeSelectedAppsQuestion": "Remover Apps Selecionados?", "removeSelectedAppsQuestion": "Remover aplicativos selecionados?",
"removeSelectedApps": "Remover Apps Selecionados", "removeSelectedApps": "Remover aplicativos selecionados",
"updateX": "Atualizar {}", "updateX": "Atualizar {}",
"installX": "Instalar {}", "installX": "Instalar {}",
"markXTrackOnlyAsUpdated": "Marcar {}\n(Apenas Seguir)\ncomo Atualizado", "markXTrackOnlyAsUpdated": "Marcar {}\n(Apenas monitorar)\ncomo Atualizado",
"changeX": "Mudar {}", "changeX": "Mudar {}",
"installUpdateApps": "Instalar/Atualizar Apps", "installUpdateApps": "Instalar/Atualizar aplicativos",
"installUpdateSelectedApps": "Instalar/Atualizar Apps Selecionados", "installUpdateSelectedApps": "Instalar/Atualizar aplicativos selecionados",
"markXSelectedAppsAsUpdated": "Marcar {} Apps Delecionados como Atualizados?", "markXSelectedAppsAsUpdated": "Marcar {} aplicativos selecionados como atualizados?",
"no": "Não", "no": "Não",
"yes": "Sim", "yes": "Sim",
"markSelectedAppsUpdated": "Marcar Apps Selecionados como Atualizados", "markSelectedAppsUpdated": "Marcar aplicativos selecionados como Atualizados",
"pinToTop": "Fixar no topo", "pinToTop": "Fixar no topo",
"unpinFromTop": "Desafixar do topo", "unpinFromTop": "Desafixar do topo",
"resetInstallStatusForSelectedAppsQuestion": "Reiniciar Status de Instalação para Apps Seleciondos?", "resetInstallStatusForSelectedAppsQuestion": "Reiniciar status de instalação para aplicativos selecionados?",
"installStatusOfXWillBeResetExplanation": "O status de instalação de qualquer app selecionado sera reiniciado.\n\nIsso pode ajudar quando uma versão de um App mostrada no Obtainium é incorreta devido a falhas ao atualizar ou outros problemas.", "installStatusOfXWillBeResetExplanation": "O status de instalação de qualquer aplicativo selecionado será reiniciado.\n\nIsso pode ajudar quando uma versão de um aplicativo mostrada no Obtainium é incorreta devido a falhas ao atualizar ou outros problemas.",
"shareSelectedAppURLs": "Compartilhar URLs de Apps Selecionados", "shareSelectedAppURLs": "Compartilhar URLs de aplicativos selecionados",
"resetInstallStatus": "Reiniciar Status de Instalação", "resetInstallStatus": "Reiniciar status de Iistalação",
"more": "Mais", "more": "Mais",
"removeOutdatedFilter": "Remover Filtro de Apps Desatualizados", "removeOutdatedFilter": "Remover filtro de aplicativos desatualizados",
"showOutdatedOnly": "Mostrar Apenas Apps Desatualizados", "showOutdatedOnly": "Mostrar apenas aplicativos desatualizados",
"filter": "Filtro", "filter": "Filtro",
"filterActive": "Filtro *", "filterActive": "Filtro *",
"filterApps": "Filtrar Apps", "filterApps": "Filtrar aplicativos",
"appName": "Nome do App", "appName": "Nome do aplicativo",
"author": "Autor", "author": "Autor",
"upToDateApps": "Apps Atualizados", "upToDateApps": "Aplicativos tualizados",
"nonInstalledApps": "Apps Não Instalados", "nonInstalledApps": "Aplicativos não instalados",
"importExport": "Importar/Exportar", "importExport": "Importar/Exportar",
"settings": "Configurações", "settings": "Configurações",
"exportedTo": "Exportado para {}", "exportedTo": "Exportado para {}",
@ -92,143 +92,142 @@
"invalidInput": "Input Inválido", "invalidInput": "Input Inválido",
"importedX": "Importado {}", "importedX": "Importado {}",
"obtainiumImport": "Importar Obtainium", "obtainiumImport": "Importar Obtainium",
"importFromURLList": "Importar de Lista de URLs", "importFromURLList": "Importar de lista de URLs",
"searchQuery": "Pesquisa", "searchQuery": "Pesquisa",
"appURLList": "Lista de URLs de Apps", "appURLList": "Lista de URLs de aplicativos",
"line": "Linha", "line": "Linha",
"searchX": "Pesquisa {}", "searchX": "Pesquisa {}",
"noResults": "Nenhum resultado encontrado", "noResults": "Nenhum resultado encontrado",
"importX": "Importar {}", "importX": "Importar {}",
"importedAppsIdDisclaimer": "Apps Importados podem ser mostrados incorretamente como \"Não Instalado\".\nPara consertar, reinstale-os usando o Obtainium.\nIsso não deve afetar dados do App.\n\nAfeta apenas métodos de importação de URL e de terceiros.", "importedAppsIdDisclaimer": "Aplicativos Importados podem ser mostrados incorretamente como \"Não Instalado\".\nPara consertar, reinstale-os usando o Obtainium.\nIsso não deve afetar dados do aplicativo.\n\nAfeta apenas métodos de importação de URL e de terceiros.",
"importErrors": "Erros de Importação", "importErrors": "Erros de importação",
"importedXOfYApps": "{} de {} Apps importados.", "importedXOfYApps": "{} de {} aplicativos importados.",
"followingURLsHadErrors": "As seguintes URLs apresentaram erros:", "followingURLsHadErrors": "As seguintes URLs apresentaram erros:",
"okay": "Ok",
"selectURL": "Selecionar URL", "selectURL": "Selecionar URL",
"selectURLs": "Selecionar URLs", "selectURLs": "Selecionar URLs",
"pick": "Escolher", "pick": "Escolher",
"theme": "Tema", "theme": "Tema",
"dark": "Escuro", "dark": "Escuro",
"light": "Claro", "light": "Claro",
"followSystem": "Seguir o Sistema", "followSystem": "Seguir o sistema",
"obtainium": "Obtainium", "obtainium": "Obtainium",
"materialYou": "Material You", "materialYou": "Material You",
"useBlackTheme": "Usar tema preto completamente escuro", "useBlackTheme": "Usar tema preto completamente escuro",
"appSortBy": "Classificar App por", "appSortBy": "Classificar aplicativo por",
"authorName": "Autor/Nome", "authorName": "Autor/Nome",
"nameAuthor": "Nome/Autor", "nameAuthor": "Nome/Autor",
"asAdded": "Como Adicionado", "asAdded": "Como adicionado",
"appSortOrder": "Ordem de classificação de Apps", "appSortOrder": "Ordem de classificação de aplicativos",
"ascending": "Ascendente", "ascending": "Ascendente",
"descending": "Descendente", "descending": "Descendente",
"bgUpdateCheckInterval": "Intervalo de verificação de atualizações em segundo plano", "bgUpdateCheckInterval": "Intervalo de verificação de atualizações em segundo-plano",
"neverManualOnly": "Nunca - Apenas Manual", "neverManualOnly": "Nunca - apenas manual",
"appearance": "Aparência", "appearance": "Aparência",
"showWebInAppView": "Mostrar páginas da internet em App view", "showWebInAppView": "Mostrar página da internet em informações do aplicativo",
"pinUpdates": "Fixar atualizações no topo da visão de Apps", "pinUpdates": "Fixar atualizações no topo da janela de aplicativos",
"updates": "Atualizações", "updates": "Atualizações",
"sourceSpecific": "Específico a fonte", "sourceSpecific": "Específico a fonte",
"appSource": "Fonte do App", "appSource": "Fonte do aplicativo",
"noLogs": "Sem Logs", "noLogs": "Sem logs",
"appLogs": "Logs do App", "appLogs": "Logs do aplicativo",
"close": "Fechar", "close": "Fechar",
"share": "Compartilhar", "share": "Compartilhar",
"appNotFound": "App não encontrado", "appNotFound": "Aplicativo não encontrado",
"obtainiumExportHyphenatedLowercase": "obtainium-export", "obtainiumExportHyphenatedLowercase": "obtainium-export",
"pickAnAPK": "Selecionar um APK", "pickAnAPK": "Selecionar um APK",
"appHasMoreThanOnePackage": "{} tem mais de um pacote:", "appHasMoreThanOnePackage": "{} tem mais de um pacote:",
"deviceSupportsXArch": "Seu dispositivo suporta a arquitetura de CPU {}.", "deviceSupportsXArch": "Seu dispositivo suporta a arquitetura de CPU {}.",
"deviceSupportsFollowingArchs": "Seu dispositivo suporta as seguintes arquiteturas de CPU:", "deviceSupportsFollowingArchs": "Seu dispositivo suporta as seguintes arquiteturas de CPU:",
"warning": "Aviso", "warning": "Aviso",
"sourceIsXButPackageFromYPrompt": "A Fonte do App é '{}' mais o pacote lançado vem de '{}'. Continuar?", "sourceIsXButPackageFromYPrompt": "A fonte do aplicativo é '{}' mas a origem do pacote é '{}'. Continuar?",
"updatesAvailable": "Atualizações Disponíveis", "updatesAvailable": "Atualizações disponíveis",
"updatesAvailableNotifDescription": "Notifica o usuário quando atualizações estão disponíveis um ou mais Apps seguidos pelo Obtainium", "updatesAvailableNotifDescription": "Notifica o usuário quando atualizações de um ou mais aplicativos monitorados pelo Obtainium estão disponíveis",
"noNewUpdates": "Sem novas atualizações.", "noNewUpdates": "Sem novas atualizações.",
"xHasAnUpdate": "{} tem uma atualização.", "xHasAnUpdate": "{} tem uma atualização.",
"appsUpdated": "Apps Atualizados", "appsUpdated": "Aplicativos atualizados",
"appsUpdatedNotifDescription": "Notifica o usuário quando atualizações para um ou mais Apps foram aplicadas em segundo plano", "appsUpdatedNotifDescription": "Notifica o usuário quando atualizações foram aplicadas em segundo-plano para um ou mais aplicativos ",
"xWasUpdatedToY": "{} foi atualizado para {}.", "xWasUpdatedToY": "{} foi atualizado para {}.",
"errorCheckingUpdates": "Erro ao Procurar por Atualizações", "errorCheckingUpdates": "Erro ao procurar por atualizações",
"errorCheckingUpdatesNotifDescription": "Uma notificação que mostra quando a checagem por atualizações em segundo plano falha", "errorCheckingUpdatesNotifDescription": "Uma notificação que mostra quando a checagem por atualizações em segundo-plano falha",
"appsRemoved": "Apps Removidos", "appsRemoved": "Aplicativos removidos",
"appsRemovedNotifDescription": "Notifica o usuário quando um ou mais Apps foram removidos devido a erros ao carregá-los", "appsRemovedNotifDescription": "Notifica o usuário quando um ou mais aplicativos foram removidos devido a erros de carregamento",
"xWasRemovedDueToErrorY": "{} foi removido devido a este erro: {}", "xWasRemovedDueToErrorY": "{} foi removido devido a este erro: {}",
"completeAppInstallation": "Instalação completa do App", "completeAppInstallation": "Instalação do aplicativo completa",
"obtainiumMustBeOpenToInstallApps": "Obtainium deve estar aberto para instalar Apps", "obtainiumMustBeOpenToInstallApps": "Obtainium deve estar aberto para instalar os aplicativos",
"completeAppInstallationNotifDescription": "Pede ao usuário que retorne ao Obtainium para finalizar a instalação de um App", "completeAppInstallationNotifDescription": "Pede ao usuário que retorne ao Obtainium para finalizar a instalação de um aplicativo",
"checkingForUpdates": "Checando por Atualizações", "checkingForUpdates": "Verificando atualizações",
"checkingForUpdatesNotifDescription": "Notificação transiente que aparece quando checando por atualizações", "checkingForUpdatesNotifDescription": "Notificação transiente que aparece quando o Obtainium está verificando se há atualizações",
"pleaseAllowInstallPerm": "Por favor, permita o Obtainium instalar Apps", "pleaseAllowInstallPerm": "Por favor, permita que o Obtainium possa instalar aplicativos",
"trackOnly": "Apenas Seguir", "trackOnly": "Apenas monitorar",
"errorWithHttpStatusCode": "Erro {}", "errorWithHttpStatusCode": "Erro {}",
"versionCorrectionDisabled": "Correção de versão desativada (plugin parece não funcionar)", "versionCorrectionDisabled": "Correção de versão desativada (plugin parece não funcionar)",
"unknown": "Desconhecido", "unknown": "Desconhecido",
"none": "Nenhum", "none": "Nenhum",
"never": "Nunca", "never": "Nunca",
"latestVersionX": "Última versão: {}", "latestVersionX": "Última versão: {}",
"installedVersionX": "Versão Instalada: {}", "installedVersionX": "Versão instalada: {}",
"lastUpdateCheckX": "Última Checagem por Atualização: {}", "lastUpdateCheckX": "Última verificação de atualizações: {}",
"remove": "Remover", "remove": "Remover",
"yesMarkUpdated": "Sim, Marcar como Atualizado", "yesMarkUpdated": "Sim, marcar como Atualizado",
"fdroid": "F-Droid Official", "fdroid": "F-Droid Official",
"appIdOrName": "ID do App ou Nome", "appIdOrName": "ID do aplicativo ou nome",
"appId": "ID do App", "appId": "ID do aplicativo",
"appWithIdOrNameNotFound": "Nenhum App foi encontrado com esse ID ou nome", "appWithIdOrNameNotFound": "Nenhum aplicativo foi encontrado com esse ID ou nome",
"reposHaveMultipleApps": "Repositórios podem conter multiplos Apps", "reposHaveMultipleApps": "Repositórios podem conter multiplos aplicativos",
"fdroidThirdPartyRepo": "Repositórios de terceiros F-Droid", "fdroidThirdPartyRepo": "Repositórios de terceiros F-Droid",
"steam": "Steam", "steam": "Steam",
"steamMobile": "Steam Mobile", "steamMobile": "Steam Mobile",
"steamChat": "Steam Chat", "steamChat": "Steam Chat",
"install": "Instalar", "install": "Instalar",
"markInstalled": "Marcar Instalado", "markInstalled": "Marcar instalado",
"update": "Atualizar", "update": "Atualizar",
"markUpdated": "Marcar Atualizado", "markUpdated": "Marcar como atualizado",
"additionalOptions": "Opções Adicionais", "additionalOptions": "Opções adicionais",
"disableVersionDetection": "Desativar Detecção de Versão", "disableVersionDetection": "Desativar detecção de versão",
"noVersionDetectionExplanation": "Essa opção deve apenas ser usada por Apps onde detecção de versão não funciona corretamente.", "noVersionDetectionExplanation": "Essa opção deve apenas ser usada por aplicativos onde a detecção de versão não funciona corretamente.",
"downloadingX": "Baixando {}", "downloadingX": "Baixando {}",
"downloadNotifDescription": "Notifica o usuário do progresso ao baixar um App", "downloadNotifDescription": "Notifica o usuário o progresso do download de um aplicativo",
"noAPKFound": "APK não encontrado", "noAPKFound": "APK não encontrado",
"noVersionDetection": "Sem Detecção de versão", "noVersionDetection": "Sem detecção de versão",
"categorize": "Categorizar", "categorize": "Categorizar",
"categories": "Categorias", "categories": "Categorias",
"category": "Categoria", "category": "Categoria",
"noCategory": "Sem Categoria", "noCategory": "Sem categoria",
"noCategories": "Sem Categoria", "noCategories": "Sem categoria",
"deleteCategoriesQuestion": "Deletar Categorias?", "deleteCategoriesQuestion": "Deletar categorias?",
"categoryDeleteWarning": "Todos os Apps em categorias removidas serão descategorizados.", "categoryDeleteWarning": "Todos os aplicativos em categorias removidas serão descategorizados.",
"addCategory": "Adicionar Categoria", "addCategory": "Adicionar categoria",
"label": "Etiqueta", "label": "Etiqueta",
"language": "Linguagem", "language": "Linguagem",
"copiedToClipboard": "Copiado para a área de transferência", "copiedToClipboard": "Copiado para a área de transferência",
"storagePermissionDenied": "Permição ao armazenamento negada", "storagePermissionDenied": "Permissão de armazenamento negada",
"selectedCategorizeWarning": "Isso vai substituir qualquer confirução de categoria para os Apps selecionados.", "selectedCategorizeWarning": "Isso vai substituir qualquer configuração de categoria para os aplicativos selecionados.",
"filterAPKsByRegEx": "Filtrar APKs por Expressão Regular", "filterAPKsByRegEx": "Filtrar APKs por expressão regular",
"removeFromObtainium": "Remover do Obtainium", "removeFromObtainium": "Remover do Obtainium",
"uninstallFromDevice": "Desinstalar do dispositivo", "uninstallFromDevice": "Desinstalar do dispositivo",
"onlyWorksWithNonVersionDetectApps": "Apenas funciona para Apps com detecção de versão desativada.", "onlyWorksWithNonVersionDetectApps": "Apenas funciona para aplicativos com detecção de versão desativada.",
"releaseDateAsVersion": "Usar Data de Lançamento como Versão", "releaseDateAsVersion": "Usar data de lançamento como versão",
"releaseDateAsVersionExplanation": "Esta opção só deve ser usada para aplicativos onde a detecção de versão não funciona corretamente, mas há uma data de lançamento disponível.", "releaseDateAsVersionExplanation": "Esta opção só deve ser usada para aplicativos onde a detecção de versão não funciona corretamente, mas há uma data de lançamento disponível.",
"changes": "Mudanças", "changes": "Mudanças",
"releaseDate": "Data de Lançamento", "releaseDate": "Data de lançamento",
"importFromURLsInFile": "Importar de URLs em Arquivo (como OPML)", "importFromURLsInFile": "Importar de URLs em arquivo (como OPML)",
"versionDetection": "Detecção de Versão", "versionDetection": "Detecção de Versão",
"standardVersionDetection": "Detecção de versão padrão", "standardVersionDetection": "Detecção de versão padrão",
"groupByCategory": "Agroupar por Categoria", "groupByCategory": "Agroupar por categoria",
"autoApkFilterByArch": "Tente filtrar APKs por arquitetura de CPU, se possível", "autoApkFilterByArch": "Tente filtrar APKs por arquitetura de CPU, se possível",
"overrideSource": "Substituir Fonte", "overrideSource": "Substituir fonte",
"dontShowAgain": "Não mostrar isso novamente", "dontShowAgain": "Não mostrar isso novamente",
"dontShowTrackOnlyWarnings": "Não mostrar avisos 'Apenas Seguir'", "dontShowTrackOnlyWarnings": "Não mostrar avisos 'Apenas Monitorar'",
"dontShowAPKOriginWarnings": "Não mostrar avisos de origem da APK", "dontShowAPKOriginWarnings": "Não mostrar avisos de origem da APK",
"moveNonInstalledAppsToBottom": "Mover Apps não instalados para o fundo da visão de Apps", "moveNonInstalledAppsToBottom": "Mover aplicativos não instalados para o fundo da lista de aplicativos",
"gitlabPATLabel": "Token de Acceso Pessoal do Gitlab\n(Ativa Pesquisa e Melhor Descoberta de APKs)", "gitlabPATLabel": "Token de Acceso Pessoal do Gitlab\n(Ativa Pesquisa e Melhor Descoberta de APKs)",
"about": "Sobre", "about": "Sobre",
"requiresCredentialsInSettings": "{}: Isso requer credenciais adicionais (em Configurações)", "requiresCredentialsInSettings": "{}: Isso requer credenciais adicionais (em Configurações)",
"checkOnStart": "Checar por atualizações ao iniciar ", "checkOnStart": "Checar por atualizações ao iniciar ",
"tryInferAppIdFromCode": "Tente inferir o ID do App pelo código fonte", "tryInferAppIdFromCode": "Tente inferir o ID do aplicativo pelo código-fonte",
"removeOnExternalUninstall": "Remover automaticamente Apps desinstalados externamente", "removeOnExternalUninstall": "Remover automaticamente aplicativos desinstalados externamente",
"pickHighestVersionCode": "Auto-selecionar o maior numero de versão do APK", "pickHighestVersionCode": "Auto-selecionar o maior numero de versão do APK",
"checkUpdateOnDetailPage": "Checar por atualizações ao abrir a pagina de detalhes de um App", "checkUpdateOnDetailPage": "Checar por atualizações ao abrir a página de detalhes de um aplicativo",
"disablePageTransitions": "Desativar animações de transição de pagina", "disablePageTransitions": "Desativar animações de transição de pagina",
"reversePageTransitions": "Reverter animações de transição de pagina", "reversePageTransitions": "Reverter animações de transição de pagina",
"minStarCount": "Contagem Minima de Estrelas", "minStarCount": "Contagem Minima de Estrelas",
@ -239,19 +238,19 @@
"sortByLastLinkSegment": "Sort by only the last segment of the link", "sortByLastLinkSegment": "Sort by only the last segment of the link",
"filterReleaseNotesByRegEx": "Filtrar Notas de Lançamento por Expressão Regular", "filterReleaseNotesByRegEx": "Filtrar Notas de Lançamento por Expressão Regular",
"customLinkFilterRegex": "Filtro de Link Personalizado por Expressão Regular (Padrão '.apk$')", "customLinkFilterRegex": "Filtro de Link Personalizado por Expressão Regular (Padrão '.apk$')",
"appsPossiblyUpdated": "Tentativas de atualização de Apps", "appsPossiblyUpdated": "Tentativas de atualização de aplicativos",
"appsPossiblyUpdatedNotifDescription": "Notifica o usuário de que atualizações de um ou mais Apps foram potencialmente aplicadas em segundo plano", "appsPossiblyUpdatedNotifDescription": "Notifica o usuário de que atualizações de um ou mais aplicativos foram potencialmente aplicadas em segundo-plano",
"xWasPossiblyUpdatedToY": "{} pode ter sido atualizado para {}.", "xWasPossiblyUpdatedToY": "{} pode ter sido atualizado para {}.",
"enableBackgroundUpdates": "Ativar atualizações em segundo plano", "enableBackgroundUpdates": "Ativar atualizações em segundo-plano",
"backgroundUpdateReqsExplanation": "Atualizações em segundo plano podem não ser possíveis para todos os Apps.", "backgroundUpdateReqsExplanation": "Atualizações em segundo-plano podem não ser possíveis para todos os aplicativos.",
"backgroundUpdateLimitsExplanation": "O sucesso de uma instalação em segundo plano só pode ser determinado quando o Obtainium é aberto.", "backgroundUpdateLimitsExplanation": "O sucesso de uma instalação em segundo-plano só pode ser determinado quando o Obtainium é aberto.",
"verifyLatestTag": "Verifique a 'ultima' etiqueta", "verifyLatestTag": "Verifique a 'ultima' etiqueta",
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit", "intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit",
"filterByLinkText": "Filter links by link text", "filterByLinkText": "Filter links by link text",
"intermediateLinkNotFound": "Link intermediário não encontrado", "intermediateLinkNotFound": "Link intermediário não encontrado",
"intermediateLink": "Intermediate link", "intermediateLink": "Intermediate link",
"exemptFromBackgroundUpdates": "Isento de atualizações em segundo plano (se ativadas)", "exemptFromBackgroundUpdates": "Isento de atualizações em segundo-plano (se ativadas)",
"bgUpdatesOnWiFiOnly": "Desative atualizações em segundo plano quando não estiver em WiFi", "bgUpdatesOnWiFiOnly": "Desative atualizações em segundo-plano quando não estiver em WiFi",
"autoSelectHighestVersionCode": "Auto-selecionar o maior codigo de versão", "autoSelectHighestVersionCode": "Auto-selecionar o maior codigo de versão",
"versionExtractionRegEx": "RegEx para Extração de Versão", "versionExtractionRegEx": "RegEx para Extração de Versão",
"matchGroupToUse": "Grupo de Seleção para Usar", "matchGroupToUse": "Grupo de Seleção para Usar",
@ -266,18 +265,18 @@
"takeFirstLink": "Take first link", "takeFirstLink": "Take first link",
"skipSort": "Skip sorting", "skipSort": "Skip sorting",
"debugMenu": "Menu Debug", "debugMenu": "Menu Debug",
"bgTaskStarted": "Tarefa em segundo plano iniciada - verifique os logs.", "bgTaskStarted": "Tarefa em segundo-plano iniciada - verifique os logs.",
"runBgCheckNow": "Execute a verificação de atualização em segundo plano agora", "runBgCheckNow": "Execute a verificação de atualização em segundo-plano agora",
"versionExtractWholePage": "Aplicar Regex de Extração de Versão à Página Inteira", "versionExtractWholePage": "Aplicar Regex de Extração de Versão à Página Inteira",
"installing": "Instalando", "installing": "Instalando",
"skipUpdateNotifications": "Pular notificações de update", "skipUpdateNotifications": "Pular notificações de update",
"updatesAvailableNotifChannel": "Atualizações Disponíveis", "updatesAvailableNotifChannel": "Atualizações Disponíveis",
"appsUpdatedNotifChannel": "Apps Atualizados", "appsUpdatedNotifChannel": "Aplicativos Atualizados",
"appsPossiblyUpdatedNotifChannel": "Tentativas de atualização de Apps", "appsPossiblyUpdatedNotifChannel": "Tentativas de atualização de aplicativos",
"errorCheckingUpdatesNotifChannel": "Erro ao Procurar por Atualizações", "errorCheckingUpdatesNotifChannel": "Erro ao Procurar por Atualizações",
"appsRemovedNotifChannel": "Apps Removidos", "appsRemovedNotifChannel": "Aplicativos Removidos",
"downloadingXNotifChannel": "Baixando {}", "downloadingXNotifChannel": "Baixando {}",
"completeAppInstallationNotifChannel": "Instalação completa do App", "completeAppInstallationNotifChannel": "Instalação completa do aplicativo",
"checkingForUpdatesNotifChannel": "Checando por Atualizações", "checkingForUpdatesNotifChannel": "Checando por Atualizações",
"onlyCheckInstalledOrTrackOnlyApps": "Apenas checar apps instalados e 'Apenas Seguir' por updates", "onlyCheckInstalledOrTrackOnlyApps": "Apenas checar apps instalados e 'Apenas Seguir' por updates",
"supportFixedAPKURL": "Suporte APK com URLs fixas", "supportFixedAPKURL": "Suporte APK com URLs fixas",
@ -287,26 +286,26 @@
"normal": "Normal", "normal": "Normal",
"shizuku": "Shizuku", "shizuku": "Shizuku",
"root": "Root", "root": "Root",
"shizukuBinderNotFound": "Shizuku não esta rodando", "shizukuBinderNotFound": "Shizuku não está rodando",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remover App?", "one": "Remover aplicativo?",
"other": "Remover Apps?" "other": "Remover aplicativos?"
}, },
"tooManyRequestsTryAgainInMinutes": { "tooManyRequestsTryAgainInMinutes": {
"one": "Muitas solicitações (taxa limitada) - tente novamente em {} minuto", "one": "Muitas solicitações (taxa limitada) - tente novamente em {} minuto",
"other": "Muitas solicitações (taxa limitada) - tente novamente em {} minutos" "other": "Muitas solicitações (taxa limitada) - tente novamente em {} minutos"
}, },
"bgUpdateGotErrorRetryInMinutes": { "bgUpdateGotErrorRetryInMinutes": {
"one": "A verificação de atualizações em segundo plano encontrou um {}, agendada uma nova verificação em {} minuto", "one": "A verificação de atualizações em segundo-plano encontrou um {}, agendada uma nova verificação em {} minuto",
"other": "A verificação de atualizações em segundo plano encontrou um {}, agendada uma nova verificação em {} minutos" "other": "A verificação de atualizações em segundo-plano encontrou um {}, agendada uma nova verificação em {} minutos"
}, },
"bgCheckFoundUpdatesWillNotifyIfNeeded": { "bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "A verificação de atualizações em segundo plano encontrou {} atualização, o usuário sera notificado caso necessário", "one": "A verificação de atualizações em segundo-plano encontrou {} atualização, o usuário sera notificado caso necessário",
"other": "A verificação de atualizações em segundo plano encontrou {} atualizações, o usuário sera notificado caso necessário" "other": "A verificação de atualizações em segundo-plano encontrou {} atualizações, o usuário sera notificado caso necessário"
}, },
"apps": { "apps": {
"one": "{} App", "one": "{} Aplicativo",
"other": "{} Apps" "other": "{} Aplicativos"
}, },
"url": { "url": {
"one": "{} URL", "one": "{} URL",

View File

@ -103,7 +103,6 @@
"importErrors": "Ошибка импорта", "importErrors": "Ошибка импорта",
"importedXOfYApps": "Импортировано приложений: {} из {}", "importedXOfYApps": "Импортировано приложений: {} из {}",
"followingURLsHadErrors": "При импорте следующие URL-адреса содержали ошибки:", "followingURLsHadErrors": "При импорте следующие URL-адреса содержали ошибки:",
"okay": "Ok",
"selectURL": "Выбрать URL-адрес", "selectURL": "Выбрать URL-адрес",
"selectURLs": "Выбрать URL-адреса", "selectURLs": "Выбрать URL-адреса",
"pick": "Выбрать", "pick": "Выбрать",
@ -287,7 +286,9 @@
"normal": "Нормальный", "normal": "Нормальный",
"shizuku": "Shizuku", "shizuku": "Shizuku",
"root": "Суперпользователь", "root": "Суперпользователь",
"shizukuBinderNotFound": "Shizuku не запущен", "shizukuBinderNotFound": "Совместимый сервис Shizuku не найден",
"useSystemFont": "Использовать системный шрифт",
"systemFontError": "Ошибка загрузки системного шрифта: {}",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Удалить приложение?", "one": "Удалить приложение?",
"other": "Удалить приложения?" "other": "Удалить приложения?"

View File

@ -103,7 +103,6 @@
"importErrors": "Importfel", "importErrors": "Importfel",
"importedXOfYApps": "{} av {} Appar importerade.", "importedXOfYApps": "{} av {} Appar importerade.",
"followingURLsHadErrors": "Följande URL:er hade fel:", "followingURLsHadErrors": "Följande URL:er hade fel:",
"okay": "Okej",
"selectURL": "Välj URL", "selectURL": "Välj URL",
"selectURLs": "Välj URL:er", "selectURLs": "Välj URL:er",
"pick": "Välj", "pick": "Välj",
@ -269,6 +268,11 @@
"bgTaskStarted": "Background task started - check logs.", "bgTaskStarted": "Background task started - check logs.",
"runBgCheckNow": "Kör Bakgrundsuppdateringskoll Nu", "runBgCheckNow": "Kör Bakgrundsuppdateringskoll Nu",
"parallelDownloads": "Allow parallel downloads", "parallelDownloads": "Allow parallel downloads",
"installMethod": "Installation method",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku is not running",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Ta Bort App?", "one": "Ta Bort App?",
"other": "Ta Bort Appar?" "other": "Ta Bort Appar?"

View File

@ -103,7 +103,6 @@
"importErrors": "İçe Aktarma Hataları", "importErrors": "İçe Aktarma Hataları",
"importedXOfYApps": "{}'den {} Uygulama İçe Aktarıldı.", "importedXOfYApps": "{}'den {} Uygulama İçe Aktarıldı.",
"followingURLsHadErrors": "Aşağıdaki URL'lerde hatalar oluştu:", "followingURLsHadErrors": "Aşağıdaki URL'lerde hatalar oluştu:",
"okay": "Tamam",
"selectURL": "URL Seç", "selectURL": "URL Seç",
"selectURLs": "URL'leri Seç", "selectURLs": "URL'leri Seç",
"pick": "Seç", "pick": "Seç",
@ -283,6 +282,11 @@
"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",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku is not running",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Uygulamayı Kaldır?", "one": "Uygulamayı Kaldır?",
"other": "Uygulamaları Kaldır?" "other": "Uygulamaları Kaldır?"
@ -335,4 +339,4 @@
"one": "{} ve 1 diğer uygulama muhtemelen güncellendi.", "one": "{} ve 1 diğer uygulama muhtemelen güncellendi.",
"other": "{} ve {} daha fazla uygulama muhtemelen güncellendi." "other": "{} ve {} daha fazla uygulama muhtemelen güncellendi."
} }
} }

View File

@ -9,7 +9,7 @@
"placeholder": "Giữ chỗ", "placeholder": "Giữ chỗ",
"someErrors": "Đã xảy ra một số lỗi", "someErrors": "Đã xảy ra một số lỗi",
"unexpectedError": "Lỗi không mong đợi", "unexpectedError": "Lỗi không mong đợi",
"ok": "Ôkê", "ok": "OK",
"and": "và", "and": "và",
"githubPATLabel": "Mã thông báo truy cập cá nhân GitHub (Tăng tốc độ giới hạn)", "githubPATLabel": "Mã thông báo truy cập cá nhân GitHub (Tăng tốc độ giới hạn)",
"includePrereleases": "Bao gồm các bản phát hành trước", "includePrereleases": "Bao gồm các bản phát hành trước",
@ -17,7 +17,7 @@
"filterReleaseTitlesByRegEx": "Lọc tiêu đề bản phát hành theo biểu thức chính quy", "filterReleaseTitlesByRegEx": "Lọc tiêu đề bản phát hành theo biểu thức chính quy",
"invalidRegEx": "Biểu thức chính quy không hợp lệ", "invalidRegEx": "Biểu thức chính quy không hợp lệ",
"noDescription": "Không có mô tả", "noDescription": "Không có mô tả",
"cancel": "Hủy bỏ", "cancel": "Hủy",
"continue": "Tiếp tục", "continue": "Tiếp tục",
"requiredInBrackets": "(Yêu cầu)", "requiredInBrackets": "(Yêu cầu)",
"dropdownNoOptsError": "LỖI: TẢI XUỐNG PHẢI CÓ ÍT NHẤT MỘT LỰA CHỌN", "dropdownNoOptsError": "LỖI: TẢI XUỐNG PHẢI CÓ ÍT NHẤT MỘT LỰA CHỌN",
@ -103,7 +103,6 @@
"importErrors": "Lỗi nhập", "importErrors": "Lỗi nhập",
"importedXOfYApps": "{} trong số {} Ứng dụng đã được nhập.", "importedXOfYApps": "{} trong số {} Ứng dụng đã được nhập.",
"followingURLsHadErrors": "Các URL sau có lỗi:", "followingURLsHadErrors": "Các URL sau có lỗi:",
"okay": "Ôkê",
"selectURL": "Chọn URL", "selectURL": "Chọn URL",
"selectURLs": "Chọn URL", "selectURLs": "Chọn URL",
"pick": "Chọn", "pick": "Chọn",
@ -113,17 +112,17 @@
"followSystem": "Theo hệ thống", "followSystem": "Theo hệ thống",
"obtainium": "Obtainium", "obtainium": "Obtainium",
"materialYou": "Material You", "materialYou": "Material You",
"useBlackTheme": "Sử dụng chủ đề tối màu đen thuần túy", "useBlackTheme": "Nền đen",
"appSortBy": "Sắp xếp ứng dụng theo", "appSortBy": "Sắp xếp ứng dụng",
"authorName": "Tác giả/Tên", "authorName": "Tác giả",
"nameAuthor": "Tên/Tác giả", "nameAuthor": "Tên",
"asAdded": "Như đã thêm", "asAdded": "Như đã thêm",
"appSortOrder": "Thứ tự sắp xếp ứng dụng", "appSortOrder": "Thứ tự sắp xếp",
"ascending": "Tăng dần", "ascending": "Tăng dần",
"descending": "Giảm dần", "descending": "Giảm dần",
"bgUpdateCheckInterval": "Khoảng thời gian kiểm tra cập nhật nền", "bgUpdateCheckInterval": "Khoảng thời gian kiểm tra cập nhật nền",
"neverManualOnly": "Không bao giờ - Chỉ thủ công", "neverManualOnly": "Không bao giờ - Chỉ thủ công",
"appearance": "Vẻ ngoài", "appearance": "Hiển thị",
"showWebInAppView": "Hiển thị trang web Nguồn trong chế độ xem Ứng dụng", "showWebInAppView": "Hiển thị trang web Nguồn trong chế độ xem Ứng dụng",
"pinUpdates": "Ghim nội dung cập nhật lên đầu chế độ xem Ứng dụng", "pinUpdates": "Ghim nội dung cập nhật lên đầu chế độ xem Ứng dụng",
"updates": "Cập nhật", "updates": "Cập nhật",
@ -229,7 +228,7 @@
"removeOnExternalUninstall": "Tự động xóa ứng dụng đã gỡ cài đặt bên ngoài", "removeOnExternalUninstall": "Tự động xóa ứng dụng đã gỡ cài đặt bên ngoài",
"pickHighestVersionCode": "Tự động chọn APK mã phiên bản cao nhất", "pickHighestVersionCode": "Tự động chọn APK mã phiên bản cao nhất",
"checkUpdateOnDetailPage": "Kiểm tra các bản cập nhật khi mở trang chi tiết Ứng dụng", "checkUpdateOnDetailPage": "Kiểm tra các bản cập nhật khi mở trang chi tiết Ứng dụng",
"disablePageTransitions": "Tắt hoạt ảnh chuyển trang", "disablePageTransitions": "Tắt hiệu ứng chuyển trang",
"reversePageTransitions": "Hoạt ảnh chuyển đổi trang đảo ngược", "reversePageTransitions": "Hoạt ảnh chuyển đổi trang đảo ngược",
"minStarCount": "Số lượng sao tối thiểu", "minStarCount": "Số lượng sao tối thiểu",
"addInfoBelow": "Thêm thông tin này vào bên dưới.", "addInfoBelow": "Thêm thông tin này vào bên dưới.",
@ -283,6 +282,11 @@
"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",
"normal": "Normal",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "Shizuku chưa khởi động",
"removeAppQuestion":{ "removeAppQuestion":{
"one": "Gỡ ứng dụng?", "one": "Gỡ ứng dụng?",
"other": "Gỡ ứng dụng?" "other": "Gỡ ứng dụng?"

View File

@ -22,11 +22,11 @@
"requiredInBrackets": "(必填)", "requiredInBrackets": "(必填)",
"dropdownNoOptsError": "错误:下拉菜单必须包含至少一个选项", "dropdownNoOptsError": "错误:下拉菜单必须包含至少一个选项",
"colour": "配色", "colour": "配色",
"githubStarredRepos": "GitHub 已星标仓库", "githubStarredRepos": "已星标的 GitHub 仓库",
"uname": "用户名", "uname": "用户名",
"wrongArgNum": "参数数量错误", "wrongArgNum": "参数数量错误",
"xIsTrackOnly": "{}为“仅追踪”模式", "xIsTrackOnly": "{}为“仅追踪”模式",
"source": "源代码", "source": "源",
"app": "应用", "app": "应用",
"appsFromSourceAreTrackOnly": "此来源的应用为“仅追踪”模式。", "appsFromSourceAreTrackOnly": "此来源的应用为“仅追踪”模式。",
"youPickedTrackOnly": "您选择了“仅追踪”。", "youPickedTrackOnly": "您选择了“仅追踪”。",
@ -56,12 +56,12 @@
"estimateInBrackets": "(推测)", "estimateInBrackets": "(推测)",
"selectAll": "全选", "selectAll": "全选",
"deselectX": "取消选择 {}", "deselectX": "取消选择 {}",
"xWillBeRemovedButRemainInstalled": "{} 将从 Obtainium 中删除,但仍安装在您的设备中。", "xWillBeRemovedButRemainInstalled": "{}将从 Obtainium 中删除,但仍安装在您的设备中。",
"removeSelectedAppsQuestion": "是否删除选中的应用?", "removeSelectedAppsQuestion": "是否删除选中的应用?",
"removeSelectedApps": "删除选中的应用", "removeSelectedApps": "删除选中的应用",
"updateX": "更新 {}", "updateX": "更新 {}",
"installX": "安装 {}", "installX": "安装 {}",
"markXTrackOnlyAsUpdated": "将 {}\n仅追踪\n标记为已更新", "markXTrackOnlyAsUpdated": "将{}\n仅追踪\n标记为已更新",
"changeX": "更改 {}", "changeX": "更改 {}",
"installUpdateApps": "安装/更新应用", "installUpdateApps": "安装/更新应用",
"installUpdateSelectedApps": "安装/更新选中的应用", "installUpdateSelectedApps": "安装/更新选中的应用",
@ -88,22 +88,21 @@
"importExport": "导入/导出", "importExport": "导入/导出",
"settings": "设置", "settings": "设置",
"exportedTo": "已导出至 {}", "exportedTo": "已导出至 {}",
"obtainiumExport": "Obtainium 导出", "obtainiumExport": "导出 Obtainium",
"invalidInput": "无效的输入", "invalidInput": "无效的输入",
"importedX": "已导入 {}", "importedX": "已导入 {}",
"obtainiumImport": "Obtainium 导入", "obtainiumImport": "导入 Obtainium",
"importFromURLList": "从 URL 列表导入", "importFromURLList": "从 URL 列表导入",
"searchQuery": "搜索查询", "searchQuery": "搜索查询",
"appURLList": "应用 URL 列表", "appURLList": "应用 URL 列表",
"line": "行", "line": "行",
"searchX": "搜索 {}", "searchX": "搜索{}",
"noResults": "无结果", "noResults": "无结果",
"importX": "导入 {}", "importX": "导入{}",
"importedAppsIdDisclaimer": "导入的应用可能会错误地显示为“未安装”状态。\n请通过 Obtainium 重新安装这些应用来解决此问题。", "importedAppsIdDisclaimer": "导入的应用可能会错误地显示为“未安装”状态。\n请通过 Obtainium 重新安装这些应用来解决此问题。",
"importErrors": "导入错误", "importErrors": "导入错误",
"importedXOfYApps": "已导入 {} 中的 {} 个应用。", "importedXOfYApps": "已导入 {} 中的 {} 个应用。",
"followingURLsHadErrors": "下列 URL 存在错误:", "followingURLsHadErrors": "下列 URL 存在错误:",
"okay": "好的",
"selectURL": "选择 URL", "selectURL": "选择 URL",
"selectURLs": "选择 URL", "selectURLs": "选择 URL",
"pick": "选择", "pick": "选择",
@ -124,7 +123,7 @@
"bgUpdateCheckInterval": "后台更新检查间隔", "bgUpdateCheckInterval": "后台更新检查间隔",
"neverManualOnly": "手动", "neverManualOnly": "手动",
"appearance": "外观", "appearance": "外观",
"showWebInAppView": "应用详情页显示来源网页", "showWebInAppView": "应用详情页显示来源网页",
"pinUpdates": "将待更新应用置顶", "pinUpdates": "将待更新应用置顶",
"updates": "更新", "updates": "更新",
"sourceSpecific": "来源", "sourceSpecific": "来源",
@ -136,7 +135,7 @@
"appNotFound": "未找到应用", "appNotFound": "未找到应用",
"obtainiumExportHyphenatedLowercase": "obtainium-export", "obtainiumExportHyphenatedLowercase": "obtainium-export",
"pickAnAPK": "选择一个 APK 文件", "pickAnAPK": "选择一个 APK 文件",
"appHasMoreThanOnePackage": "{} 有多个架构可用:", "appHasMoreThanOnePackage": "{}有多个架构可用:",
"deviceSupportsXArch": "您的设备支持 {} 架构。", "deviceSupportsXArch": "您的设备支持 {} 架构。",
"deviceSupportsFollowingArchs": "您的设备支持下列架构:", "deviceSupportsFollowingArchs": "您的设备支持下列架构:",
"warning": "警告", "warning": "警告",
@ -144,15 +143,15 @@
"updatesAvailable": "更新可用", "updatesAvailable": "更新可用",
"updatesAvailableNotifDescription": "Obtainium 追踪的应用有更新时发送通知", "updatesAvailableNotifDescription": "Obtainium 追踪的应用有更新时发送通知",
"noNewUpdates": "全部应用已是最新。", "noNewUpdates": "全部应用已是最新。",
"xHasAnUpdate": "{} 可以更新了。", "xHasAnUpdate": "{}可以更新了。",
"appsUpdated": "应用已更新", "appsUpdated": "应用已更新",
"appsUpdatedNotifDescription": "当应用在后台安装更新时发送通知", "appsUpdatedNotifDescription": "当应用在后台安装更新时发送通知",
"xWasUpdatedToY": "{} 已更新至 {}。", "xWasUpdatedToY": "{}已更新至 {}。",
"errorCheckingUpdates": "检查更新出错", "errorCheckingUpdates": "检查更新出错",
"errorCheckingUpdatesNotifDescription": "当后台检查更新失败时显示的通知", "errorCheckingUpdatesNotifDescription": "当后台检查更新失败时显示的通知",
"appsRemoved": "应用已删除", "appsRemoved": "应用已删除",
"appsRemovedNotifDescription": "当应用因加载出错而被删除时发送通知", "appsRemovedNotifDescription": "当应用因加载出错而被删除时发送通知",
"xWasRemovedDueToErrorY": "{} 由于以下错误被删除:{}", "xWasRemovedDueToErrorY": "{}由于以下错误被删除:{}",
"completeAppInstallation": "完成应用安装", "completeAppInstallation": "完成应用安装",
"obtainiumMustBeOpenToInstallApps": "必须启动 Obtainium 才能安装应用", "obtainiumMustBeOpenToInstallApps": "必须启动 Obtainium 才能安装应用",
"completeAppInstallationNotifDescription": "提示返回 Obtainium 以完成应用的安装", "completeAppInstallationNotifDescription": "提示返回 Obtainium 以完成应用的安装",
@ -160,7 +159,7 @@
"checkingForUpdatesNotifDescription": "检查更新时短暂显示的通知", "checkingForUpdatesNotifDescription": "检查更新时短暂显示的通知",
"pleaseAllowInstallPerm": "请授予 Obtainium 安装应用的权限", "pleaseAllowInstallPerm": "请授予 Obtainium 安装应用的权限",
"trackOnly": "仅追踪", "trackOnly": "仅追踪",
"errorWithHttpStatusCode": "错误 {}", "errorWithHttpStatusCode": "{} 错误",
"versionCorrectionDisabled": "禁用版本号更正(插件似乎未起作用)", "versionCorrectionDisabled": "禁用版本号更正(插件似乎未起作用)",
"unknown": "未知", "unknown": "未知",
"none": "无", "none": "无",
@ -186,11 +185,11 @@
"additionalOptions": "附加选项", "additionalOptions": "附加选项",
"disableVersionDetection": "禁用版本检测", "disableVersionDetection": "禁用版本检测",
"noVersionDetectionExplanation": "此选项应该仅用于无法进行版本检测的应用。", "noVersionDetectionExplanation": "此选项应该仅用于无法进行版本检测的应用。",
"downloadingX": "正在下载{}", "downloadingX": "正在下载{}",
"downloadNotifDescription": "提示应用的下载进度", "downloadNotifDescription": "提示应用的下载进度",
"noAPKFound": "未找到 APK 文件", "noAPKFound": "未找到 APK 文件",
"noVersionDetection": "禁用版本检测", "noVersionDetection": "禁用版本检测",
"categorize": "类", "categorize": "类",
"categories": "类别", "categories": "类别",
"category": "类别", "category": "类别",
"noCategory": "无类别", "noCategory": "无类别",
@ -218,17 +217,17 @@
"autoApkFilterByArch": "如果可能,尝试按设备支持的 CPU 架构筛选 APK 文件", "autoApkFilterByArch": "如果可能,尝试按设备支持的 CPU 架构筛选 APK 文件",
"overrideSource": "覆盖来源", "overrideSource": "覆盖来源",
"dontShowAgain": "不再显示", "dontShowAgain": "不再显示",
"dontShowTrackOnlyWarnings": "不显示“仅追踪”模式警告", "dontShowTrackOnlyWarnings": "忽略“仅追踪”模式警告",
"dontShowAPKOriginWarnings": "不显示 APK 文件来源警告", "dontShowAPKOriginWarnings": "忽略 APK 文件来源警告",
"moveNonInstalledAppsToBottom": "将未安装应用置底", "moveNonInstalledAppsToBottom": "将未安装应用置底",
"gitlabPATLabel": "GitLab 个人访问令牌(启用搜索功能并增强 APK 发现)", "gitlabPATLabel": "GitLab 个人访问令牌(启用搜索功能并增强 APK 发现)",
"about": "相关文档", "about": "相关文档",
"requiresCredentialsInSettings": "{}: 此功能需要额外的凭据(在“设置”中添加)", "requiresCredentialsInSettings": "{}此功能需要额外的凭据(在“设置”中添加)",
"checkOnStart": "启动时进行一次检查", "checkOnStart": "启动时进行一次检查",
"tryInferAppIdFromCode": "尝试从源代码推断应用 ID", "tryInferAppIdFromCode": "尝试从源代码推断应用 ID",
"removeOnExternalUninstall": "自动删除已卸载的外部应用", "removeOnExternalUninstall": "自动删除列表中已卸载的应用",
"pickHighestVersionCode": "自动选择版本号最高的 APK 文件", "pickHighestVersionCode": "自动选择版本号最高的 APK 文件",
"checkUpdateOnDetailPage": "打开应用详情页时检查更新", "checkUpdateOnDetailPage": "打开应用详情页时进行检查",
"disablePageTransitions": "禁用页面过渡动画效果", "disablePageTransitions": "禁用页面过渡动画效果",
"reversePageTransitions": "反转页面过渡动画效果", "reversePageTransitions": "反转页面过渡动画效果",
"minStarCount": "最小星标数", "minStarCount": "最小星标数",
@ -236,9 +235,9 @@
"addInfoInSettings": "在“设置”中添加此凭据。", "addInfoInSettings": "在“设置”中添加此凭据。",
"githubSourceNote": "使用访问令牌可避免触发 GitHub 的 API 请求限制。", "githubSourceNote": "使用访问令牌可避免触发 GitHub 的 API 请求限制。",
"gitlabSourceNote": "未使用访问令牌时可能无法从 GitLab 获取 APK 文件。", "gitlabSourceNote": "未使用访问令牌时可能无法从 GitLab 获取 APK 文件。",
"sortByLastLinkSegment": "Sort by only the last segment of the link", "sortByLastLinkSegment": "仅根据链接的末尾部分进行筛选",
"filterReleaseNotesByRegEx": "筛选发行说明(正则表达式)", "filterReleaseNotesByRegEx": "筛选发行说明(正则表达式)",
"customLinkFilterRegex": "筛选自定义来源 APK 文件链接\n正则表达式默认匹配模式为“.apk$”)", "customLinkFilterRegex": "筛选自定义来源 APK 文件链接\n正则表达式默认匹配模式为“.apk$”)",
"appsPossiblyUpdated": "已尝试更新应用", "appsPossiblyUpdated": "已尝试更新应用",
"appsPossiblyUpdatedNotifDescription": "当应用已尝试在后台更新时发送通知", "appsPossiblyUpdatedNotifDescription": "当应用已尝试在后台更新时发送通知",
"xWasPossiblyUpdatedToY": "已尝试将“{}”更新至 {}。", "xWasPossiblyUpdatedToY": "已尝试将“{}”更新至 {}。",
@ -246,29 +245,29 @@
"backgroundUpdateReqsExplanation": "后台更新未必适用于所有的应用。", "backgroundUpdateReqsExplanation": "后台更新未必适用于所有的应用。",
"backgroundUpdateLimitsExplanation": "只有在启动 Obtainium 时才能确认安装是否成功。", "backgroundUpdateLimitsExplanation": "只有在启动 Obtainium 时才能确认安装是否成功。",
"verifyLatestTag": "验证“Latest”标签", "verifyLatestTag": "验证“Latest”标签",
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit", "intermediateLinkRegex": "筛选中转链接(正则表达式)",
"filterByLinkText": "Filter links by link text", "filterByLinkText": "根据链接文本进行筛选",
"intermediateLinkNotFound": "未找到中转链接", "intermediateLinkNotFound": "未找到中转链接",
"intermediateLink": "Intermediate link", "intermediateLink": "中转链接",
"exemptFromBackgroundUpdates": "禁用后台更新\n(如果已经全局启用)", "exemptFromBackgroundUpdates": "禁用后台更新(如果已经全局启用)",
"bgUpdatesOnWiFiOnly": "未连接 Wi-Fi 时禁用后台更新", "bgUpdatesOnWiFiOnly": "未连接 Wi-Fi 时禁用后台更新",
"autoSelectHighestVersionCode": "自动选择版本号最高的 APK 文件", "autoSelectHighestVersionCode": "自动选择版本号最高的 APK 文件",
"versionExtractionRegEx": "提取版本号(正则表达式)", "versionExtractionRegEx": "版本号提取规则(正则表达式)",
"matchGroupToUse": "引用的捕获组", "matchGroupToUse": "引用的捕获组",
"highlightTouchTargets": "突出展示不明显的触摸区域", "highlightTouchTargets": "突出展示不明显的触摸区域",
"pickExportDir": "选择导出文件夹", "pickExportDir": "选择导出文件夹",
"autoExportOnChanges": "数据变更时自动导出", "autoExportOnChanges": "数据变更时自动导出",
"includeSettings": "Include settings", "includeSettings": "同时导出应用设置",
"filterVersionsByRegEx": "筛选版本号(正则表达式)", "filterVersionsByRegEx": "筛选版本号(正则表达式)",
"trySelectingSuggestedVersionCode": "尝试选择推荐版本的 APK 文件", "trySelectingSuggestedVersionCode": "尝试选择推荐版本的 APK 文件",
"dontSortReleasesList": "保持来自 API 的发行顺序", "dontSortReleasesList": "保持来自 API 的发行顺序",
"reverseSort": "反转排序", "reverseSort": "反转排序",
"takeFirstLink": "Take first link", "takeFirstLink": "选取第一个链接",
"skipSort": "Skip sorting", "skipSort": "不进行排序",
"debugMenu": "调试选项", "debugMenu": "调试选项",
"bgTaskStarted": "后台任务已启动 - 详见日志", "bgTaskStarted": "后台任务已启动 - 详见日志",
"runBgCheckNow": "立即进行后台更新检查", "runBgCheckNow": "立即进行后台更新检查",
"versionExtractWholePage": "将提取版本号的正则表达式应用于整页面", "versionExtractWholePage": "将版本号提取规则应用于整页面",
"installing": "正在安装", "installing": "正在安装",
"skipUpdateNotifications": "忽略更新通知", "skipUpdateNotifications": "忽略更新通知",
"updatesAvailableNotifChannel": "更新可用", "updatesAvailableNotifChannel": "更新可用",
@ -276,13 +275,20 @@
"appsPossiblyUpdatedNotifChannel": "已尝试更新应用", "appsPossiblyUpdatedNotifChannel": "已尝试更新应用",
"errorCheckingUpdatesNotifChannel": "检查更新出错", "errorCheckingUpdatesNotifChannel": "检查更新出错",
"appsRemovedNotifChannel": "应用已删除", "appsRemovedNotifChannel": "应用已删除",
"downloadingXNotifChannel": "正在下载{}", "downloadingXNotifChannel": "正在下载{}",
"completeAppInstallationNotifChannel": "完成应用安装", "completeAppInstallationNotifChannel": "完成应用安装",
"checkingForUpdatesNotifChannel": "正在检查更新", "checkingForUpdatesNotifChannel": "正在检查更新",
"onlyCheckInstalledOrTrackOnlyApps": "只已安装和“仅追踪”的应用进行更新检查", "onlyCheckInstalledOrTrackOnlyApps": "只检查已安装和“仅追踪”的应用",
"supportFixedAPKURL": "Support fixed APK URLs", "supportFixedAPKURL": "支持固定的 APK 文件链接",
"selectX": "Select {}", "selectX": "选择{}",
"parallelDownloads": "Allow parallel downloads", "parallelDownloads": "启用并行下载",
"installMethod": "安装方式",
"normal": "常规",
"shizuku": "Shizuku",
"root": "Root",
"shizukuBinderNotFound": "未发现兼容的 Shizuku 服务",
"useSystemFont": "使用系统字体",
"systemFontError": "加载系统字体出错:{}",
"removeAppQuestion": { "removeAppQuestion": {
"one": "是否删除应用?", "one": "是否删除应用?",
"other": "是否删除应用?" "other": "是否删除应用?"
@ -324,15 +330,15 @@
"other": "清除了 {n} 个日志({before} 之前,{after} 之后)" "other": "清除了 {n} 个日志({before} 之前,{after} 之后)"
}, },
"xAndNMoreUpdatesAvailable": { "xAndNMoreUpdatesAvailable": {
"one": "{} 和另外 1 个应用可以更新了。", "one": "{}和另外 1 个应用可以更新了。",
"other": "{} 和另外 {} 个应用可以更新了。" "other": "{}和另外 {} 个应用可以更新了。"
}, },
"xAndNMoreUpdatesInstalled": { "xAndNMoreUpdatesInstalled": {
"one": "{} 和另外 1 个应用已更新。", "one": "{} 和另外 1 个应用已更新。",
"other": "{} 和另外 {} 个应用已更新。" "other": "{}和另外 {} 个应用已更新。"
}, },
"xAndNMoreUpdatesPossiblyInstalled": { "xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} 和另外 1 个应用已尝试更新。", "one": "{} 和另外 1 个应用已尝试更新。",
"other": "{} 和另外 {} 个应用已尝试更新。" "other": "{}和另外 {} 个应用已尝试更新。"
} }
} }

View File

@ -10,7 +10,7 @@ class APKCombo extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/+[^/]+/+[^/]+'); RegExp standardUrlRegEx = RegExp('^https?://(www\\.)?$host/+[^/]+/+[^/]+');
var match = standardUrlRegEx.firstMatch(url.toLowerCase()); var match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -34,7 +34,7 @@ class APKPure extends AppSource {
url = 'https://$host${Uri.parse(url).path}'; url = 'https://$host${Uri.parse(url).path}';
} }
RegExp standardUrlRegExA = RegExp standardUrlRegExA =
RegExp('^https?://$host/+[^/]+/+[^/]+(/+[^/]+)?'); RegExp('^https?://(www\\.)?$host/+[^/]+/+[^/]+(/+[^/]+)?');
match = standardUrlRegExA.firstMatch(url.toLowerCase()); match = standardUrlRegExA.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -16,7 +16,7 @@ class Codeberg extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+'); RegExp standardUrlRegEx = RegExp('^https?://(www\\.)?$host/[^/]+/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -38,13 +38,14 @@ class FDroid extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegExB = RegExp standardUrlRegExB =
RegExp('^https?://$host/+[^/]+/+packages/+[^/]+'); RegExp('^https?://(www\\.)?$host/+[^/]+/+packages/+[^/]+');
RegExpMatch? match = standardUrlRegExB.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegExB.firstMatch(url.toLowerCase());
if (match != null) { if (match != null) {
url = url =
'https://${Uri.parse(url.substring(0, match.end)).host}/packages/${Uri.parse(url).pathSegments.last}'; 'https://${Uri.parse(url.substring(0, match.end)).host}/packages/${Uri.parse(url).pathSegments.last}';
} }
RegExp standardUrlRegExA = RegExp('^https?://$host/+packages/+[^/]+'); RegExp standardUrlRegExA =
RegExp('^https?://(www\\.)?$host/+packages/+[^/]+');
match = standardUrlRegExA.firstMatch(url.toLowerCase()); match = standardUrlRegExA.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);
@ -84,17 +85,30 @@ class FDroid extends AppSource {
try { try {
var res = await sourceRequest( var res = await sourceRequest(
'https://gitlab.com/fdroid/fdroiddata/-/raw/master/metadata/$appId.yml'); 'https://gitlab.com/fdroid/fdroiddata/-/raw/master/metadata/$appId.yml');
String author = res.body var lines = res.body.split('\n');
.split('\n') String author = lines
.where((l) => l.startsWith('AuthorName: ')) .where((l) => l.startsWith('AuthorName: '))
.first .first
.split(': ') .split(': ')
.sublist(1) .sublist(1)
.join(': '); .join(': ');
details.names.author = author; details.names.author = author;
var changelogUrls = lines.where((l) => l.startsWith('Changelog: '));
if (changelogUrls.isNotEmpty) {
details.changeLog = changelogUrls.first;
details.changeLog = (await sourceRequest(details.changeLog!
.split(': ')
.sublist(1)
.join(': ')
.replaceFirst('/blob/', '/raw/')))
.body;
}
} catch (e) { } catch (e) {
// Fail silently // Fail silently
} }
if ((details.changeLog?.length ?? 0) > 1000) {
details.changeLog = '${details.changeLog!.substring(0, 2048)}...';
}
} }
return details; return details;
} }

View File

@ -149,7 +149,7 @@ class GitHub extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+'); RegExp standardUrlRegEx = RegExp('^https?://(www\\.)?$host/[^/]+/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);
@ -346,6 +346,11 @@ class GitHub extends AppSource {
continue; continue;
} }
var apkUrls = getReleaseAPKUrls(releases[i]); var apkUrls = getReleaseAPKUrls(releases[i]);
if (additionalSettings['apkFilterRegEx'] != null) {
var reg = RegExp(additionalSettings['apkFilterRegEx']);
apkUrls =
apkUrls.where((element) => reg.hasMatch(element.key)).toList();
}
if (apkUrls.isEmpty && additionalSettings['trackOnly'] != true) { if (apkUrls.isEmpty && additionalSettings['trackOnly'] != true) {
continue; continue;
} }

View File

@ -52,7 +52,7 @@ class GitLab extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+'); RegExp standardUrlRegEx = RegExp('^https?://(www\\.)?$host/[^/]+/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -1,5 +1,4 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:html/parser.dart'; 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';
@ -18,13 +17,17 @@ String ensureAbsoluteUrl(String ambiguousUrl, Uri referenceAbsoluteUrl) {
.split('/') .split('/')
.where((element) => element.trim().isNotEmpty) .where((element) => element.trim().isNotEmpty)
.toList(); .toList();
String absoluteUrl;
if (ambiguousUrl.startsWith('/') || currPathSegments.isEmpty) { if (ambiguousUrl.startsWith('/') || currPathSegments.isEmpty) {
return '${referenceAbsoluteUrl.origin}/$ambiguousUrl'; absoluteUrl = '${referenceAbsoluteUrl.origin}/$ambiguousUrl';
} else if (ambiguousUrl.split('/').where((e) => e.isNotEmpty).length == 1) { } else if (ambiguousUrl.split('/').where((e) => e.isNotEmpty).length == 1) {
return '${referenceAbsoluteUrl.origin}/${currPathSegments.join('/')}/$ambiguousUrl'; absoluteUrl =
'${referenceAbsoluteUrl.origin}/${currPathSegments.join('/')}/$ambiguousUrl';
} else { } else {
return '${referenceAbsoluteUrl.origin}/${currPathSegments.sublist(0, currPathSegments.length - (currPathSegments.last.contains('.') ? 1 : 0)).join('/')}/$ambiguousUrl'; absoluteUrl =
'${referenceAbsoluteUrl.origin}/${currPathSegments.sublist(0, currPathSegments.length - (currPathSegments.last.contains('.') ? 1 : 0)).join('/')}/$ambiguousUrl';
} }
return Uri.parse(absoluteUrl).toString();
} }
int compareAlphaNumeric(String a, String b) { int compareAlphaNumeric(String a, String b) {
@ -100,28 +103,6 @@ class HTML extends AppSource {
} }
]) ])
], ],
[
GeneratedFormTextField('versionExtractionRegEx',
label: tr('versionExtractionRegEx'),
required: false,
additionalValidators: [(value) => regExValidator(value)]),
],
[
GeneratedFormTextField('matchGroupToUse',
label: tr('matchGroupToUse'),
required: false,
hint: '0',
textInputType: const TextInputType.numberWithOptions(),
additionalValidators: [
(value) {
if (value?.isEmpty == true) {
value = null;
}
value ??= '0';
return intValidator(value);
}
])
],
[ [
GeneratedFormSwitch('versionExtractWholePage', GeneratedFormSwitch('versionExtractWholePage',
label: tr('versionExtractWholePage')) label: tr('versionExtractWholePage'))
@ -195,6 +176,8 @@ class HTML extends AppSource {
? element.text ? element.text
: (element.attributes['href'] ?? '').split('/').last)) : (element.attributes['href'] ?? '').split('/').last))
.where((element) => element.key.isNotEmpty) .where((element) => element.key.isNotEmpty)
.map((e) =>
MapEntry(ensureAbsoluteUrl(e.key, res.request!.url), e.value))
.toList(); .toList();
if (allLinks.isEmpty) { if (allLinks.isEmpty) {
allLinks = RegExp( allLinks = RegExp(
@ -242,9 +225,14 @@ class HTML extends AppSource {
Map<String, dynamic> additionalSettings, Map<String, dynamic> additionalSettings,
) async { ) async {
var currentUrl = standardUrl; var currentUrl = standardUrl;
for (int i = 0; if (additionalSettings['intermediateLink']?.isNotEmpty != true) {
i < (additionalSettings['intermediateLink']?.length ?? 0); additionalSettings['intermediateLink'] = [];
i++) { }
additionalSettings['intermediateLink'] =
additionalSettings['intermediateLink']
.where((l) => l['customLinkFilterRegex'].isNotEmpty == true)
.toList();
for (int i = 0; i < (additionalSettings['intermediateLink'].length); i++) {
var intLinks = await grabLinksCommon(await sourceRequest(currentUrl), var intLinks = await grabLinksCommon(await sourceRequest(currentUrl),
additionalSettings['intermediateLink'][i]); additionalSettings['intermediateLink'][i]);
if (intLinks.isEmpty) { if (intLinks.isEmpty) {
@ -270,27 +258,12 @@ class HTML extends AppSource {
if (additionalSettings['supportFixedAPKURL'] != true) { if (additionalSettings['supportFixedAPKURL'] != true) {
version = rel.hashCode.toString(); version = rel.hashCode.toString();
} }
var versionExtractionRegEx = version = extractVersion(
additionalSettings['versionExtractionRegEx'] as String?; additionalSettings['versionExtractionRegEx'] as String?,
if (versionExtractionRegEx?.isNotEmpty == true) { additionalSettings['matchGroupToUse'] as String?,
var match = RegExp(versionExtractionRegEx!).allMatches( additionalSettings['versionExtractWholePage'] == true
additionalSettings['versionExtractWholePage'] == true ? res.body.split('\r\n').join('\n').split('\n').join('\\n')
? res.body.split('\r\n').join('\n').split('\n').join('\\n') : rel);
: rel);
if (match.isEmpty) {
throw NoVersionError();
}
String matchGroupString =
(additionalSettings['matchGroupToUse'] as String).trim();
if (matchGroupString.isEmpty) {
matchGroupString = "0";
}
version = match.last.group(int.parse(matchGroupString));
if (version?.isEmpty == true) {
throw NoVersionError();
}
}
rel = ensureAbsoluteUrl(rel, uri);
version ??= (await checkDownloadHash(rel)).toString(); version ??= (await checkDownloadHash(rel)).toString();
return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(), return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(),
AppNames(uri.host, tr('app'))); AppNames(uri.host, tr('app')));

View File

@ -13,7 +13,7 @@ class HuaweiAppGallery extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/app/[^/]+'); RegExp standardUrlRegEx = RegExp('^https?://(www\\.)?$host/app/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -11,7 +11,7 @@ class Mullvad extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host'); RegExp standardUrlRegEx = RegExp('^https?://(www\\.)?$host');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -10,7 +10,8 @@ class NeutronCode extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/downloads/file/[^/]+'); RegExp standardUrlRegEx =
RegExp('^https?://(www\\.)?$host/downloads/file/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -10,13 +10,14 @@ class SourceForge extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegExB = RegExp('^https?://$host/p/[^/]+'); RegExp standardUrlRegExB = RegExp('^https?://(www\\.)?$host/p/[^/]+');
RegExpMatch? match = standardUrlRegExB.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegExB.firstMatch(url.toLowerCase());
if (match != null) { if (match != null) {
url = url =
'https://${Uri.parse(url.substring(0, match.end)).host}/projects/${url.substring(Uri.parse(url.substring(0, match.end)).host.length + '/projects/'.length + 1)}'; 'https://${Uri.parse(url.substring(0, match.end)).host}/projects/${url.substring(Uri.parse(url.substring(0, match.end)).host.length + '/projects/'.length + 1)}';
} }
RegExp standardUrlRegExA = RegExp('^https?://$host/projects/[^/]+'); RegExp standardUrlRegExA =
RegExp('^https?://(www\\.)?$host/projects/[^/]+');
match = standardUrlRegExA.firstMatch(url.toLowerCase()); match = standardUrlRegExA.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -20,7 +20,7 @@ class SourceHut extends AppSource {
@override @override
String sourceSpecificStandardizeURL(String url) { String sourceSpecificStandardizeURL(String url) {
RegExp standardUrlRegEx = RegExp('^https?://$host/[^/]+/[^/]+'); RegExp standardUrlRegEx = RegExp('^https?://(www\\.)?$host/[^/]+/[^/]+');
RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase()); RegExpMatch? match = standardUrlRegEx.firstMatch(url.toLowerCase());
if (match == null) { if (match == null) {
throw InvalidURLError(name); throw InvalidURLError(name);

View File

@ -6,6 +6,8 @@ import 'package:obtainium/providers/source_provider.dart';
class WhatsApp extends AppSource { class WhatsApp extends AppSource {
WhatsApp() { WhatsApp() {
host = 'whatsapp.com'; host = 'whatsapp.com';
overrideVersionDetectionFormDefault('noVersionDetection',
disableStandard: true, disableRelDate: true);
} }
@override @override

View File

@ -123,7 +123,7 @@ class GeneratedFormSubForm extends GeneratedFormItem {
final List<List<GeneratedFormItem>> items; final List<List<GeneratedFormItem>> items;
GeneratedFormSubForm(super.key, this.items, GeneratedFormSubForm(super.key, this.items,
{super.label, super.belowWidgets, super.defaultValue}); {super.label, super.belowWidgets, super.defaultValue = const []});
@override @override
ensureType(val) { ensureType(val) {

View File

@ -19,7 +19,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart';
// ignore: implementation_imports // ignore: implementation_imports
import 'package:easy_localization/src/localization.dart'; import 'package:easy_localization/src/localization.dart';
const String currentVersion = '0.15.0'; const String currentVersion = '0.15.7';
const String currentReleaseTag = const String currentReleaseTag =
'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES 'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES
@ -36,7 +36,7 @@ List<MapEntry<Locale, String>> supportedLocales = const [
MapEntry(Locale('fr'), 'Français'), MapEntry(Locale('fr'), 'Français'),
MapEntry(Locale('es'), 'Español'), MapEntry(Locale('es'), 'Español'),
MapEntry(Locale('pl'), 'Polski'), MapEntry(Locale('pl'), 'Polski'),
MapEntry(Locale('ru'), 'Русский язык'), MapEntry(Locale('ru'), 'Русский'),
MapEntry(Locale('bs'), 'Bosanski'), MapEntry(Locale('bs'), 'Bosanski'),
MapEntry(Locale('pt'), 'Brasileiro'), MapEntry(Locale('pt'), 'Brasileiro'),
MapEntry(Locale('cs'), 'Česky'), MapEntry(Locale('cs'), 'Česky'),
@ -152,7 +152,6 @@ class _ObtainiumState extends State<Obtainium> {
requiresStorageNotLow: false, requiresStorageNotLow: false,
requiresDeviceIdle: false, requiresDeviceIdle: false,
requiredNetworkType: NetworkType.ANY), (String taskId) async { requiredNetworkType: NetworkType.ANY), (String taskId) async {
// We don't want periodic tasks in the foreground - ignore
await bgUpdateCheck(taskId, null); await bgUpdateCheck(taskId, null);
BackgroundFetch.finish(taskId); BackgroundFetch.finish(taskId);
}, (String taskId) async { }, (String taskId) async {
@ -237,13 +236,15 @@ class _ObtainiumState extends State<Obtainium> {
colorScheme: settingsProvider.theme == ThemeSettings.dark colorScheme: settingsProvider.theme == ThemeSettings.dark
? darkColorScheme ? darkColorScheme
: lightColorScheme, : lightColorScheme,
fontFamily: 'Metropolis'), fontFamily:
settingsProvider.useSystemFont ? 'SystemFont' : 'Metropolis'),
darkTheme: ThemeData( darkTheme: ThemeData(
useMaterial3: true, useMaterial3: true,
colorScheme: settingsProvider.theme == ThemeSettings.light colorScheme: settingsProvider.theme == ThemeSettings.light
? lightColorScheme ? lightColorScheme
: darkColorScheme, : darkColorScheme,
fontFamily: 'Metropolis'), fontFamily:
settingsProvider.useSystemFont ? 'SystemFont' : 'Metropolis'),
home: Shortcuts(shortcuts: <LogicalKeySet, Intent>{ home: Shortcuts(shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(), LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
}, child: const HomePage())); }, child: const HomePage()));

View File

@ -286,10 +286,14 @@ class AddAppPageState extends State<AddAppPage> {
selectedByDefault: true, selectedByDefault: true,
onlyOneSelectionAllowed: false, onlyOneSelectionAllowed: false,
titlesAreLinks: false, titlesAreLinks: false,
deselectThese: settingsProvider.searchDeselected,
); );
}) ?? }) ??
[]; [];
if (searchSources.isNotEmpty) { if (searchSources.isNotEmpty) {
settingsProvider.searchDeselected = sourceStrings.keys
.where((s) => !searchSources.contains(s))
.toList();
var results = await Future.wait(sourceProvider.sources var results = await Future.wait(sourceProvider.sources
.where((e) => searchSources.contains(e.name)) .where((e) => searchSources.contains(e.name))
.map((e) async { .map((e) async {
@ -306,7 +310,6 @@ class AddAppPageState extends State<AddAppPage> {
} }
})); }));
// .then((results) async {
// Interleave results instead of simple reduce // Interleave results instead of simple reduce
Map<String, List<String>> res = {}; Map<String, List<String>> res = {};
var si = 0; var si = 0;

View File

@ -5,6 +5,7 @@ import 'package:app_links/app_links.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';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:obtainium/components/generated_form_modal.dart';
import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/pages/add_app.dart'; import 'package:obtainium/pages/add_app.dart';
import 'package:obtainium/pages/apps.dart'; import 'package:obtainium/pages/apps.dart';
@ -76,14 +77,39 @@ class _HomePageState extends State<HomePage> {
try { try {
if (action == 'add') { if (action == 'add') {
await goToAddApp(data); await goToAddApp(data);
} else if (action == 'app') { } else if (action == 'app' || action == 'apps') {
await context var dataStr = Uri.decodeComponent(data);
.read<AppsProvider>() if (await showDialog(
.import('{ "apps": [${Uri.decodeComponent(data)}] }'); context: context,
} else if (action == 'apps') { builder: (BuildContext ctx) {
await context return GeneratedFormModal(
.read<AppsProvider>() title: tr('importX', args: [
.import('{ "apps": ${Uri.decodeComponent(data)} }'); action == 'app' ? tr('app') : tr('appsString')
]),
items: const [],
additionalWidgets: [
ExpansionTile(
title: const Text('Raw JSON'),
children: [
Text(
dataStr,
style: const TextStyle(fontFamily: 'monospace'),
)
],
)
],
);
}) !=
null) {
// ignore: use_build_context_synchronously
var result = await context.read<AppsProvider>().import(
action == 'app'
? '{ "apps": [$dataStr] }'
: '{ "apps": $dataStr }');
// ignore: use_build_context_synchronously
showMessage(
tr('importedX', args: [plural('apps', result.key)]), context);
}
} else { } else {
throw ObtainiumError(tr('unknown')); throw ObtainiumError(tr('unknown'));
} }

View File

@ -590,7 +590,7 @@ class _ImportErrorDialogState extends State<ImportErrorDialog> {
onPressed: () { onPressed: () {
Navigator.of(context).pop(null); Navigator.of(context).pop(null);
}, },
child: Text(tr('okay'))) child: Text(tr('ok')))
], ],
); );
} }
@ -604,11 +604,13 @@ class SelectionModal extends StatefulWidget {
this.selectedByDefault = true, this.selectedByDefault = true,
this.onlyOneSelectionAllowed = false, this.onlyOneSelectionAllowed = false,
this.titlesAreLinks = true, this.titlesAreLinks = true,
this.title}); this.title,
this.deselectThese = const []});
String? title; String? title;
Map<String, List<String>> entries; Map<String, List<String>> entries;
bool selectedByDefault; bool selectedByDefault;
List<String> deselectThese;
bool onlyOneSelectionAllowed; bool onlyOneSelectionAllowed;
bool titlesAreLinks; bool titlesAreLinks;
@ -622,9 +624,13 @@ class _SelectionModalState extends State<SelectionModal> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
for (var url in widget.entries.entries) { for (var entry in widget.entries.entries) {
entrySelections.putIfAbsent(url, entrySelections.putIfAbsent(
() => widget.selectedByDefault && !widget.onlyOneSelectionAllowed); entry,
() =>
widget.selectedByDefault &&
!widget.onlyOneSelectionAllowed &&
!widget.deselectThese.contains(entry.key));
} }
if (widget.selectedByDefault && widget.onlyOneSelectionAllowed) { if (widget.selectedByDefault && widget.onlyOneSelectionAllowed) {
selectOnlyOne(widget.entries.entries.first.key); selectOnlyOne(widget.entries.entries.first.key);

View File

@ -7,6 +7,7 @@ import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/main.dart'; import 'package:obtainium/main.dart';
import 'package:obtainium/providers/apps_provider.dart'; import 'package:obtainium/providers/apps_provider.dart';
import 'package:obtainium/providers/logs_provider.dart'; import 'package:obtainium/providers/logs_provider.dart';
import 'package:obtainium/providers/native_provider.dart';
import 'package:obtainium/providers/settings_provider.dart'; import 'package:obtainium/providers/settings_provider.dart';
import 'package:obtainium/providers/source_provider.dart'; import 'package:obtainium/providers/source_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -350,8 +351,6 @@ class _SettingsPageState extends State<SettingsPage> {
], ],
), ),
height16, height16,
installMethodDropdown,
height16,
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -364,6 +363,7 @@ class _SettingsPageState extends State<SettingsPage> {
}) })
], ],
), ),
installMethodDropdown,
height32, height32,
Text( Text(
tr('sourceSpecific'), tr('sourceSpecific'),
@ -408,6 +408,30 @@ class _SettingsPageState extends State<SettingsPage> {
height16, height16,
localeDropdown, localeDropdown,
height16, height16,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(child: Text(tr('useSystemFont'))),
Switch(
value: settingsProvider.useSystemFont,
onChanged: (useSystemFont) {
if (useSystemFont) {
NativeFeatures.loadSystemFont().then((fontLoadRes) {
if (fontLoadRes == 'ok') {
settingsProvider.useSystemFont = true;
} else {
showError(ObtainiumError(
tr('systemFontError', args: [fontLoadRes])
), context);
}
});
} else {
settingsProvider.useSystemFont = false;
}
})
],
),
height16,
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [

View File

@ -32,7 +32,7 @@ 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';
import 'package:shared_storage/shared_storage.dart' as saf; import 'package:shared_storage/shared_storage.dart' as saf;
import 'installers_provider.dart'; import 'native_provider.dart';
final pm = AndroidPackageManager(); final pm = AndroidPackageManager();
@ -522,14 +522,15 @@ class AppsProvider with ChangeNotifier {
code = await AndroidPackageInstaller.installApk( code = await AndroidPackageInstaller.installApk(
apkFilePath: file.file.path); apkFilePath: file.file.path);
case InstallMethodSettings.shizuku: case InstallMethodSettings.shizuku:
code = (await Installers.installWithShizuku( code = (await NativeFeatures.installWithShizuku(
apkFileUri: file.file.uri.toString())) apkFileUri: file.file.uri.toString()))
? 0 ? 0
: 1; : 1;
case InstallMethodSettings.root: case InstallMethodSettings.root:
code = (await Installers.installWithRoot(apkFilePath: file.file.path)) code =
? 0 (await NativeFeatures.installWithRoot(apkFilePath: file.file.path))
: 1; ? 0
: 1;
} }
bool installed = false; bool installed = false;
if (code != null && code != 0 && code != 3) { if (code != null && code != 0 && code != 3) {
@ -694,14 +695,14 @@ class AppsProvider with ChangeNotifier {
throw ObtainiumError(tr('cancelled')); throw ObtainiumError(tr('cancelled'));
} }
case InstallMethodSettings.shizuku: case InstallMethodSettings.shizuku:
int code = await Installers.checkPermissionShizuku(); int code = await NativeFeatures.checkPermissionShizuku();
if (code == -1) { if (code == -1) {
throw ObtainiumError(tr('shizukuBinderNotFound')); throw ObtainiumError(tr('shizukuBinderNotFound'));
} else if (code == 0) { } else if (code == 0) {
throw ObtainiumError(tr('cancelled')); throw ObtainiumError(tr('cancelled'));
} }
case InstallMethodSettings.root: case InstallMethodSettings.root:
if (!(await Installers.checkPermissionRoot())) { if (!(await NativeFeatures.checkPermissionRoot())) {
throw ObtainiumError(tr('cancelled')); throw ObtainiumError(tr('cancelled'));
} }
} }
@ -1300,6 +1301,9 @@ class AppsProvider with ChangeNotifier {
settingsProvider.prefs?.setInt(key, value); settingsProvider.prefs?.setInt(key, value);
} else if (value is bool) { } else if (value is bool) {
settingsProvider.prefs?.setBool(key, value); settingsProvider.prefs?.setBool(key, value);
} else if (value is List) {
settingsProvider.prefs
?.setStringList(key, value.map((e) => e as String).toList());
} else { } else {
settingsProvider.prefs?.setString(key, value as String); settingsProvider.prefs?.setString(key, value as String);
} }

View File

@ -1,12 +1,26 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
class Installers { class NativeFeatures {
static const MethodChannel _channel = MethodChannel('installers'); static const MethodChannel _channel = MethodChannel('native');
static bool _systemFontLoaded = false;
static bool _callbacksApplied = false; static bool _callbacksApplied = false;
static int _resPermShizuku = -2; // not set static int _resPermShizuku = -2; // not set
static Future waitWhile(bool Function() test, static Future<ByteData> _readFileBytes(String path) async {
var file = File(path);
var bytes = await file.readAsBytes();
return ByteData.view(bytes.buffer);
}
static Future _handleCalls(MethodCall call) async {
if (call.method == 'resPermShizuku') {
_resPermShizuku = call.arguments['res'];
}
}
static Future _waitWhile(bool Function() test,
[Duration pollInterval = const Duration(milliseconds: 250)]) { [Duration pollInterval = const Duration(milliseconds: 250)]) {
var completer = Completer(); var completer = Completer();
check() { check() {
@ -20,20 +34,25 @@ class Installers {
return completer.future; return completer.future;
} }
static Future handleCalls(MethodCall call) async { static Future<String> loadSystemFont() async {
if (call.method == 'resPermShizuku') { if (_systemFontLoaded) { return "ok"; }
_resPermShizuku = call.arguments['res']; var getFontRes = await _channel.invokeMethod('getSystemFont');
} if (getFontRes[0] != '/') { return getFontRes; } // Error
var fontLoader = FontLoader('SystemFont');
fontLoader.addFont(_readFileBytes(getFontRes));
await fontLoader.load();
_systemFontLoaded = true;
return "ok";
} }
static Future<int> checkPermissionShizuku() async { static Future<int> checkPermissionShizuku() async {
if (!_callbacksApplied) { if (!_callbacksApplied) {
_channel.setMethodCallHandler(handleCalls); _channel.setMethodCallHandler(_handleCalls);
_callbacksApplied = true; _callbacksApplied = true;
} }
int res = await _channel.invokeMethod('checkPermissionShizuku'); int res = await _channel.invokeMethod('checkPermissionShizuku');
if(res == -2) { if (res == -2) {
await waitWhile(() => _resPermShizuku == -2); await _waitWhile(() => _resPermShizuku == -2);
res = _resPermShizuku; res = _resPermShizuku;
_resPermShizuku = -2; _resPermShizuku = -2;
} }

View File

@ -51,6 +51,15 @@ class SettingsProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
bool get useSystemFont {
return prefs?.getBool('useSystemFont') ?? false;
}
set useSystemFont(bool useSystemFont) {
prefs?.setBool('useSystemFont', useSystemFont);
notifyListeners();
}
InstallMethodSettings get installMethod { InstallMethodSettings get installMethod {
return InstallMethodSettings.values[ return InstallMethodSettings.values[
prefs?.getInt('installMethod') ?? InstallMethodSettings.normal.index]; prefs?.getInt('installMethod') ?? InstallMethodSettings.normal.index];
@ -446,4 +455,13 @@ class SettingsProvider with ChangeNotifier {
prefs?.setBool('parallelDownloads', val); prefs?.setBool('parallelDownloads', val);
notifyListeners(); notifyListeners();
} }
List<String> get searchDeselected {
return prefs?.getStringList('searchDeselected') ?? [];
}
set searchDeselected(List<String> list) {
prefs?.setStringList('searchDeselected', list);
notifyListeners();
}
} }

View File

@ -147,7 +147,7 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
} }
// HTML single 'intermediate link' should be converted to multi-support version // HTML single 'intermediate link' should be converted to multi-support version
if (originalAdditionalSettings['intermediateLinkRegex'] != null && if (originalAdditionalSettings['intermediateLinkRegex'] != null &&
additionalSettings['intermediateLink']?.isNotEmpty != true) { additionalSettings['intermediateLinkRegex']?.isNotEmpty != true) {
additionalSettings['intermediateLink'] = [ additionalSettings['intermediateLink'] = [
{ {
'customLinkFilterRegex': 'customLinkFilterRegex':
@ -157,6 +157,30 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
} }
]; ];
} }
if ((additionalSettings['intermediateLink']?.length ?? 0) > 0) {
additionalSettings['intermediateLink'] =
additionalSettings['intermediateLink'].where((e) {
return e['customLinkFilterRegex']?.isNotEmpty == true;
}).toList();
}
// Steam source apps should be converted to HTML (#1244)
var legacySteamSourceApps = SteamMobile().apks.keys;
if (legacySteamSourceApps.contains(additionalSettings['app'] ?? '')) {
json['url'] = '${json['url']}/mobile';
var replacementAdditionalSettings = getDefaultValuesFromFormItems(
HTML().combinedAppSpecificSettingFormItems);
for (var s in replacementAdditionalSettings.keys) {
if (additionalSettings.containsKey(s)) {
replacementAdditionalSettings[s] = additionalSettings[s];
}
}
replacementAdditionalSettings['customLinkFilterRegex'] =
'/${additionalSettings['app']}-(([0-9]+\\.?){1,})\\.apk';
replacementAdditionalSettings['versionExtractionRegEx'] =
replacementAdditionalSettings['customLinkFilterRegex'];
replacementAdditionalSettings['matchGroupToUse'] = '\$1';
additionalSettings = replacementAdditionalSettings;
}
} }
json['additionalSettings'] = jsonEncode(additionalSettings); json['additionalSettings'] = jsonEncode(additionalSettings);
// F-Droid no longer needs cloudflare exception since override can be used - migrate apps appropriately // F-Droid no longer needs cloudflare exception since override can be used - migrate apps appropriately
@ -438,6 +462,16 @@ abstract class AppSource {
label: tr('trackOnly'), label: tr('trackOnly'),
) )
], ],
[
GeneratedFormTextField('versionExtractionRegEx',
label: tr('versionExtractionRegEx'),
required: false,
additionalValidators: [(value) => regExValidator(value)]),
],
[
GeneratedFormTextField('matchGroupToUse',
label: tr('matchGroupToUse'), required: false, hint: '\$0')
],
[ [
GeneratedFormDropdown( GeneratedFormDropdown(
'versionDetection', 'versionDetection',
@ -574,6 +608,57 @@ bool isTempId(App app) {
return RegExp('^[0-9]+\$').hasMatch(app.id); return RegExp('^[0-9]+\$').hasMatch(app.id);
} }
replaceMatchGroupsInString(RegExpMatch match, String matchGroupString) {
if (RegExp('^\\d+\$').hasMatch(matchGroupString)) {
matchGroupString = '\$$matchGroupString';
}
// Regular expression to match numbers in the input string
final numberRegex = RegExp(r'\$\d+');
// Extract all numbers from the input string
final numbers = numberRegex.allMatches(matchGroupString);
if (numbers.isEmpty) {
// If no numbers found, return the original string
return null;
}
// Replace numbers with corresponding match groups
var outputString = matchGroupString;
for (final numberMatch in numbers) {
final number = numberMatch.group(0)!;
final matchGroup = match.group(int.parse(number.substring(1))) ?? '';
// Check if the number is preceded by a single backslash
final isEscaped = outputString.contains('\\$number');
// Replace the number with the corresponding match group
if (!isEscaped) {
outputString = outputString.replaceAll(number, matchGroup);
} else {
outputString = outputString.replaceAll('\\$number', number);
}
}
return outputString;
}
String? extractVersion(String? versionExtractionRegEx, String? matchGroupString,
String stringToCheck) {
if (versionExtractionRegEx?.isNotEmpty == true) {
String? version = stringToCheck;
var match = RegExp(versionExtractionRegEx!).allMatches(version);
if (match.isEmpty) {
throw NoVersionError();
}
matchGroupString = matchGroupString?.trim() ?? '';
if (matchGroupString.isEmpty) {
matchGroupString = "0";
}
version = replaceMatchGroupsInString(match.last, matchGroupString);
if (version?.isNotEmpty != true) {
throw NoVersionError();
}
return version!;
} else {
return null;
}
}
class SourceProvider { class SourceProvider {
// Add more source classes here so they are available via the service // Add more source classes here so they are available via the service
List<AppSource> get sources => [ List<AppSource> get sources => [
@ -591,13 +676,11 @@ class SourceProvider {
APKMirror(), APKMirror(),
HuaweiAppGallery(), HuaweiAppGallery(),
Jenkins(), Jenkins(),
// APKCombo(), // Can't get past their scraping blocking yet (get 403 Forbidden)
Mullvad(), Mullvad(),
Signal(), Signal(),
VLC(), VLC(),
WhatsApp(), // As of 2023-03-20 this is unusable as the version on the webpage is months out of date WhatsApp(),
TelegramApp(), TelegramApp(),
SteamMobile(),
NeutronCode(), NeutronCode(),
HTML() // This should ALWAYS be the last option as they are tried in order HTML() // This should ALWAYS be the last option as they are tried in order
]; ];
@ -673,6 +756,18 @@ class SourceProvider {
String standardUrl = source.standardizeUrl(url); String standardUrl = source.standardizeUrl(url);
APKDetails apk = APKDetails apk =
await source.getLatestAPKDetails(standardUrl, additionalSettings); await source.getLatestAPKDetails(standardUrl, additionalSettings);
if (source.runtimeType != HTML().runtimeType) {
// HTML does it separately
String? extractedVersion = extractVersion(
additionalSettings['versionExtractionRegEx'] as String?,
additionalSettings['matchGroupToUse'] as String?,
apk.version);
if (extractedVersion != null) {
apk.version = extractedVersion;
}
}
if (additionalSettings['versionDetection'] == 'releaseDateAsVersion' && if (additionalSettings['versionDetection'] == 'releaseDateAsVersion' &&
apk.releaseDate != null) { apk.releaseDate != null) {
apk.version = apk.releaseDate!.microsecondsSinceEpoch.toString(); apk.version = apk.releaseDate!.microsecondsSinceEpoch.toString();

View File

@ -30,10 +30,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: animations name: animations
sha256: "708e4b68c23228c264b038fe7003a2f5d01ce85fc64d8cae090e86b27fcea6c5" sha256: d3d6dcfb218225bbe68e87ccf6378bbb2e32a94900722c5f81611dad089911cb
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.10" version: "2.0.11"
app_links: app_links:
dependency: "direct main" dependency: "direct main"
description: description:
@ -46,10 +46,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: archive name: archive
sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.4.9" version: "3.4.10"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -328,10 +328,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_markdown name: flutter_markdown
sha256: "35108526a233cc0755664d445f8a6b4b61e6f8fe993b3658b80b4a26827fc196" sha256: "30088ce826b5b9cfbf9e8bece34c716c8a59fa54461dcae1e4ac01a94639e762"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.18+2" version: "0.6.18+3"
flutter_plugin_android_lifecycle: flutter_plugin_android_lifecycle:
dependency: transitive dependency: transitive
description: description:
@ -610,18 +610,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: platform name: platform
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.3" version: "3.1.4"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: plugin_platform_interface name: plugin_platform_interface
sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.7" version: "2.1.8"
pointycastle: pointycastle:
dependency: transitive dependency: transitive
description: description:
@ -831,18 +831,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" sha256: c0766a55ab42cefaa728cabc951e82919ab41a3a4fee0aaa96176ca82da8cc51
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.0" version: "6.2.1"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 sha256: "46b81e3109cbb2d6b81702ad3077540789a3e74e22795eb9f0b7d494dbaa72ea"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.1" version: "6.2.2"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
@ -863,18 +863,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_platform_interface name: url_launcher_platform_interface
sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" sha256: "4aca1e060978e19b2998ee28503f40b5ba6226819c2b5e3e4d1821e8ccd92198"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.3.0"
url_launcher_web: url_launcher_web:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9" sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.2" version: "2.2.3"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
@ -911,18 +911,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: webview_flutter name: webview_flutter
sha256: "42393b4492e629aa3a88618530a4a00de8bb46e50e7b3993fedbfdc5352f0dbf" sha256: "60e23976834e995c404c0b21d3b9db37ecd77d3303ef74f8b8d7a7b19947fc04"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.4.2" version: "4.4.3"
webview_flutter_android: webview_flutter_android:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_android name: webview_flutter_android
sha256: b54c89fe14a6d26a2a46e24880da0441cdd2bf1f6d01a5b3e1d39558feb1de0b sha256: "161af93c2abaf94ef2192bffb53a3658b2d721a3bf99b69aa1e47814ee18cc96"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.13.1" version: "3.13.2"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -935,18 +935,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_wkwebview name: webview_flutter_wkwebview
sha256: eebfabfa8a115b535b52031b8b26f7a4b58ceceab378bc9db8762b0fb46f7b5d sha256: "02d8f3ebbc842704b2b662377b3ee11c0f8f1bbaa8eab6398262f40049819160"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.10.0" version: "3.10.1"
win32: win32:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.1.1" version: "5.2.0"
win32_registry: win32_registry:
dependency: transitive dependency: transitive
description: description:
@ -959,10 +959,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.3" version: "1.0.4"
xml: xml:
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: 0.15.0+236 # When changing this, update the tag in main() accordingly version: 0.15.7+243 # When changing this, update the tag in main() accordingly
environment: environment:
sdk: '>=3.0.0 <4.0.0' sdk: '>=3.0.0 <4.0.0'