mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-20 16:19:41 +02:00
Compare commits
58 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d33ca0948f | ||
|
f76637a2e1 | ||
|
b7de627c7b | ||
|
27fc60d437 | ||
|
ec240f946e | ||
|
ecd80fc371 | ||
|
68fa660e6d | ||
|
70f9e33d17 | ||
|
2e2dffd8e2 | ||
|
0b1d5bf514 | ||
|
2570c8e289 | ||
|
43a8ba4de1 | ||
|
3f2fb1c1ed | ||
|
40d303fb57 | ||
|
2c1687c33d | ||
|
b688e7f160 | ||
|
0c80d88583 | ||
|
b293b1e9ff | ||
|
61038a8969 | ||
|
b92d1541bf | ||
|
13f0ccb10d | ||
|
ed732cfad2 | ||
|
fb206aee84 | ||
|
285530784d | ||
|
0ddb5b5e81 | ||
|
c16cda1962 | ||
|
49022726d3 | ||
|
a311894b9f | ||
|
29e13efd66 | ||
|
8c2a97e092 | ||
|
34d571f586 | ||
|
a20b87889b | ||
|
c7319cd958 | ||
|
d61fd800ef | ||
|
12dda8bfa9 | ||
|
0657f832e1 | ||
|
6431357b15 | ||
|
dcc42bdfe5 | ||
|
85718dc3a3 | ||
|
9dff352796 | ||
|
c5477767a0 | ||
|
3131ef8c4e | ||
|
4d9f05aa87 | ||
|
7b882d9bd8 | ||
|
d1a2831922 | ||
|
b042050ea3 | ||
|
2d43dfe0a7 | ||
|
b1a740223c | ||
|
41c98d97b1 | ||
|
fb06babb96 | ||
|
ccc0e7696b | ||
|
6d41ed8011 | ||
|
c1476a7d58 | ||
|
2289e58dda | ||
|
049bcfbaf5 | ||
|
5b5f922b54 | ||
|
6545498c21 | ||
|
9717db0ca4 |
2
.flutter
2
.flutter
Submodule .flutter updated: 300451adae...54e66469a9
10
README.md
10
README.md
@@ -4,11 +4,13 @@
|
|||||||
|
|
||||||
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)
|
More info:
|
||||||
|
- [Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki)
|
||||||
Read the Wiki: [https://github.com/ImranR98/Obtainium/wiki](https://github.com/ImranR98/Obtainium/wiki)
|
- [AppVerifier](https://github.com/soupslurpr/AppVerifier) - App verification tool (recommended, integrates with Obtainium)
|
||||||
|
- [apps.obtainium.imranr.dev](https://apps.obtainium.imranr.dev/) - Crowdsourced app configurations
|
||||||
|
- [Side Of Burritos - You should use this instead of F-Droid | How to use app RSS feed](https://youtu.be/FFz57zNR_M0) - Original motivation for this app
|
||||||
|
|
||||||
Currently supported App sources:
|
Currently supported App sources:
|
||||||
- Open Source - General:
|
- Open Source - General:
|
||||||
|
@@ -92,20 +92,6 @@ repositories {
|
|||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
|
||||||
def shizuku_version = '13.1.5'
|
|
||||||
implementation "dev.rikka.shizuku:api:$shizuku_version"
|
|
||||||
implementation "dev.rikka.shizuku:provider:$shizuku_version"
|
|
||||||
|
|
||||||
def hidden_api_version = '4.3.1'
|
|
||||||
implementation "dev.rikka.tools.refine:runtime:$hidden_api_version"
|
|
||||||
implementation "dev.rikka.hidden:compat:$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"
|
|
||||||
}
|
|
||||||
|
|
||||||
ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3]
|
ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3]
|
||||||
import com.android.build.OutputFile
|
import com.android.build.OutputFile
|
||||||
android.applicationVariants.all { variant ->
|
android.applicationVariants.all { variant ->
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
android:value="2" />
|
android:value="2" />
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="dev.imranr.obtainium"
|
android:authorities="${applicationId}"
|
||||||
android:grantUriPermissions="true">
|
android:grantUriPermissions="true">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
@@ -1,44 +0,0 @@
|
|||||||
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"
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,179 +1,5 @@
|
|||||||
package dev.imranr.obtainium
|
package dev.imranr.obtainium
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.IntentSender
|
|
||||||
import android.content.pm.IPackageInstaller
|
|
||||||
import android.content.pm.IPackageInstallerSession
|
|
||||||
import android.content.pm.PackageInstaller
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Process
|
|
||||||
import androidx.annotation.NonNull
|
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
import dev.imranr.obtainium.util.IIntentSenderAdaptor
|
|
||||||
import dev.imranr.obtainium.util.IntentSenderUtils
|
|
||||||
import dev.imranr.obtainium.util.PackageInstallerUtils
|
|
||||||
import dev.imranr.obtainium.util.ShizukuSystemServerApi
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
|
||||||
import io.flutter.plugin.common.MethodChannel
|
|
||||||
import io.flutter.plugin.common.MethodChannel.Result
|
|
||||||
import java.io.IOException
|
|
||||||
import java.util.concurrent.CountDownLatch
|
|
||||||
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
|
||||||
import rikka.shizuku.Shizuku
|
|
||||||
import rikka.shizuku.Shizuku.OnRequestPermissionResultListener
|
|
||||||
import rikka.shizuku.ShizukuBinderWrapper
|
|
||||||
|
|
||||||
class MainActivity: FlutterActivity() {
|
class MainActivity: FlutterActivity()
|
||||||
private var nativeChannel: MethodChannel? = null
|
|
||||||
private val SHIZUKU_PERMISSION_REQUEST_CODE = (10..200).random()
|
|
||||||
|
|
||||||
private fun shizukuCheckPermission(result: Result) {
|
|
||||||
try {
|
|
||||||
if (Shizuku.isPreV11()) { // Unsupported
|
|
||||||
result.success(-1)
|
|
||||||
} else if (Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
result.success(1)
|
|
||||||
} else if (Shizuku.shouldShowRequestPermissionRationale()) { // Deny and don't ask again
|
|
||||||
result.success(0)
|
|
||||||
} else {
|
|
||||||
Shizuku.requestPermission(SHIZUKU_PERMISSION_REQUEST_CODE)
|
|
||||||
result.success(-2)
|
|
||||||
}
|
|
||||||
} catch (_: Exception) { // If shizuku not running
|
|
||||||
result.success(-1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val shizukuRequestPermissionResultListener = OnRequestPermissionResultListener {
|
|
||||||
requestCode: Int, grantResult: Int ->
|
|
||||||
if (requestCode == SHIZUKU_PERMISSION_REQUEST_CODE) {
|
|
||||||
val res = if (grantResult == PackageManager.PERMISSION_GRANTED) 1 else 0
|
|
||||||
nativeChannel!!.invokeMethod("resPermShizuku", mapOf("res" to res))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun shizukuInstallApk(apkFileUri: String, result: Result) {
|
|
||||||
val uri = Uri.parse(apkFileUri)
|
|
||||||
var res = false
|
|
||||||
var session: PackageInstaller.Session? = null
|
|
||||||
try {
|
|
||||||
val iPackageInstaller: IPackageInstaller =
|
|
||||||
ShizukuSystemServerApi.PackageManager_getPackageInstaller()
|
|
||||||
val isRoot = Shizuku.getUid() == 0
|
|
||||||
// The reason for use "com.android.shell" as installer package under adb
|
|
||||||
// is that getMySessions will check installer package's owner
|
|
||||||
val installerPackageName = if (isRoot) packageName else "com.android.shell"
|
|
||||||
var installerAttributionTag: String? = null
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
installerAttributionTag = attributionTag
|
|
||||||
}
|
|
||||||
val userId = if (isRoot) Process.myUserHandle().hashCode() else 0
|
|
||||||
val packageInstaller = PackageInstallerUtils.createPackageInstaller(
|
|
||||||
iPackageInstaller, installerPackageName, installerAttributionTag, userId)
|
|
||||||
val params =
|
|
||||||
PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
|
|
||||||
var installFlags: Int = PackageInstallerUtils.getInstallFlags(params)
|
|
||||||
installFlags = installFlags or (0x00000002/*PackageManager.INSTALL_REPLACE_EXISTING*/
|
|
||||||
or 0x00000004 /*PackageManager.INSTALL_ALLOW_TEST*/)
|
|
||||||
PackageInstallerUtils.setInstallFlags(params, installFlags)
|
|
||||||
val sessionId = packageInstaller.createSession(params)
|
|
||||||
val iSession = IPackageInstallerSession.Stub.asInterface(
|
|
||||||
ShizukuBinderWrapper(iPackageInstaller.openSession(sessionId).asBinder()))
|
|
||||||
session = PackageInstallerUtils.createSession(iSession)
|
|
||||||
val inputStream = contentResolver.openInputStream(uri)
|
|
||||||
val openedSession = session.openWrite("apk.apk", 0, -1)
|
|
||||||
val buffer = ByteArray(8192)
|
|
||||||
var length: Int
|
|
||||||
try {
|
|
||||||
while (inputStream!!.read(buffer).also { length = it } > 0) {
|
|
||||||
openedSession.write(buffer, 0, length)
|
|
||||||
openedSession.flush()
|
|
||||||
session.fsync(openedSession)
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
inputStream!!.close()
|
|
||||||
openedSession.close()
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val results = arrayOf<Intent?>(null)
|
|
||||||
val countDownLatch = CountDownLatch(1)
|
|
||||||
val intentSender: IntentSender =
|
|
||||||
IntentSenderUtils.newInstance(object : IIntentSenderAdaptor() {
|
|
||||||
override fun send(intent: Intent?) {
|
|
||||||
results[0] = intent
|
|
||||||
countDownLatch.countDown()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
session.commit(intentSender)
|
|
||||||
countDownLatch.await()
|
|
||||||
res = results[0]!!.getIntExtra(
|
|
||||||
PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE) == 0
|
|
||||||
} catch (_: Exception) {
|
|
||||||
res = false
|
|
||||||
} finally {
|
|
||||||
if (session != null) {
|
|
||||||
try {
|
|
||||||
session.close()
|
|
||||||
} catch (_: Exception) {
|
|
||||||
res = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.success(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rootCheckPermission(result: Result) {
|
|
||||||
Shell.getShell(Shell.GetShellCallback(
|
|
||||||
fun(shell: Shell) {
|
|
||||||
result.success(shell.isRoot)
|
|
||||||
}
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rootInstallApk(apkFilePath: String, result: Result) {
|
|
||||||
Shell.sh("pm install -r -t " + apkFilePath).submit { out ->
|
|
||||||
val builder = StringBuilder()
|
|
||||||
for (data in out.getOut()) { builder.append(data) }
|
|
||||||
result.success(builder.toString().endsWith("Success"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
|
||||||
super.configureFlutterEngine(flutterEngine)
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
||||||
HiddenApiBypass.addHiddenApiExemptions("")
|
|
||||||
}
|
|
||||||
Shizuku.addRequestPermissionResultListener(shizukuRequestPermissionResultListener)
|
|
||||||
nativeChannel = MethodChannel(
|
|
||||||
flutterEngine.dartExecutor.binaryMessenger, "native")
|
|
||||||
nativeChannel!!.setMethodCallHandler {
|
|
||||||
call, result ->
|
|
||||||
if (call.method == "getSystemFont") {
|
|
||||||
val res = DefaultSystemFont().get()
|
|
||||||
result.success(res)
|
|
||||||
} else if (call.method == "checkPermissionShizuku") {
|
|
||||||
shizukuCheckPermission(result)
|
|
||||||
} else if (call.method == "checkPermissionRoot") {
|
|
||||||
rootCheckPermission(result)
|
|
||||||
} else if (call.method == "installWithShizuku") {
|
|
||||||
val apkFileUri: String? = call.argument("apkFileUri")
|
|
||||||
shizukuInstallApk(apkFileUri!!, result)
|
|
||||||
} else if (call.method == "installWithRoot") {
|
|
||||||
val apkFilePath: String? = call.argument("apkFilePath")
|
|
||||||
rootInstallApk(apkFilePath!!, result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
Shizuku.removeRequestPermissionResultListener(shizukuRequestPermissionResultListener)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -1,37 +0,0 @@
|
|||||||
package dev.imranr.obtainium.util;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Application;
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class ApplicationUtils {
|
|
||||||
|
|
||||||
private static Application application;
|
|
||||||
|
|
||||||
public static Application getApplication() {
|
|
||||||
return application;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setApplication(Application application) {
|
|
||||||
ApplicationUtils.application = application;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getProcessName() {
|
|
||||||
if (Build.VERSION.SDK_INT >= 28)
|
|
||||||
return Application.getProcessName();
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
@SuppressLint("PrivateApi")
|
|
||||||
Class<?> activityThread = Class.forName("android.app.ActivityThread");
|
|
||||||
@SuppressLint("DiscouragedPrivateApi")
|
|
||||||
Method method = activityThread.getDeclaredMethod("currentProcessName");
|
|
||||||
return (String) method.invoke(null);
|
|
||||||
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
package dev.imranr.obtainium.util;
|
|
||||||
|
|
||||||
import android.content.IIntentReceiver;
|
|
||||||
import android.content.IIntentSender;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.IBinder;
|
|
||||||
|
|
||||||
public abstract class IIntentSenderAdaptor extends IIntentSender.Stub {
|
|
||||||
|
|
||||||
public abstract void send(Intent intent);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int send(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
|
|
||||||
send(intent);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
|
|
||||||
send(intent);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
package dev.imranr.obtainium.util;
|
|
||||||
|
|
||||||
import android.content.IIntentSender;
|
|
||||||
import android.content.IntentSender;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
public class IntentSenderUtils {
|
|
||||||
|
|
||||||
public static IntentSender newInstance(IIntentSender binder) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
|
||||||
//noinspection JavaReflectionMemberAccess
|
|
||||||
return IntentSender.class.getConstructor(IIntentSender.class).newInstance(binder);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,41 +0,0 @@
|
|||||||
package dev.imranr.obtainium.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.IPackageInstaller;
|
|
||||||
import android.content.pm.IPackageInstallerSession;
|
|
||||||
import android.content.pm.PackageInstaller;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
@SuppressWarnings({"JavaReflectionMemberAccess"})
|
|
||||||
public class PackageInstallerUtils {
|
|
||||||
|
|
||||||
public static PackageInstaller createPackageInstaller(IPackageInstaller installer, String installerPackageName, String installerAttributionTag, int userId) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
return PackageInstaller.class.getConstructor(IPackageInstaller.class, String.class, String.class, int.class)
|
|
||||||
.newInstance(installer, installerPackageName, installerAttributionTag, userId);
|
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
return PackageInstaller.class.getConstructor(IPackageInstaller.class, String.class, int.class)
|
|
||||||
.newInstance(installer, installerPackageName, userId);
|
|
||||||
} else {
|
|
||||||
return PackageInstaller.class.getConstructor(Context.class, PackageManager.class, IPackageInstaller.class, String.class, int.class)
|
|
||||||
.newInstance(ApplicationUtils.getApplication(), ApplicationUtils.getApplication().getPackageManager(), installer, installerPackageName, userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PackageInstaller.Session createSession(IPackageInstallerSession session) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
|
||||||
return PackageInstaller.Session.class.getConstructor(IPackageInstallerSession.class)
|
|
||||||
.newInstance(session);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getInstallFlags(PackageInstaller.SessionParams params) throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
return (int) PackageInstaller.SessionParams.class.getDeclaredField("installFlags").get(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setInstallFlags(PackageInstaller.SessionParams params, int newValue) throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
PackageInstaller.SessionParams.class.getDeclaredField("installFlags").set(params, newValue);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,68 +0,0 @@
|
|||||||
package dev.imranr.obtainium.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.IPackageInstaller;
|
|
||||||
import android.content.pm.IPackageManager;
|
|
||||||
import android.content.pm.UserInfo;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.IUserManager;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import rikka.shizuku.ShizukuBinderWrapper;
|
|
||||||
import rikka.shizuku.SystemServiceHelper;
|
|
||||||
|
|
||||||
public class ShizukuSystemServerApi {
|
|
||||||
|
|
||||||
private static final Singleton<IPackageManager> PACKAGE_MANAGER = new Singleton<IPackageManager>() {
|
|
||||||
@Override
|
|
||||||
protected IPackageManager create() {
|
|
||||||
return IPackageManager.Stub.asInterface(new ShizukuBinderWrapper(SystemServiceHelper.getSystemService("package")));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Singleton<IUserManager> USER_MANAGER = new Singleton<IUserManager>() {
|
|
||||||
@Override
|
|
||||||
protected IUserManager create() {
|
|
||||||
return IUserManager.Stub.asInterface(new ShizukuBinderWrapper(SystemServiceHelper.getSystemService(Context.USER_SERVICE)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static IPackageInstaller PackageManager_getPackageInstaller() throws RemoteException {
|
|
||||||
IPackageInstaller packageInstaller = PACKAGE_MANAGER.get().getPackageInstaller();
|
|
||||||
return IPackageInstaller.Stub.asInterface(new ShizukuBinderWrapper(packageInstaller.asBinder()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<UserInfo> UserManager_getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated) throws RemoteException {
|
|
||||||
if (Build.VERSION.SDK_INT >= 30) {
|
|
||||||
return USER_MANAGER.get().getUsers(excludePartial, excludeDying, excludePreCreated);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
return USER_MANAGER.get().getUsers(excludeDying);
|
|
||||||
} catch (NoSuchFieldError e) {
|
|
||||||
return USER_MANAGER.get().getUsers(excludePartial, excludeDying, excludePreCreated);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// method 2: use transactRemote directly
|
|
||||||
/*public static List<UserInfo> UserManager_getUsers(boolean excludeDying) {
|
|
||||||
Parcel data = SystemServiceHelper.obtainParcel(Context.USER_SERVICE, "android.os.IUserManager", "getUsers");
|
|
||||||
Parcel reply = Parcel.obtain();
|
|
||||||
data.writeInt(excludeDying ? 1 : 0);
|
|
||||||
|
|
||||||
List<UserInfo> res = null;
|
|
||||||
try {
|
|
||||||
ShizukuService.transactRemote(data, reply, 0);
|
|
||||||
reply.readException();
|
|
||||||
res = reply.createTypedArrayList(UserInfo.CREATOR);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e("ShizukuSample", "UserManager#getUsers", e);
|
|
||||||
} finally {
|
|
||||||
data.recycle();
|
|
||||||
reply.recycle();
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}*/
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
package dev.imranr.obtainium.util;
|
|
||||||
|
|
||||||
public abstract class Singleton<T> {
|
|
||||||
|
|
||||||
private T mInstance;
|
|
||||||
|
|
||||||
protected abstract T create();
|
|
||||||
|
|
||||||
public final T get() {
|
|
||||||
synchronized (this) {
|
|
||||||
if (mInstance == null) {
|
|
||||||
mInstance = create();
|
|
||||||
}
|
|
||||||
return mInstance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx2048M
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(obavezno)",
|
"requiredInBrackets": "(obavezno)",
|
||||||
"dropdownNoOptsError": "GREŠKA: PADAJUĆI MENI MORA IMATI NAJMANJE JEDNU OPCIJU",
|
"dropdownNoOptsError": "GREŠKA: PADAJUĆI MENI MORA IMATI NAJMANJE JEDNU OPCIJU",
|
||||||
"colour": "Boja",
|
"colour": "Boja",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Custom",
|
||||||
|
"useMaterialYou": "Use Material You",
|
||||||
"githubStarredRepos": "GitHub repo-i sa zvjezdicom",
|
"githubStarredRepos": "GitHub repo-i sa zvjezdicom",
|
||||||
"uname": "Korisničko ime",
|
"uname": "Korisničko ime",
|
||||||
"wrongArgNum": "Naveden je pogrešan broj argumenata",
|
"wrongArgNum": "Naveden je pogrešan broj argumenata",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Nema novih ažuriranja.",
|
"noNewUpdates": "Nema novih ažuriranja.",
|
||||||
"xHasAnUpdate": "{} ima ažuriranje.",
|
"xHasAnUpdate": "{} ima ažuriranje.",
|
||||||
"appsUpdated": "Aplikacije su ažurirane",
|
"appsUpdated": "Aplikacije su ažurirane",
|
||||||
|
"appsNotUpdated": "Failed to update applications",
|
||||||
"appsUpdatedNotifDescription": "Obavještava korisnika da su u pozadini primijenjena ažuriranja na jednu ili više aplikacija",
|
"appsUpdatedNotifDescription": "Obavještava korisnika da su u pozadini primijenjena ažuriranja na jednu ili više aplikacija",
|
||||||
"xWasUpdatedToY": "{} je ažuriran na {}.",
|
"xWasUpdatedToY": "{} je ažuriran na {}.",
|
||||||
|
"xWasNotUpdatedToY": "Failed to update {} to {}.",
|
||||||
"errorCheckingUpdates": "Greška pri provjeri ažuriranja",
|
"errorCheckingUpdates": "Greška pri provjeri ažuriranja",
|
||||||
"errorCheckingUpdatesNotifDescription": "Obavijest koja se prikazuje kada provjera sigurnosnog ažuriranja ne uspije",
|
"errorCheckingUpdatesNotifDescription": "Obavijest koja se prikazuje kada provjera sigurnosnog ažuriranja ne uspije",
|
||||||
"appsRemoved": "Aplikacije su uklonjene",
|
"appsRemoved": "Aplikacije su uklonjene",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Podržite fiksne APK URL-ove",
|
"supportFixedAPKURL": "Podržite fiksne APK URL-ove",
|
||||||
"selectX": "Izaberite {}",
|
"selectX": "Izaberite {}",
|
||||||
"parallelDownloads": "Dozvoli paralelna preuzimanja",
|
"parallelDownloads": "Dozvoli paralelna preuzimanja",
|
||||||
"installMethod": "Način instalacije",
|
"useShizuku": "Use Shizuku or Sui to install",
|
||||||
"normal": "normalno",
|
|
||||||
"root": "korijen",
|
|
||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
|
"shizukuOld": "Old Shizuku version (<11) - update it",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku running on Android < 8.1 with ADB - update Android or use Sui instead",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Set Google Play as the installation source (if Shizuku is used)",
|
||||||
"useSystemFont": "Koristite sistemski font",
|
"useSystemFont": "Koristite sistemski font",
|
||||||
"systemFontError": "Greška pri učitavanju sistemskog fonta: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Koristite kod verzije aplikacije kao verziju koju je otkrio OS",
|
"useVersionCodeAsOSVersion": "Koristite kod verzije aplikacije kao verziju koju je otkrio OS",
|
||||||
"requestHeader": "Zaglavlje zahtjeva",
|
"requestHeader": "Zaglavlje zahtjeva",
|
||||||
"useLatestAssetDateAsReleaseDate": "Koristite najnovije otpremanje materijala kao datum izdavanja",
|
"useLatestAssetDateAsReleaseDate": "Koristite najnovije otpremanje materijala kao datum izdavanja",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} i još 1 aplikacija je ažurirana.",
|
"one": "{} i još 1 aplikacija je ažurirana.",
|
||||||
"other": "{} i još {} aplikacija je ažurirano."
|
"other": "{} i još {} aplikacija je ažurirano."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Failed to update {} and 1 more app.",
|
||||||
|
"other": "Failed to update {} and {} more apps."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} i još jedna aplikacija je vjerovatno ažurirana.",
|
"one": "{} i još jedna aplikacija je vjerovatno ažurirana.",
|
||||||
"other": "{} i još {} aplikacija su vjerovatno ažurirane."
|
"other": "{} i još {} aplikacija su vjerovatno ažurirane."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Požadované)",
|
"requiredInBrackets": "(Požadované)",
|
||||||
"dropdownNoOptsError": "ERROR: DROPDOWN MUSÍ MÍT AŽ JEDNU MOŽNOST",
|
"dropdownNoOptsError": "ERROR: DROPDOWN MUSÍ MÍT AŽ JEDNU MOŽNOST",
|
||||||
"colour": "Barva",
|
"colour": "Barva",
|
||||||
|
"standard": "Standardní",
|
||||||
|
"custom": "Vlastní",
|
||||||
|
"useMaterialYou": "Použijte materiál, který jste",
|
||||||
"githubStarredRepos": "GitHub označená hvězdičkou",
|
"githubStarredRepos": "GitHub označená hvězdičkou",
|
||||||
"uname": "Uživatelské jméno",
|
"uname": "Uživatelské jméno",
|
||||||
"wrongArgNum": "Nesprávný počet zadaných argumentů",
|
"wrongArgNum": "Nesprávný počet zadaných argumentů",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Žádné nové aktualizace.",
|
"noNewUpdates": "Žádné nové aktualizace.",
|
||||||
"xHasAnUpdate": "{} má aktualizaci.",
|
"xHasAnUpdate": "{} má aktualizaci.",
|
||||||
"appsUpdated": "Aplikace aktualizovány",
|
"appsUpdated": "Aplikace aktualizovány",
|
||||||
|
"appsNotUpdated": "Nepodařilo se aktualizovat aplikace",
|
||||||
"appsUpdatedNotifDescription": "Upozornit, ž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": "{} byla aktualizována na {}",
|
"xWasUpdatedToY": "{} byla aktualizována na {}",
|
||||||
|
"xWasNotUpdatedToY": "Nepodařilo se aktualizovat {} na {}.",
|
||||||
"errorCheckingUpdates": "Chyba kontroly aktualizací",
|
"errorCheckingUpdates": "Chyba kontroly aktualizací",
|
||||||
"errorCheckingUpdatesNotifDescription": "Zobrazit oznámení 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",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"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",
|
"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": "Vybrat {}",
|
"selectX": "Vybrat {}",
|
||||||
"parallelDownloads": "Povolit souběžné stahování",
|
"parallelDownloads": "Povolit souběžné stahování",
|
||||||
"installMethod": "Metoda instalace",
|
"useShizuku": "K instalaci použijte Shizuku nebo Sui",
|
||||||
"normal": "Normální",
|
|
||||||
"root": "Správce",
|
|
||||||
"shizukuBinderNotFound": "Shizuku neběží",
|
"shizukuBinderNotFound": "Shizuku neběží",
|
||||||
|
"shizukuOld": "Stará verze Shizuku (<11) - aktualizujte ji",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku běží na Androidu < 8.1 s ADB - aktualizujte Android nebo místo toho použijte Sui",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Nastavení Google Play jako zdroje instalace (pokud se používá Shizuku)",
|
||||||
"useSystemFont": "Použít systémové písmo",
|
"useSystemFont": "Použít systémové písmo",
|
||||||
"systemFontError": "Chyba při načítání systémového písma: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Použít kód verze aplikace jako verzi zjištěnou OS",
|
"useVersionCodeAsOSVersion": "Použít kód verze aplikace jako verzi zjištěnou OS",
|
||||||
"requestHeader": "Hlavička požadavku",
|
"requestHeader": "Hlavička požadavku",
|
||||||
"useLatestAssetDateAsReleaseDate": "Použít poslední nahrané dílo jako datum vydání",
|
"useLatestAssetDateAsReleaseDate": "Použít poslední nahrané dílo jako datum vydání",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} a 1 další aplikace mají aktualizace.",
|
"one": "{} a 1 další aplikace mají aktualizace.",
|
||||||
"other": "{} a {} další aplikace byly aktualizovány."
|
"other": "{} a {} další aplikace byly aktualizovány."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Nepodařilo se aktualizovat {} a 1 další aplikaci.",
|
||||||
|
"other": "Nepodařilo se aktualizovat {} a {} další aplikace."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} a 1 další aplikace možno aktualizovat",
|
"one": "{} a 1 další aplikace možno aktualizovat",
|
||||||
"other": "{} a {} další aplikace mohou být aktualizovány."
|
"other": "{} a {} další aplikace mohou být aktualizovány."
|
||||||
|
@@ -19,9 +19,12 @@
|
|||||||
"noDescription": "Keine Beschreibung",
|
"noDescription": "Keine Beschreibung",
|
||||||
"cancel": "Abbrechen",
|
"cancel": "Abbrechen",
|
||||||
"continue": "Weiter",
|
"continue": "Weiter",
|
||||||
"requiredInBrackets": "(Benötigt)",
|
"requiredInBrackets": "(wird benötigt)",
|
||||||
"dropdownNoOptsError": "FEHLER: DROPDOWN MUSS MINDESTENS EINE OPTION HABEN",
|
"dropdownNoOptsError": "FEHLER: DROPDOWN MUSS MINDESTENS EINE OPTION HABEN",
|
||||||
"colour": "Farbe",
|
"colour": "Farbe",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Benutzerdefiniert",
|
||||||
|
"useMaterialYou": "Verwende Material You",
|
||||||
"githubStarredRepos": "GitHub Starred Repos",
|
"githubStarredRepos": "GitHub Starred Repos",
|
||||||
"uname": "Benutzername",
|
"uname": "Benutzername",
|
||||||
"wrongArgNum": "Falsche Anzahl von Argumenten (Parametern) übermittelt",
|
"wrongArgNum": "Falsche Anzahl von Argumenten (Parametern) übermittelt",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Keine neuen Aktualisierungen.",
|
"noNewUpdates": "Keine neuen Aktualisierungen.",
|
||||||
"xHasAnUpdate": "{} hat eine Aktualisierung.",
|
"xHasAnUpdate": "{} hat eine Aktualisierung.",
|
||||||
"appsUpdated": "Apps aktualisiert",
|
"appsUpdated": "Apps aktualisiert",
|
||||||
|
"appsNotUpdated": "Aktualisierung der Anwendungen fehlgeschlagen",
|
||||||
"appsUpdatedNotifDescription": "Benachrichtigt den Benutzer, dass Aktualisierungen für eine oder mehrere Apps im Hintergrund durchgeführt wurden",
|
"appsUpdatedNotifDescription": "Benachrichtigt den Benutzer, dass Aktualisierungen für eine oder mehrere Apps im Hintergrund durchgeführt wurden",
|
||||||
"xWasUpdatedToY": "{} wurde auf {} aktualisiert.",
|
"xWasUpdatedToY": "{} wurde auf {} aktualisiert.",
|
||||||
|
"xWasNotUpdatedToY": "Die Aktualisierung von {} auf {} ist fehlgeschlagen.",
|
||||||
"errorCheckingUpdates": "Fehler beim Prüfen auf Aktualisierungen",
|
"errorCheckingUpdates": "Fehler beim Prüfen auf Aktualisierungen",
|
||||||
"errorCheckingUpdatesNotifDescription": "Eine Benachrichtigung, die angezeigt wird, wenn die Prüfung der Hintergrundaktualisierung fehlschlägt",
|
"errorCheckingUpdatesNotifDescription": "Eine Benachrichtigung, die angezeigt wird, wenn die Prüfung der Hintergrundaktualisierung fehlschlägt",
|
||||||
"appsRemoved": "Apps entfernt",
|
"appsRemoved": "Apps entfernt",
|
||||||
@@ -183,9 +188,9 @@
|
|||||||
"disableVersionDetection": "Versionsermittlung deaktivieren",
|
"disableVersionDetection": "Versionsermittlung deaktivieren",
|
||||||
"noVersionDetectionExplanation": "Diese Option sollte nur für Apps verwendet werden, bei denen die Versionserkennung nicht korrekt funktioniert.",
|
"noVersionDetectionExplanation": "Diese Option sollte nur für Apps verwendet werden, bei denen die Versionserkennung nicht korrekt funktioniert.",
|
||||||
"downloadingX": "Lade {} herunter",
|
"downloadingX": "Lade {} herunter",
|
||||||
"downloadX": "Herunterladen {}",
|
"downloadX": "{} herunterladen",
|
||||||
"downloadedX": "Heruntergeladen {}",
|
"downloadedX": "{} heruntergeladen",
|
||||||
"releaseAsset": "Asset freigeben",
|
"releaseAsset": "release Asset",
|
||||||
"downloadNotifDescription": "Benachrichtigt den Nutzer über den Fortschritt beim Herunterladen einer App",
|
"downloadNotifDescription": "Benachrichtigt den Nutzer über den Fortschritt beim Herunterladen einer App",
|
||||||
"noAPKFound": "Keine APK gefunden",
|
"noAPKFound": "Keine APK gefunden",
|
||||||
"noVersionDetection": "Keine Versionserkennung",
|
"noVersionDetection": "Keine Versionserkennung",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"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",
|
"useShizuku": "Verwenden Sie Shizuku oder Sui zur Installation",
|
||||||
"normal": "Normal",
|
|
||||||
"root": "Root",
|
|
||||||
"shizukuBinderNotFound": "Kompatibler Shizukudienst wurde nicht gefunden",
|
"shizukuBinderNotFound": "Kompatibler Shizukudienst wurde nicht gefunden",
|
||||||
|
"shizukuOld": "Alte Shizuku-Version (<11) - aktualisieren Sie sie",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku läuft auf Android < 8.1 mit ADB - aktualisieren Sie Android oder verwenden Sie stattdessen Sui",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Google Play als Installationsquelle festlegen (wenn Shizuku verwendet wird)",
|
||||||
"useSystemFont": "Verwende die Systemschriftart",
|
"useSystemFont": "Verwende die Systemschriftart",
|
||||||
"systemFontError": "Fehler beim Laden der Systemschriftart: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Verwende die Appversion als erkannte Version vom Betriebssystem",
|
"useVersionCodeAsOSVersion": "Verwende die Appversion als erkannte Version vom Betriebssystem",
|
||||||
"requestHeader": "Request Header",
|
"requestHeader": "Request Header",
|
||||||
"useLatestAssetDateAsReleaseDate": "Den letzten Asset-Upload als Veröffentlichungsdatum verwenden",
|
"useLatestAssetDateAsReleaseDate": "Den letzten Asset-Upload als Veröffentlichungsdatum verwenden",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} und 1 weitere Anwendung wurden aktualisiert.",
|
"one": "{} und 1 weitere Anwendung wurden aktualisiert.",
|
||||||
"other": "{} und {} weitere Anwendungen wurden aktualisiert."
|
"other": "{} und {} weitere Anwendungen wurden aktualisiert."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Aktualisierung fehlgeschlagen {} und 1 weitere Anwendung.",
|
||||||
|
"other": "Die Aktualisierung von {} und {} weiteren Anwendungen ist fehlgeschlagen."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} und 1 weitere Anwendung wurden möglicherweise aktualisiert.",
|
"one": "{} und 1 weitere Anwendung wurden möglicherweise aktualisiert.",
|
||||||
"other": "{} und {} weitere Anwendungen wurden möglicherweise aktualisiert."
|
"other": "{} und {} weitere Anwendungen wurden möglicherweise aktualisiert."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Required)",
|
"requiredInBrackets": "(Required)",
|
||||||
"dropdownNoOptsError": "ERROR: DROPDOWN MUST HAVE AT LEAST ONE OPT",
|
"dropdownNoOptsError": "ERROR: DROPDOWN MUST HAVE AT LEAST ONE OPT",
|
||||||
"colour": "Colour",
|
"colour": "Colour",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Custom",
|
||||||
|
"useMaterialYou": "Use Material You",
|
||||||
"githubStarredRepos": "GitHub Starred Repos",
|
"githubStarredRepos": "GitHub Starred Repos",
|
||||||
"uname": "Username",
|
"uname": "Username",
|
||||||
"wrongArgNum": "Wrong number of arguments provided",
|
"wrongArgNum": "Wrong number of arguments provided",
|
||||||
@@ -110,6 +113,7 @@
|
|||||||
"dark": "Dark",
|
"dark": "Dark",
|
||||||
"light": "Light",
|
"light": "Light",
|
||||||
"followSystem": "Follow System",
|
"followSystem": "Follow System",
|
||||||
|
"followSystemThemeExplanation": "Following system theme is possible only by using third-party applications",
|
||||||
"useBlackTheme": "Use pure black dark theme",
|
"useBlackTheme": "Use pure black dark theme",
|
||||||
"appSortBy": "App Sort By",
|
"appSortBy": "App Sort By",
|
||||||
"authorName": "Author/Name",
|
"authorName": "Author/Name",
|
||||||
@@ -143,8 +147,10 @@
|
|||||||
"noNewUpdates": "No new updates.",
|
"noNewUpdates": "No new updates.",
|
||||||
"xHasAnUpdate": "{} has an update.",
|
"xHasAnUpdate": "{} has an update.",
|
||||||
"appsUpdated": "Apps Updated",
|
"appsUpdated": "Apps Updated",
|
||||||
|
"appsNotUpdated": "Failed to update applications",
|
||||||
"appsUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were applied in the background",
|
"appsUpdatedNotifDescription": "Notifies the user that updates to one or more Apps were applied in the background",
|
||||||
"xWasUpdatedToY": "{} was updated to {}.",
|
"xWasUpdatedToY": "{} was updated to {}.",
|
||||||
|
"xWasNotUpdatedToY": "Failed to update {} to {}.",
|
||||||
"errorCheckingUpdates": "Error Checking for Updates",
|
"errorCheckingUpdates": "Error Checking for Updates",
|
||||||
"errorCheckingUpdatesNotifDescription": "A notification that shows when background update checking fails",
|
"errorCheckingUpdatesNotifDescription": "A notification that shows when background update checking fails",
|
||||||
"appsRemoved": "Apps Removed",
|
"appsRemoved": "Apps Removed",
|
||||||
@@ -253,7 +259,7 @@
|
|||||||
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
|
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
|
||||||
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
|
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
|
||||||
"versionExtractionRegEx": "Version String Extraction RegEx",
|
"versionExtractionRegEx": "Version String Extraction RegEx",
|
||||||
"matchGroupToUse": "Match Group to Use for Version String Extraction Regex",
|
"matchGroupToUse": "Match Group to Use for Version String Extraction RegEx",
|
||||||
"highlightTouchTargets": "Highlight less obvious touch targets",
|
"highlightTouchTargets": "Highlight less obvious touch targets",
|
||||||
"pickExportDir": "Pick Export Directory",
|
"pickExportDir": "Pick Export Directory",
|
||||||
"autoExportOnChanges": "Auto-export on changes",
|
"autoExportOnChanges": "Auto-export on changes",
|
||||||
@@ -282,12 +288,12 @@
|
|||||||
"supportFixedAPKURL": "Support fixed APK URLs",
|
"supportFixedAPKURL": "Support fixed APK URLs",
|
||||||
"selectX": "Select {}",
|
"selectX": "Select {}",
|
||||||
"parallelDownloads": "Allow parallel downloads",
|
"parallelDownloads": "Allow parallel downloads",
|
||||||
"installMethod": "Installation method",
|
"useShizuku": "Use Shizuku or Sui to install",
|
||||||
"normal": "Normal",
|
"shizukuBinderNotFound": "Shizuku service not running",
|
||||||
"root": "Root",
|
"shizukuOld": "Old Shizuku version (<11) - update it",
|
||||||
"shizukuBinderNotFound": "Сompatible Shizuku service wasn't found",
|
"shizukuOldAndroidWithADB": "Shizuku running on Android < 8.1 with ADB - update Android or use Sui instead",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Set Google Play as the installation source (if Shizuku is used)",
|
||||||
"useSystemFont": "Use the system font",
|
"useSystemFont": "Use the system font",
|
||||||
"systemFontError": "Error loading the system font: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
@@ -352,6 +358,10 @@
|
|||||||
"one": "{} and 1 more app was updated.",
|
"one": "{} and 1 more app was updated.",
|
||||||
"other": "{} and {} more apps were updated."
|
"other": "{} and {} more apps were updated."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Failed to update {} and 1 more app.",
|
||||||
|
"other": "Failed to update {} and {} more apps."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"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."
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"invalidURLForSource": "El URL de la aplicación {} no es válido",
|
"invalidURLForSource": "El URL de la aplicación {} no es válido",
|
||||||
"noReleaseFound": "No se ha podido encontrar una versión válida",
|
"noReleaseFound": "No se ha encontrado una versión válida",
|
||||||
"noVersionFound": "No se ha podido determinar la versión",
|
"noVersionFound": "No se ha podido determinar la versión",
|
||||||
"urlMatchesNoSource": "El URL no coincide con ninguna fuente conocida",
|
"urlMatchesNoSource": "El URL no coincide con ninguna fuente conocida",
|
||||||
"cantInstallOlderVersion": "No se puede instalar una versión previa de la aplicación",
|
"cantInstallOlderVersion": "No se puede instalar una versión previa de la aplicación",
|
||||||
"appIdMismatch": "El id. del paquete descargado no coincide con la ID de la aplicación instalada",
|
"appIdMismatch": "El ID del paquete descargado no coincide con el ID de la aplicación instalada",
|
||||||
"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",
|
||||||
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Requerido)",
|
"requiredInBrackets": "(Requerido)",
|
||||||
"dropdownNoOptsError": "ERROR: EL DESPLEGABLE DEBE TENER AL MENOS UNA OPCIÓN",
|
"dropdownNoOptsError": "ERROR: EL DESPLEGABLE DEBE TENER AL MENOS UNA OPCIÓN",
|
||||||
"colour": "Color",
|
"colour": "Color",
|
||||||
|
"standard": "Estándar",
|
||||||
|
"custom": "A medida",
|
||||||
|
"useMaterialYou": "Utilice el material que",
|
||||||
"githubStarredRepos": "Repositorios favoritos en GitHub",
|
"githubStarredRepos": "Repositorios favoritos en 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",
|
||||||
@@ -49,7 +52,7 @@
|
|||||||
"noAppsForFilter": "Sin aplicaciones para filtrar",
|
"noAppsForFilter": "Sin aplicaciones para filtrar",
|
||||||
"byX": "por: {}",
|
"byX": "por: {}",
|
||||||
"percentProgress": "Progreso: {} %",
|
"percentProgress": "Progreso: {} %",
|
||||||
"pleaseWait": "Espere un momento",
|
"pleaseWait": "Espere...",
|
||||||
"updateAvailable": "Actualización disponible",
|
"updateAvailable": "Actualización disponible",
|
||||||
"notInstalled": "No instalado",
|
"notInstalled": "No instalado",
|
||||||
"pseudoVersion": "pseudoversión",
|
"pseudoVersion": "pseudoversión",
|
||||||
@@ -97,7 +100,7 @@
|
|||||||
"appURLList": "Lista de URL de aplicaciones",
|
"appURLList": "Lista de URL de aplicaciones",
|
||||||
"line": "Línea",
|
"line": "Línea",
|
||||||
"searchX": "Buscar {}",
|
"searchX": "Buscar {}",
|
||||||
"noResults": "No se encontró ningún resultado",
|
"noResults": "No se ha encontrado ningún resultado",
|
||||||
"importX": "Importar desde {}",
|
"importX": "Importar desde {}",
|
||||||
"importedAppsIdDisclaimer": "Las aplicaciones importadas podrían mostrarse incorrectamente como «No instalada».\nPara solucionarlo, reinstálelas a través de Obtainium.\nEsto no debería afectar a los datos de las aplicaciones.\n\nSolo afecta a los URL y a los métodos de importación mediante terceros.",
|
"importedAppsIdDisclaimer": "Las aplicaciones importadas podrían mostrarse incorrectamente como «No instalada».\nPara solucionarlo, reinstálelas a través de Obtainium.\nEsto no debería afectar a los datos de las aplicaciones.\n\nSolo afecta a los URL y a los métodos de importación mediante terceros.",
|
||||||
"importErrors": "Errores de Importación",
|
"importErrors": "Errores de Importación",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "No hay nuevas actualizaciones.",
|
"noNewUpdates": "No hay nuevas actualizaciones.",
|
||||||
"xHasAnUpdate": "{} tiene una actualización.",
|
"xHasAnUpdate": "{} tiene una actualización.",
|
||||||
"appsUpdated": "Aplicaciones actualizadas",
|
"appsUpdated": "Aplicaciones actualizadas",
|
||||||
|
"appsNotUpdated": "Error al actualizar las aplicaciones",
|
||||||
"appsUpdatedNotifDescription": "Notifica al usuario de que una o más aplicaciones han sido actualizadas en segundo plano",
|
"appsUpdatedNotifDescription": "Notifica al usuario de que una o más aplicaciones han sido actualizadas en segundo plano",
|
||||||
"xWasUpdatedToY": "{} ha sido actualizada a {}.",
|
"xWasUpdatedToY": "{} ha sido actualizada a {}.",
|
||||||
|
"xWasNotUpdatedToY": "Error al actualizar {} a {}.",
|
||||||
"errorCheckingUpdates": "Error al buscar actualizaciones",
|
"errorCheckingUpdates": "Error al buscar actualizaciones",
|
||||||
"errorCheckingUpdatesNotifDescription": "Una notificación que muestra cuándo la comprobación de actualizaciones en segundo plano falla",
|
"errorCheckingUpdatesNotifDescription": "Una notificación que muestra cuándo la comprobación de actualizaciones en segundo plano falla",
|
||||||
"appsRemoved": "Aplicaciones eliminadas",
|
"appsRemoved": "Aplicaciones eliminadas",
|
||||||
@@ -170,7 +175,7 @@
|
|||||||
"fdroid": "Repositorio oficial F-Droid",
|
"fdroid": "Repositorio oficial F-Droid",
|
||||||
"appIdOrName": "ID o Nombre de la Aplicación",
|
"appIdOrName": "ID o Nombre de la Aplicación",
|
||||||
"appId": "ID de la Aplicación",
|
"appId": "ID de la Aplicación",
|
||||||
"appWithIdOrNameNotFound": "No se han encontrado aplicaciones con esa ID o nombre",
|
"appWithIdOrNameNotFound": "No se han encontrado aplicaciones con ese ID o nombre",
|
||||||
"reposHaveMultipleApps": "Los repositorios pueden contener varias aplicaciones",
|
"reposHaveMultipleApps": "Los repositorios pueden contener varias aplicaciones",
|
||||||
"fdroidThirdPartyRepo": "Repositorio de tercera parte F-Droid",
|
"fdroidThirdPartyRepo": "Repositorio de tercera parte F-Droid",
|
||||||
"steamMobile": "Steam para móviles",
|
"steamMobile": "Steam para móviles",
|
||||||
@@ -187,7 +192,7 @@
|
|||||||
"downloadedX": "Descargado {}",
|
"downloadedX": "Descargado {}",
|
||||||
"releaseAsset": "Liberar activos",
|
"releaseAsset": "Liberar activos",
|
||||||
"downloadNotifDescription": "Notifica al usuario del progreso de descarga de una aplicación",
|
"downloadNotifDescription": "Notifica al usuario del progreso de descarga de una aplicación",
|
||||||
"noAPKFound": "No se encontró el paquete de instalación APK",
|
"noAPKFound": "No se ha encontrado el paquete de instalación APK",
|
||||||
"noVersionDetection": "Sin detección de versiones",
|
"noVersionDetection": "Sin detección de versiones",
|
||||||
"categorize": "Catogorizar",
|
"categorize": "Catogorizar",
|
||||||
"categories": "Categorías",
|
"categories": "Categorías",
|
||||||
@@ -199,7 +204,7 @@
|
|||||||
"addCategory": "Añadir categoría",
|
"addCategory": "Añadir categoría",
|
||||||
"label": "Nombre",
|
"label": "Nombre",
|
||||||
"language": "Idioma",
|
"language": "Idioma",
|
||||||
"copiedToClipboard": "Se copió en el portapapeles",
|
"copiedToClipboard": "Copiado en el portapapeles",
|
||||||
"storagePermissionDenied": "Permiso de almacenamiento rechazado",
|
"storagePermissionDenied": "Permiso de almacenamiento rechazado",
|
||||||
"selectedCategorizeWarning": "Esto reemplazará cualquier ajuste de categoría para las aplicaciones seleccionadas.",
|
"selectedCategorizeWarning": "Esto reemplazará cualquier ajuste de categoría para las aplicaciones seleccionadas.",
|
||||||
"filterAPKsByRegEx": "Filtrar por APK",
|
"filterAPKsByRegEx": "Filtrar por APK",
|
||||||
@@ -216,7 +221,7 @@
|
|||||||
"standardVersionDetection": "Por versión",
|
"standardVersionDetection": "Por versión",
|
||||||
"groupByCategory": "Agrupar por categoría",
|
"groupByCategory": "Agrupar por categoría",
|
||||||
"autoApkFilterByArch": "Filtrar APK por arquitectura del procesador (si es posible)",
|
"autoApkFilterByArch": "Filtrar APK por arquitectura del procesador (si es posible)",
|
||||||
"overrideSource": "Anular fuente",
|
"overrideSource": "Forzar desde la fuente",
|
||||||
"dontShowAgain": "No mostrar de nuevo",
|
"dontShowAgain": "No mostrar de nuevo",
|
||||||
"dontShowTrackOnlyWarnings": "No mostrar avisos sobre apps en 'solo seguimiento'",
|
"dontShowTrackOnlyWarnings": "No mostrar avisos sobre apps en 'solo seguimiento'",
|
||||||
"dontShowAPKOriginWarnings": "No mostrar avisos sobre las fuentes de las APKs",
|
"dontShowAPKOriginWarnings": "No mostrar avisos sobre las fuentes de las APKs",
|
||||||
@@ -225,7 +230,7 @@
|
|||||||
"about": "Acerca",
|
"about": "Acerca",
|
||||||
"requiresCredentialsInSettings": "{}: Esto requiere credenciales adicionales (en ajustes)",
|
"requiresCredentialsInSettings": "{}: Esto requiere credenciales adicionales (en ajustes)",
|
||||||
"checkOnStart": "Comprobar actualizaciones al inicio",
|
"checkOnStart": "Comprobar actualizaciones al inicio",
|
||||||
"tryInferAppIdFromCode": "Intentar deducir la ID de la app por el código fuente",
|
"tryInferAppIdFromCode": "Intentar deducir el 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 de versión superior del paquete APK",
|
"pickHighestVersionCode": "Auto selección de versión superior del paquete APK",
|
||||||
"checkUpdateOnDetailPage": "Comprobar actualizaciones al abrir detalles de la app",
|
"checkUpdateOnDetailPage": "Comprobar actualizaciones al abrir detalles de la app",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"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",
|
"useShizuku": "Utilice Shizuku o Sui para instalar",
|
||||||
"normal": "Normal",
|
|
||||||
"root": "Raíz",
|
|
||||||
"shizukuBinderNotFound": "Shizuku no funciona",
|
"shizukuBinderNotFound": "Shizuku no funciona",
|
||||||
"useSystemFont": "Usar la fuente de impresión del sistema",
|
"shizukuOld": "Versión antigua de Shizuku (<11) - actualícela",
|
||||||
"systemFontError": "Error al cargar la fuente de impresión del sistema: {}",
|
"shizukuOldAndroidWithADB": "Shizuku corriendo en Android < 8.1 con ADB - actualiza Android o usa Sui en su lugar",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Establecer Google Play como fuente de instalación (si se utiliza Shizuku)",
|
||||||
|
"useSystemFont": "Usar fuente del sistema",
|
||||||
"useVersionCodeAsOSVersion": "Usar la versión de la aplicación como versión detectada por el sistema operativo",
|
"useVersionCodeAsOSVersion": "Usar la versión de la aplicación como versión detectada por el sistema operativo",
|
||||||
"requestHeader": "Encabezado de solicitud",
|
"requestHeader": "Encabezado de solicitud",
|
||||||
"useLatestAssetDateAsReleaseDate": "Usar la última carga de recursos como fecha de lanzamiento",
|
"useLatestAssetDateAsReleaseDate": "Usar la última carga de recursos como fecha de lanzamiento",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} y 1 aplicación más se han actualizado.",
|
"one": "{} y 1 aplicación más se han actualizado.",
|
||||||
"other": "{} y {} aplicaciones más se han actualizado."
|
"other": "{} y {} aplicaciones más se han actualizado."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Error al actualizar {} y 1 aplicación más.",
|
||||||
|
"other": "No se han podido actualizar {} y {} aplicaciones más."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} y 1 aplicación más podría haber sido actualizada.",
|
"one": "{} y 1 aplicación más podría haber sido actualizada.",
|
||||||
"other": "{} y {} aplicaciones más podrían haber sido actualizadas."
|
"other": "{} y {} aplicaciones más podrían haber sido actualizadas."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(ضروری)",
|
"requiredInBrackets": "(ضروری)",
|
||||||
"dropdownNoOptsError": "خطا: کشویی باید حداقل یک گزینه داشته باشد",
|
"dropdownNoOptsError": "خطا: کشویی باید حداقل یک گزینه داشته باشد",
|
||||||
"colour": "رنگ",
|
"colour": "رنگ",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Custom",
|
||||||
|
"useMaterialYou": "Use Material You",
|
||||||
"githubStarredRepos": "مخازن ستاره دار گیتهاب",
|
"githubStarredRepos": "مخازن ستاره دار گیتهاب",
|
||||||
"uname": "نام کاربری",
|
"uname": "نام کاربری",
|
||||||
"wrongArgNum": "تعداد آرگومان های ارائه شده اشتباه است",
|
"wrongArgNum": "تعداد آرگومان های ارائه شده اشتباه است",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "به روز رسانی جدیدی وجود ندارد.",
|
"noNewUpdates": "به روز رسانی جدیدی وجود ندارد.",
|
||||||
"xHasAnUpdate": "{} یک به روز رسانی دارد.",
|
"xHasAnUpdate": "{} یک به روز رسانی دارد.",
|
||||||
"appsUpdated": "برنامه ها به روز شدند",
|
"appsUpdated": "برنامه ها به روز شدند",
|
||||||
|
"appsNotUpdated": "Failed to update applications",
|
||||||
"appsUpdatedNotifDescription": "به کاربر اطلاع می دهد که به روز رسانی یک یا چند برنامه در پس زمینه اعمال شده است",
|
"appsUpdatedNotifDescription": "به کاربر اطلاع می دهد که به روز رسانی یک یا چند برنامه در پس زمینه اعمال شده است",
|
||||||
"xWasUpdatedToY": "{} به {} به روز شد.",
|
"xWasUpdatedToY": "{} به {} به روز شد.",
|
||||||
|
"xWasNotUpdatedToY": "Failed to update {} to {}.",
|
||||||
"errorCheckingUpdates": "خطا در بررسی بهروزرسانیها",
|
"errorCheckingUpdates": "خطا در بررسی بهروزرسانیها",
|
||||||
"errorCheckingUpdatesNotifDescription": "اعلانی که وقتی بررسی بهروزرسانی پسزمینه ناموفق است نشان میدهد",
|
"errorCheckingUpdatesNotifDescription": "اعلانی که وقتی بررسی بهروزرسانی پسزمینه ناموفق است نشان میدهد",
|
||||||
"appsRemoved": "برنامه ها حذف شدند",
|
"appsRemoved": "برنامه ها حذف شدند",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "پشتیبانی از URL های APK ثابت",
|
"supportFixedAPKURL": "پشتیبانی از URL های APK ثابت",
|
||||||
"selectX": "انتخاب کنید {}",
|
"selectX": "انتخاب کنید {}",
|
||||||
"parallelDownloads": "اجازه دانلود موازی",
|
"parallelDownloads": "اجازه دانلود موازی",
|
||||||
"installMethod": "روش نصب",
|
"useShizuku": "Use Shizuku or Sui to install",
|
||||||
"normal": "طبیعی",
|
|
||||||
"root": "ریشه",
|
|
||||||
"shizukuBinderNotFound": "Shizuku در حال اجرا نیست",
|
"shizukuBinderNotFound": "Shizuku در حال اجرا نیست",
|
||||||
|
"shizukuOld": "Old Shizuku version (<11) - update it",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku running on Android < 8.1 with ADB - update Android or use Sui instead",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Set Google Play as the installation source (if Shizuku is used)",
|
||||||
"useSystemFont": "استفاده از فونت سیستم",
|
"useSystemFont": "استفاده از فونت سیستم",
|
||||||
"systemFontError": "خطا در بارگیری فونت سیستم: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "استفاده کد نسخه برنامه به جای نسخه شناسایی شده توسط سیستم عامل استفاده کنید",
|
"useVersionCodeAsOSVersion": "استفاده کد نسخه برنامه به جای نسخه شناسایی شده توسط سیستم عامل استفاده کنید",
|
||||||
"requestHeader": "درخواست سطر بالایی",
|
"requestHeader": "درخواست سطر بالایی",
|
||||||
"useLatestAssetDateAsReleaseDate": "استفاده از آخرین بارگذاری دارایی به عنوان تاریخ انتشار",
|
"useLatestAssetDateAsReleaseDate": "استفاده از آخرین بارگذاری دارایی به عنوان تاریخ انتشار",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} و 1 برنامه دیگر به روز شدند.",
|
"one": "{} و 1 برنامه دیگر به روز شدند.",
|
||||||
"other": "{} و {} برنامه دیگر به روز شدند."
|
"other": "{} و {} برنامه دیگر به روز شدند."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Failed to update {} and 1 more app.",
|
||||||
|
"other": "Failed to update {} and {} more apps."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} و 1 برنامه دیگر ممکن است به روز شده باشند.",
|
"one": "{} و 1 برنامه دیگر ممکن است به روز شده باشند.",
|
||||||
"other": "ممکن است {} و {} برنامه های دیگر به روز شده باشند."
|
"other": "ممکن است {} و {} برنامه های دیگر به روز شده باشند."
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"invalidURLForSource": "URL d'application {} invalide",
|
"invalidURLForSource": "URL d'application {} invalide",
|
||||||
"noReleaseFound": "Impossible de trouver une version appropriée",
|
"noReleaseFound": "Impossible de trouver une version adaptée",
|
||||||
"noVersionFound": "Impossible de déterminer la version de la version",
|
"noVersionFound": "Impossible de déterminer la variante de la version",
|
||||||
"urlMatchesNoSource": "L'URL ne correspond pas à une source connue",
|
"urlMatchesNoSource": "L'URL ne correspond pas à une source connue",
|
||||||
"cantInstallOlderVersion": "Impossible d'installer une ancienne version d'une application",
|
"cantInstallOlderVersion": "Impossible d'installer une ancienne version d'une application",
|
||||||
"appIdMismatch": "L'ID de paquet téléchargé ne correspond pas à l'ID de l'application existante",
|
"appIdMismatch": "L'ID de paquet téléchargé ne correspond pas à l'ID de l'application existante",
|
||||||
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Requis)",
|
"requiredInBrackets": "(Requis)",
|
||||||
"dropdownNoOptsError": "ERREUR : LE DÉROULEMENT DOIT AVOIR AU MOINS UNE OPT",
|
"dropdownNoOptsError": "ERREUR : LE DÉROULEMENT DOIT AVOIR AU MOINS UNE OPT",
|
||||||
"colour": "Couleur",
|
"colour": "Couleur",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Sur mesure",
|
||||||
|
"useMaterialYou": "Utiliser le matériel que vous",
|
||||||
"githubStarredRepos": "Dépôts étoilés GitHub",
|
"githubStarredRepos": "Dépôts étoilés GitHub",
|
||||||
"uname": "Nom d'utilisateur",
|
"uname": "Nom d'utilisateur",
|
||||||
"wrongArgNum": "Mauvais nombre d'arguments fournis",
|
"wrongArgNum": "Mauvais nombre d'arguments fournis",
|
||||||
@@ -43,7 +46,7 @@
|
|||||||
"additionalOptsFor": "Options supplémentaires pour {}",
|
"additionalOptsFor": "Options supplémentaires pour {}",
|
||||||
"supportedSources": "Sources prises en charge ",
|
"supportedSources": "Sources prises en charge ",
|
||||||
"trackOnlyInBrackets": "(Suivi uniquement)",
|
"trackOnlyInBrackets": "(Suivi uniquement)",
|
||||||
"searchableInBrackets": "(Recherchable)",
|
"searchableInBrackets": "(Intérrogeable)",
|
||||||
"appsString": "Applications",
|
"appsString": "Applications",
|
||||||
"noApps": "Aucune application",
|
"noApps": "Aucune application",
|
||||||
"noAppsForFilter": "Aucune application pour le filtre",
|
"noAppsForFilter": "Aucune application pour le filtre",
|
||||||
@@ -51,7 +54,7 @@
|
|||||||
"percentProgress": "Progrès: {}%",
|
"percentProgress": "Progrès: {}%",
|
||||||
"pleaseWait": "Veuillez patienter",
|
"pleaseWait": "Veuillez patienter",
|
||||||
"updateAvailable": "Mise à jour disponible",
|
"updateAvailable": "Mise à jour disponible",
|
||||||
"notInstalled": "Pas installé",
|
"notInstalled": "Non installé",
|
||||||
"pseudoVersion": "pseudo-version",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Tout sélectionner",
|
"selectAll": "Tout sélectionner",
|
||||||
"deselectX": "Déselectionner {}",
|
"deselectX": "Déselectionner {}",
|
||||||
@@ -60,22 +63,22 @@
|
|||||||
"removeSelectedApps": "Supprimer les applications sélectionnées",
|
"removeSelectedApps": "Supprimer les applications sélectionnées",
|
||||||
"updateX": "Mise à jour {}",
|
"updateX": "Mise à jour {}",
|
||||||
"installX": "Installer {}",
|
"installX": "Installer {}",
|
||||||
"markXTrackOnlyAsUpdated": "Marquer {}\n(Suivi uniquement)\nas mis à jour",
|
"markXTrackOnlyAsUpdated": "Marquer {}\n(Suivi uniquement)\n comme mis à jour",
|
||||||
"changeX": "Changer {}",
|
"changeX": "Changer {}",
|
||||||
"installUpdateApps": "Installer/Mettre à jour les applications",
|
"installUpdateApps": "Installer/Mettre à jour les applications",
|
||||||
"installUpdateSelectedApps": "Installer/Mettre à jour les applications sélectionnées",
|
"installUpdateSelectedApps": "Installer/Mettre à jour les applications sélectionnées",
|
||||||
"markXSelectedAppsAsUpdated": "Marquer {} les applications sélectionnées comme mises à jour ?",
|
"markXSelectedAppsAsUpdated": "Marquer {} les applications sélectionnées comme étant à jour ?",
|
||||||
"no": "Non",
|
"no": "Non",
|
||||||
"yes": "Oui",
|
"yes": "Oui",
|
||||||
"markSelectedAppsUpdated": "Marquer les applications sélectionnées comme mises à jour",
|
"markSelectedAppsUpdated": "Marquer les applications sélectionnées comme étant à jour",
|
||||||
"pinToTop": "Épingler en haut",
|
"pinToTop": "Épingler en haut",
|
||||||
"unpinFromTop": "Détacher du haut",
|
"unpinFromTop": "Désépingler du haut",
|
||||||
"resetInstallStatusForSelectedAppsQuestion": "Réinitialiser l'état d'installation des applications sélectionnées ?",
|
"resetInstallStatusForSelectedAppsQuestion": "Réinitialiser le statu d'installation des applications sélectionnées ?",
|
||||||
"installStatusOfXWillBeResetExplanation": "L'état d'installation de toutes les applications sélectionnées sera réinitialisé.\n\nCela peut aider lorsque la version de l'application affichée dans Obtainium est incorrecte en raison d'échecs de mises à jour ou d'autres problèmes.",
|
"installStatusOfXWillBeResetExplanation": "Le statu d'installation de toutes les applications sélectionnées sera réinitialisé.\n\nCela peut aider lorsque la version de l'application affichée dans Obtainium est incorrecte en raison d'échecs de mises à jour ou d'autres problèmes.",
|
||||||
"customLinkMessage": "Ces liens fonctionnent sur les appareils sur lesquels Obtenirium est installé",
|
"customLinkMessage": "Ces liens fonctionnent sur les appareils sur lesquels Obtainium est installé",
|
||||||
"shareAppConfigLinks": "Partager la configuration de l'application sous forme de lien HTML",
|
"shareAppConfigLinks": "Partager la configuration de l'application sous forme de lien HTML",
|
||||||
"shareSelectedAppURLs": "Partager les URL d'application sélectionnées",
|
"shareSelectedAppURLs": "Partager les URL d'application sélectionnées",
|
||||||
"resetInstallStatus": "Réinitialiser le statut d'installation",
|
"resetInstallStatus": "Réinitialiser le statu d'installation",
|
||||||
"more": "Plus",
|
"more": "Plus",
|
||||||
"removeOutdatedFilter": "Supprimer le filtre d'application obsolète",
|
"removeOutdatedFilter": "Supprimer le filtre d'application obsolète",
|
||||||
"showOutdatedOnly": "Afficher uniquement les applications obsolètes",
|
"showOutdatedOnly": "Afficher uniquement les applications obsolètes",
|
||||||
@@ -88,12 +91,12 @@
|
|||||||
"importExport": "Importer/Exporter",
|
"importExport": "Importer/Exporter",
|
||||||
"settings": "Paramètres",
|
"settings": "Paramètres",
|
||||||
"exportedTo": "Exporté vers {}",
|
"exportedTo": "Exporté vers {}",
|
||||||
"obtainiumExport": "Exportation d'Obtainium",
|
"obtainiumExport": "Exporter d'Obtainium",
|
||||||
"invalidInput": "Entrée invalide",
|
"invalidInput": "Entrée invalide",
|
||||||
"importedX": "Importé {}",
|
"importedX": "Importé {}",
|
||||||
"obtainiumImport": "Importation d'Obtainium",
|
"obtainiumImport": "Importer d'Obtainium",
|
||||||
"importFromURLList": "Importer à partir de la liste d'URL",
|
"importFromURLList": "Importer à partir de la liste d'URL",
|
||||||
"searchQuery": "Requête de recherche",
|
"searchQuery": "Requête",
|
||||||
"appURLList": "Liste d'URL d'application",
|
"appURLList": "Liste d'URL d'application",
|
||||||
"line": "Queue",
|
"line": "Queue",
|
||||||
"searchX": "Rechercher {}",
|
"searchX": "Rechercher {}",
|
||||||
@@ -110,14 +113,14 @@
|
|||||||
"dark": "Sombre",
|
"dark": "Sombre",
|
||||||
"light": "Clair",
|
"light": "Clair",
|
||||||
"followSystem": "Suivre le système",
|
"followSystem": "Suivre le système",
|
||||||
"useBlackTheme": "Utilisez le thème noir pur et sombre",
|
"useBlackTheme": "Utilisez le thème noir pur",
|
||||||
"appSortBy": "Applications triées par",
|
"appSortBy": "Applications triées par",
|
||||||
"authorName": "Auteur/Nom",
|
"authorName": "Auteur/Nom",
|
||||||
"nameAuthor": "Nom/Auteur",
|
"nameAuthor": "Nom/Auteur",
|
||||||
"asAdded": "Comme ajouté",
|
"asAdded": "Comme ajouté",
|
||||||
"appSortOrder": "Ordre de tri des applications",
|
"appSortOrder": "Ordre de tri des applications",
|
||||||
"ascending": "Ascendant",
|
"ascending": "Ascendant",
|
||||||
"descending": "Descendanr",
|
"descending": "Descendant",
|
||||||
"bgUpdateCheckInterval": "Intervalle de vérification des mises à jour en arrière-plan",
|
"bgUpdateCheckInterval": "Intervalle de vérification des mises à jour en arrière-plan",
|
||||||
"neverManualOnly": "Jamais - Manuel uniquement",
|
"neverManualOnly": "Jamais - Manuel uniquement",
|
||||||
"appearance": "Apparence",
|
"appearance": "Apparence",
|
||||||
@@ -131,20 +134,22 @@
|
|||||||
"close": "Fermer",
|
"close": "Fermer",
|
||||||
"share": "Partager",
|
"share": "Partager",
|
||||||
"appNotFound": "Application introuvable",
|
"appNotFound": "Application introuvable",
|
||||||
"obtainiumExportHyphenatedLowercase": "exportation d'obtainium",
|
"obtainiumExportHyphenatedLowercase": "exportation d'Obtainium",
|
||||||
"pickAnAPK": "Choisissez un APK",
|
"pickAnAPK": "Choisissez un APK",
|
||||||
"appHasMoreThanOnePackage": "{} a plus d'un paquet :",
|
"appHasMoreThanOnePackage": "{} a plus d'un paquet :",
|
||||||
"deviceSupportsXArch": "Votre appareil prend en charge l'architecture de processeur {}.",
|
"deviceSupportsXArch": "Votre appareil prend en charge l'architecture CPU {}.",
|
||||||
"deviceSupportsFollowingArchs": "Votre appareil prend en charge les architectures CPU suivantes :",
|
"deviceSupportsFollowingArchs": "Votre appareil prend en charge les architectures CPU suivantes :",
|
||||||
"warning": "Avertissement",
|
"warning": "Avertissement",
|
||||||
"sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais le paquet de version provient de '{}'. Continuer?",
|
"sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais la version du paquet provient de '{}'. Continuer?",
|
||||||
"updatesAvailable": "Mises à jour disponibles",
|
"updatesAvailable": "Mises à jour disponibles",
|
||||||
"updatesAvailableNotifDescription": "Avertit l'utilisateur que des mises à jour sont disponibles pour une ou plusieurs applications suivies par Obtainium",
|
"updatesAvailableNotifDescription": "Avertit l'utilisateur que des mises à jour sont disponibles pour une ou plusieurs applications suivies par Obtainium",
|
||||||
"noNewUpdates": "Aucune nouvelle mise à jour.",
|
"noNewUpdates": "Aucune nouvelle mise à jour.",
|
||||||
"xHasAnUpdate": "{} a une mise à jour.",
|
"xHasAnUpdate": "{} a une mise à jour.",
|
||||||
"appsUpdated": "Applications mises à jour",
|
"appsUpdated": "Applications mises à jour",
|
||||||
|
"appsNotUpdated": "Échec de la mise à jour des applications",
|
||||||
"appsUpdatedNotifDescription": "Avertit l'utilisateur que les mises à jour d'une ou plusieurs applications ont été appliquées en arrière-plan",
|
"appsUpdatedNotifDescription": "Avertit l'utilisateur que les mises à jour d'une ou plusieurs applications ont été appliquées en arrière-plan",
|
||||||
"xWasUpdatedToY": "{} a été mis à jour pour {}.",
|
"xWasUpdatedToY": "{} a été mis à jour pour {}.",
|
||||||
|
"xWasNotUpdatedToY": "Échec de la mise à jour de {} vers {}.",
|
||||||
"errorCheckingUpdates": "Erreur lors de la vérification des mises à jour",
|
"errorCheckingUpdates": "Erreur lors de la vérification des mises à jour",
|
||||||
"errorCheckingUpdatesNotifDescription": "Une notification qui s'affiche lorsque la vérification de la mise à jour en arrière-plan échoue",
|
"errorCheckingUpdatesNotifDescription": "Une notification qui s'affiche lorsque la vérification de la mise à jour en arrière-plan échoue",
|
||||||
"appsRemoved": "Applications supprimées",
|
"appsRemoved": "Applications supprimées",
|
||||||
@@ -179,7 +184,7 @@
|
|||||||
"markInstalled": "Marquer installée",
|
"markInstalled": "Marquer installée",
|
||||||
"update": "Mettre à jour",
|
"update": "Mettre à jour",
|
||||||
"markUpdated": "Marquer à jour",
|
"markUpdated": "Marquer à jour",
|
||||||
"additionalOptions": "Options additionelles",
|
"additionalOptions": "Options additionnelles",
|
||||||
"disableVersionDetection": "Désactiver la détection de version",
|
"disableVersionDetection": "Désactiver la détection de version",
|
||||||
"noVersionDetectionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement.",
|
"noVersionDetectionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement.",
|
||||||
"downloadingX": "Téléchargement {}",
|
"downloadingX": "Téléchargement {}",
|
||||||
@@ -188,7 +193,7 @@
|
|||||||
"releaseAsset": "Actif libéré",
|
"releaseAsset": "Actif libéré",
|
||||||
"downloadNotifDescription": "Avertit l'utilisateur de la progression du téléchargement d'une application",
|
"downloadNotifDescription": "Avertit l'utilisateur de la progression du téléchargement d'une application",
|
||||||
"noAPKFound": "Aucun APK trouvé",
|
"noAPKFound": "Aucun APK trouvé",
|
||||||
"noVersionDetection": "Pas de détection de version",
|
"noVersionDetection": "Aucune de détection de version",
|
||||||
"categorize": "Catégoriser",
|
"categorize": "Catégoriser",
|
||||||
"categories": "Catégories",
|
"categories": "Catégories",
|
||||||
"category": "Catégorie",
|
"category": "Catégorie",
|
||||||
@@ -201,13 +206,13 @@
|
|||||||
"language": "Langue",
|
"language": "Langue",
|
||||||
"copiedToClipboard": "Copié dans le presse-papier",
|
"copiedToClipboard": "Copié dans le presse-papier",
|
||||||
"storagePermissionDenied": "Autorisation de stockage refusée",
|
"storagePermissionDenied": "Autorisation de stockage refusée",
|
||||||
"selectedCategorizeWarning": "Cela remplacera tous les paramètres de catégorie existants pour les applications sélectionnées.",
|
"selectedCategorizeWarning": "Cela remplacera toutes les catégorie définies pour les applications sélectionnées.",
|
||||||
"filterAPKsByRegEx": "Filtrer les APK par expression régulière",
|
"filterAPKsByRegEx": "Filtrer les APK par expression régulière",
|
||||||
"removeFromObtainium": "Supprimer d'Obtainium",
|
"removeFromObtainium": "Supprimer d'Obtainium",
|
||||||
"uninstallFromDevice": "Désinstaller de l'appareil",
|
"uninstallFromDevice": "Désinstaller de l'appareil",
|
||||||
"onlyWorksWithNonVersionDetectApps": "Fonctionne uniquement pour les applications avec la détection de version désactivée.",
|
"onlyWorksWithNonVersionDetectApps": "Fonctionne uniquement pour les applications avec la détection de version désactivée.",
|
||||||
"releaseDateAsVersion": "Utiliser la date de sortie comme version",
|
"releaseDateAsVersion": "Utiliser la date de sortie comme version",
|
||||||
"releaseDateAsVersionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement, mais une date de sortie est disponible.",
|
"releaseDateAsVersionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement, mais dont une date de sortie est disponible.",
|
||||||
"changes": "Changements",
|
"changes": "Changements",
|
||||||
"releaseDate": "Date de sortie",
|
"releaseDate": "Date de sortie",
|
||||||
"importFromURLsInFile": "Importer à partir d'URL dans un fichier (comme OPML)",
|
"importFromURLsInFile": "Importer à partir d'URL dans un fichier (comme OPML)",
|
||||||
@@ -215,59 +220,59 @@
|
|||||||
"versionDetection": "Détection des versions",
|
"versionDetection": "Détection des versions",
|
||||||
"standardVersionDetection": "Détection de version standard",
|
"standardVersionDetection": "Détection de version standard",
|
||||||
"groupByCategory": "Regrouper par catégorie",
|
"groupByCategory": "Regrouper par catégorie",
|
||||||
"autoApkFilterByArch": "Essayez de filtrer les APK par architecture CPU si possible",
|
"autoApkFilterByArch": "Si possible, essayez de filtrer les APK par architecture CPU",
|
||||||
"overrideSource": "Remplacer la source",
|
"overrideSource": "Remplacer la source",
|
||||||
"dontShowAgain": "Ne montre plus ça",
|
"dontShowAgain": "Ne plus montrer",
|
||||||
"dontShowTrackOnlyWarnings": "Don't Show the 'Track-Only' Warning",
|
"dontShowTrackOnlyWarnings": "Ne pas afficher l'avertissement 'Track-Only'",
|
||||||
"dontShowAPKOriginWarnings": "Ne pas afficher les avertissements sur l'origine de l'APK",
|
"dontShowAPKOriginWarnings": "Ne pas afficher les avertissements sur l'origine de l'APK",
|
||||||
"moveNonInstalledAppsToBottom": "Déplacer les applications non installées vers le bas de la vue Applications",
|
"moveNonInstalledAppsToBottom": "Déplacer les applications non installées vers le bas de la vue Applications",
|
||||||
"gitlabPATLabel": "Jeton d'accès personnel GitLab",
|
"gitlabPATLabel": "Jeton d'accès personnel GitLab",
|
||||||
"about": "À propos de",
|
"about": "À propos de",
|
||||||
"requiresCredentialsInSettings": "{}: This needs additional credentials (in Settings)",
|
"requiresCredentialsInSettings": "{}: Cela nécessite des identifiants supplémentaires (dans Paramètres)",
|
||||||
"checkOnStart": "Vérifier les mises à jour au démarrage",
|
"checkOnStart": "Vérifier les mises à jour au démarrage",
|
||||||
"tryInferAppIdFromCode": "Essayez de déduire l'ID de l'application à partir du code source",
|
"tryInferAppIdFromCode": "Essayez de déduire l'ID de l'application à partir du code source",
|
||||||
"removeOnExternalUninstall": "Supprimer automatiquement les applications désinstallées en externe",
|
"removeOnExternalUninstall": "Supprimer automatiquement les applications désinstallées en externe",
|
||||||
"pickHighestVersionCode": "Sélectionner automatiquement le code APK de la version la plus élevée",
|
"pickHighestVersionCode": "Sélectionner automatiquement le code de version de l'APK la plus élevée",
|
||||||
"checkUpdateOnDetailPage": "Vérifier les mises à jour lors de l'ouverture d'une page de détails d'application",
|
"checkUpdateOnDetailPage": "Vérifier les mises à jour lors de l'ouverture de la page détaillée d'une application",
|
||||||
"disablePageTransitions": "Désactiver les animations de transition de page",
|
"disablePageTransitions": "Désactiver les animations de transition de page",
|
||||||
"reversePageTransitions": "Animations de transition de page inversée",
|
"reversePageTransitions": "Inverser les animations de transition de page",
|
||||||
"minStarCount": "Nombre minimum d'étoiles",
|
"minStarCount": "Nombre minimum d'étoiles",
|
||||||
"addInfoBelow": "Ajoutez ces informations ci-dessous.",
|
"addInfoBelow": "Ajoutez ces informations ci-dessous.",
|
||||||
"addInfoInSettings": "Ajoutez ces informations dans les paramètres.",
|
"addInfoInSettings": "Ajoutez ces informations dans les paramètres.",
|
||||||
"githubSourceNote": "La limitation du débit GitHub peut être évitée à l'aide d'une clé API.",
|
"githubSourceNote": "La limite de débit GitHub peut être évitée à l'aide d'une clé API.",
|
||||||
"sortByLastLinkSegment": "Trier uniquement sur le dernier segment du lien",
|
"sortByLastLinkSegment": "Trier uniquement sur le dernier segment du lien",
|
||||||
"filterReleaseNotesByRegEx": "Filtrer les notes de version par expression régulière",
|
"filterReleaseNotesByRegEx": "Filtrer les notes de version par expression régulière",
|
||||||
"customLinkFilterRegex": "Filtre de lien APK personnalisé par expression régulière (par défaut '.apk$')",
|
"customLinkFilterRegex": "Filtre du lien APK personnalisé par expression régulière (par défaut '.apk$')",
|
||||||
"appsPossiblyUpdated": "Tentative de mise à jour de l'application",
|
"appsPossiblyUpdated": "Tentative de mise à jour de l'application",
|
||||||
"appsPossiblyUpdatedNotifDescription": "Avertit l'utilisateur que des mises à jour d'une ou plusieurs applications ont été potentiellement appliquées en arrière-plan",
|
"appsPossiblyUpdatedNotifDescription": "Avertit l'utilisateur que des mises à jour d'une ou plusieurs applications ont été potentiellement appliquées en arrière-plan",
|
||||||
"xWasPossiblyUpdatedToY": "{} a peut-être été mis à jour vers {}.",
|
"xWasPossiblyUpdatedToY": "{} a peut-être été mis à jour vers {}.",
|
||||||
"enableBackgroundUpdates": "Activer les mises à jour en arrière-plan",
|
"enableBackgroundUpdates": "Activer les mises à jour en arrière-plan",
|
||||||
"backgroundUpdateReqsExplanation": "Les mises à jour en arrière-plan peuvent ne pas être possibles pour toutes les applications.",
|
"backgroundUpdateReqsExplanation": "Les mises à jour en arrière-plan peuvent ne pas être possibles pour toutes les applications.",
|
||||||
"backgroundUpdateLimitsExplanation": "Le succès d'une installation en arrière-plan ne peut être déterminé qu'à l'ouverture d'Obetium.",
|
"backgroundUpdateLimitsExplanation": "Le succès d'une installation en arrière-plan ne peut être déterminé qu'à l'ouverture d'Obtainium.",
|
||||||
"verifyLatestTag": "Vérifiez la balise 'dernière'",
|
"verifyLatestTag": "Vérifiez la balise 'Latest'",
|
||||||
"intermediateLinkRegex": " Filtrer un lien \" intermédiaire \" à visiter ",
|
"intermediateLinkRegex": " Filtrer un lien \" intermédiaire \" à visiter ",
|
||||||
"filterByLinkText": "Filtrer les liens par texte de lien",
|
"filterByLinkText": "Filtrer les liens par le texte du lien",
|
||||||
"intermediateLinkNotFound": "Lien intermédiaire introuvable",
|
"intermediateLinkNotFound": "Lien intermédiaire introuvable",
|
||||||
"intermediateLink": "Lien intermédiaire",
|
"intermediateLink": "Lien intermédiaire",
|
||||||
"exemptFromBackgroundUpdates": "Exempt des mises à jour en arrière-plan (si activé)",
|
"exemptFromBackgroundUpdates": "Exempté des mises à jour en arrière-plan (si activé)",
|
||||||
"bgUpdatesOnWiFiOnly": "Désactiver les mises à jour en arrière-plan lorsque vous n'êtes pas connecté au WiFi",
|
"bgUpdatesOnWiFiOnly": "Désactiver les mises à jour en arrière-plan lorsque vous n'êtes pas connecté au WiFi",
|
||||||
"autoSelectHighestVersionCode": "Sélection automatique de la version la plus élevéeCode APK",
|
"autoSelectHighestVersionCode": "Sélection automatique du code de version de l'APK la plus élevée",
|
||||||
"versionExtractionRegEx": "Version Extraction RegEx",
|
"versionExtractionRegEx": "Expression régulière d'extraction de version",
|
||||||
"matchGroupToUse": "Match Group to Use",
|
"matchGroupToUse": "Groupe de correspondance pour l'expression régulière d'extraction de version",
|
||||||
"highlightTouchTargets": "Mettez en évidence les cibles tactiles moins évidentes",
|
"highlightTouchTargets": "Mettre en évidence les cibles tactiles moins évidentes",
|
||||||
"pickExportDir": "Choisir le répertoire d'exportation",
|
"pickExportDir": "Choisir le répertoire d'exportation",
|
||||||
"autoExportOnChanges": "Exportation automatique sur modifications",
|
"autoExportOnChanges": "Exporter automatiquement après modification",
|
||||||
"includeSettings": "Inclure les paramètres",
|
"includeSettings": "Inclure les paramètres",
|
||||||
"filterVersionsByRegEx": "Filtrer les versions par expression régulière",
|
"filterVersionsByRegEx": "Filtrer les versions par expression régulière",
|
||||||
"trySelectingSuggestedVersionCode": "Essayez de sélectionner la version suggéréeCode APK",
|
"trySelectingSuggestedVersionCode": "Essayez de sélectionner le code de la version APK suggérée",
|
||||||
"dontSortReleasesList": "Conserver la commande de version de l'API",
|
"dontSortReleasesList": "Conserver l'ordre des version de l'API",
|
||||||
"reverseSort": "Tri inversé",
|
"reverseSort": "Tri inversé",
|
||||||
"takeFirstLink": "Prendre le premier lien",
|
"takeFirstLink": "Prendre le premier lien",
|
||||||
"skipSort": "Sauter le tri",
|
"skipSort": "Sauter le tri",
|
||||||
"debugMenu": "Menu de débogage",
|
"debugMenu": "Menu de débogage",
|
||||||
"bgTaskStarted": "Tâche en arrière-plan démarrée - vérifier les journaux.",
|
"bgTaskStarted": "Tâche en arrière-plan démarrée - vérifier les journaux.",
|
||||||
"runBgCheckNow": "Exécuter la vérification de la mise à jour en arrière-plan maintenant",
|
"runBgCheckNow": "Exécuter maintenant la vérification de la mise à jour en arrière-plan",
|
||||||
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
|
"versionExtractWholePage": "Appliquer l'expression régulière d'extraction de version sur l'ensemble de la page",
|
||||||
"installing": "Installation",
|
"installing": "Installation",
|
||||||
"skipUpdateNotifications": "Ignorer les notifications de mise à jour",
|
"skipUpdateNotifications": "Ignorer les notifications de mise à jour",
|
||||||
"updatesAvailableNotifChannel": "Mises à jour disponibles",
|
"updatesAvailableNotifChannel": "Mises à jour disponibles",
|
||||||
@@ -278,19 +283,19 @@
|
|||||||
"downloadingXNotifChannel": "Téléchargement {}",
|
"downloadingXNotifChannel": "Téléchargement {}",
|
||||||
"completeAppInstallationNotifChannel": "Installation complète de l'application",
|
"completeAppInstallationNotifChannel": "Installation complète de l'application",
|
||||||
"checkingForUpdatesNotifChannel": "Vérification des mises à jour",
|
"checkingForUpdatesNotifChannel": "Vérification des mises à jour",
|
||||||
"onlyCheckInstalledOrTrackOnlyApps": "Vérifiez uniquement les mises à jour des applications installées et de suivi uniquement",
|
"onlyCheckInstalledOrTrackOnlyApps": "Vérifiez uniquement les mises à jour des applications installées et 'Track-Only'",
|
||||||
"supportFixedAPKURL": "Prise en charge des URL APK fixes",
|
"supportFixedAPKURL": "Prise en charge des URL APK fixes",
|
||||||
"selectX": "Sélectionner {}",
|
"selectX": "Sélectionner {}",
|
||||||
"parallelDownloads": "Autoriser les téléchargements parallèles",
|
"parallelDownloads": "Autoriser les téléchargements parallèles",
|
||||||
"installMethod": "Méthode d'installation",
|
"useShizuku": "Utiliser Shizuku ou Sui pour l'installation",
|
||||||
"normal": "Normale",
|
"shizukuBinderNotFound": "Service Shizuku compatible non trouvé",
|
||||||
"root": "Racine",
|
"shizukuOld": "Ancienne version de Shizuku (<11) - la mettre à jour",
|
||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuOldAndroidWithADB": "Shizuku fonctionne sur Android < 8.1 avec ADB - mettre à jour Android ou utiliser Sui à la place",
|
||||||
"useSystemFont": "Utiliser la police système",
|
"shizukuPretendToBeGooglePlay": "Définir Google Play comme source d'installation (si Shizuku est utilisé)",
|
||||||
"systemFontError": "Erreur de chargement de la police système : {}",
|
"useSystemFont": "Utiliser la police du système",
|
||||||
"useVersionCodeAsOSVersion": "Utiliser le code de version de l'application comme version détectée par le système d'exploitation",
|
"useVersionCodeAsOSVersion": "Utiliser le code de version de l'application comme version détectée par le système d'exploitation",
|
||||||
"requestHeader": "En-tête de demande",
|
"requestHeader": "En-tête de demande",
|
||||||
"useLatestAssetDateAsReleaseDate": "Utiliser le dernier téléchargement d'élément comme date de sortie",
|
"useLatestAssetDateAsReleaseDate": "Utiliser le dernier élément téléversé comme date de sortie",
|
||||||
"defaultPseudoVersioningMethod": "Méthode de pseudo-version par défaut",
|
"defaultPseudoVersioningMethod": "Méthode de pseudo-version par défaut",
|
||||||
"partialAPKHash": "Hash APK partiel",
|
"partialAPKHash": "Hash APK partiel",
|
||||||
"APKLinkHash": "Hash de lien APK",
|
"APKLinkHash": "Hash de lien APK",
|
||||||
@@ -313,12 +318,12 @@
|
|||||||
"other": "Trop de demandes (taux limité) - réessayez dans {} minutes"
|
"other": "Trop de demandes (taux limité) - réessayez dans {} minutes"
|
||||||
},
|
},
|
||||||
"bgUpdateGotErrorRetryInMinutes": {
|
"bgUpdateGotErrorRetryInMinutes": {
|
||||||
"one": "La vérification de la mise à jour en arrière-plan a rencontré un {}, planifiera une nouvelle tentative de vérification dans {} minute",
|
"one": "La vérification de la mise à jour en arrière-plan a rencontré un {}, une nouvelle tentative de vérification sera planifié dans {} minute",
|
||||||
"other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, planifiera une nouvelle tentative de vérification dans {} minutes"
|
"other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, une nouvelle tentative de vérification sera planifié dans {} minute"
|
||||||
},
|
},
|
||||||
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
|
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
|
||||||
"one": "La vérification des mises à jour en arrière-plan trouvée {} mise à jour - avertira l'utilisateur si nécessaire",
|
"one": "La vérification des mises à jour en arrière-plan a trouvée {} mise à jour - l'utilisateur sera notifié si nécessaire",
|
||||||
"other": "La vérification des mises à jour en arrière-plan a trouvé {} mises à jour - avertira l'utilisateur si nécessaire"
|
"other": "La vérification des mises à jour en arrière-plan a trouvé {} mises à jour - l'utilisateur sera notifié si nécessaire"
|
||||||
},
|
},
|
||||||
"apps": {
|
"apps": {
|
||||||
"one": "{} Application",
|
"one": "{} Application",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} et 1 autre application ont été mises à jour.",
|
"one": "{} et 1 autre application ont été mises à jour.",
|
||||||
"other": "{} et {} autres applications ont été mises à jour."
|
"other": "{} et {} autres applications ont été mises à jour."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Échec de la mise à jour de {} et d'une autre application.",
|
||||||
|
"other": "Échec de la mise à jour de {} et {} autres applications."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"une": "{} et 1 application supplémentaire ont peut-être été mises à jour.",
|
"une": "{} et 1 application supplémentaire ont peut-être été mises à jour.",
|
||||||
"other": "{} et {} autres applications peuvent avoir été mises à jour."
|
"other": "{} et {} autres applications peuvent avoir été mises à jour."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Kötelező)",
|
"requiredInBrackets": "(Kötelező)",
|
||||||
"dropdownNoOptsError": "HIBA: A LEDOBÁST LEGALÁBB EGY OPCIÓHOZ KELL RENDELNI",
|
"dropdownNoOptsError": "HIBA: A LEDOBÁST LEGALÁBB EGY OPCIÓHOZ KELL RENDELNI",
|
||||||
"colour": "Szín",
|
"colour": "Szín",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Custom",
|
||||||
|
"useMaterialYou": "Használja az Ön által használt anyagot",
|
||||||
"githubStarredRepos": "GitHub Csillagos Repo-k",
|
"githubStarredRepos": "GitHub Csillagos Repo-k",
|
||||||
"uname": "Felh.név",
|
"uname": "Felh.név",
|
||||||
"wrongArgNum": "Rossz számú argumentumot adott meg",
|
"wrongArgNum": "Rossz számú argumentumot adott meg",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Nincsenek új frissítések.",
|
"noNewUpdates": "Nincsenek új frissítések.",
|
||||||
"xHasAnUpdate": "A(z) {} frissítést kapott.",
|
"xHasAnUpdate": "A(z) {} frissítést kapott.",
|
||||||
"appsUpdated": "Alkalmazások frissítve",
|
"appsUpdated": "Alkalmazások frissítve",
|
||||||
|
"appsNotUpdated": "Nem sikerült frissíteni az alkalmazásokat",
|
||||||
"appsUpdatedNotifDescription": "Értesíti a felhasználót, hogy egy/több app frissítése megtörtént a háttérben",
|
"appsUpdatedNotifDescription": "Értesíti a felhasználót, hogy egy/több app frissítése megtörtént a háttérben",
|
||||||
"xWasUpdatedToY": "{} frissítve a következőre: {}.",
|
"xWasUpdatedToY": "{} frissítve a következőre: {}.",
|
||||||
|
"xWasNotUpdatedToY": "A {} frissítése a {}-ra nem sikerült.",
|
||||||
"errorCheckingUpdates": "Hiba a frissítések keresésekor",
|
"errorCheckingUpdates": "Hiba a frissítések keresésekor",
|
||||||
"errorCheckingUpdatesNotifDescription": "Értesítés, amely akkor jelenik meg, ha a háttérbeli frissítések ellenőrzése sikertelen",
|
"errorCheckingUpdatesNotifDescription": "Értesítés, amely akkor jelenik meg, ha a háttérbeli frissítések ellenőrzése sikertelen",
|
||||||
"appsRemoved": "Alkalmazások eltávolítva",
|
"appsRemoved": "Alkalmazások eltávolítva",
|
||||||
@@ -185,7 +190,7 @@
|
|||||||
"downloadingX": "{} letöltés",
|
"downloadingX": "{} letöltés",
|
||||||
"downloadX": "Letöltés {}",
|
"downloadX": "Letöltés {}",
|
||||||
"downloadedX": "Letöltés {}",
|
"downloadedX": "Letöltés {}",
|
||||||
"releaseAsset": "Release Asset",
|
"releaseAsset": "Kiadási tartalom",
|
||||||
"downloadNotifDescription": "Értesíti a felhasználót az app letöltésének előrehaladásáról",
|
"downloadNotifDescription": "Értesíti a felhasználót az app letöltésének előrehaladásáról",
|
||||||
"noAPKFound": "Nem található APK",
|
"noAPKFound": "Nem található APK",
|
||||||
"noVersionDetection": "Nincs verzió érzékelés",
|
"noVersionDetection": "Nincs verzió érzékelés",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"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": "Párhuzamos letöltéseket enged",
|
"parallelDownloads": "Párhuzamos letöltéseket enged",
|
||||||
"installMethod": "Telepítési mód",
|
"useShizuku": "Használja Shizuku vagy Sui telepítéséhez",
|
||||||
"normal": "Normál",
|
|
||||||
"root": "Root",
|
|
||||||
"shizukuBinderNotFound": "A Shizuku nem fut",
|
"shizukuBinderNotFound": "A Shizuku nem fut",
|
||||||
|
"shizukuOld": "Régi Shizuku verzió (<11) - frissítsd!",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku fut Android < 8.1 ADB-vel - frissítse az Androidot vagy használja a Sui-t helyette",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Állítsa be a Google Play-t telepítési forrásként (ha Shizuku-t használ)",
|
||||||
"useSystemFont": "Használja a rendszer betűtípusát",
|
"useSystemFont": "Használja a rendszer betűtípusát",
|
||||||
"systemFontError": "Hiba a rendszer betűtípusának betöltésekor: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Az app verziókód használata a rendszer által észlelt verzióként",
|
"useVersionCodeAsOSVersion": "Az app verziókód használata a rendszer által észlelt verzióként",
|
||||||
"requestHeader": "Kérelem fejléc",
|
"requestHeader": "Kérelem fejléc",
|
||||||
"useLatestAssetDateAsReleaseDate": "Használja a legújabb tartalomfeltöltést megjelenési dátumként",
|
"useLatestAssetDateAsReleaseDate": "Használja a legújabb tartalomfeltöltést megjelenési dátumként",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "A(z) {} és 1 további alkalmazás frissítve.",
|
"one": "A(z) {} és 1 további alkalmazás frissítve.",
|
||||||
"other": "{} és {} további alkalmazás frissítve."
|
"other": "{} és {} további alkalmazás frissítve."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Nem sikerült frissíteni {} és még 1 alkalmazást.",
|
||||||
|
"other": "Nem sikerült frissíteni {} és {} további alkalmazásokat."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} és 1 további alkalmazás is frissült.",
|
"one": "{} és 1 további alkalmazás is frissült.",
|
||||||
"other": "{} és {} további alkalmazás is frissült."
|
"other": "{} és {} további alkalmazás is frissült."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(richiesto)",
|
"requiredInBrackets": "(richiesto)",
|
||||||
"dropdownNoOptsError": "ERRORE: LA TENDINA DEVE AVERE ALMENO UN'OPZIONE",
|
"dropdownNoOptsError": "ERRORE: LA TENDINA DEVE AVERE ALMENO UN'OPZIONE",
|
||||||
"colour": "Colore",
|
"colour": "Colore",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Personalizzato",
|
||||||
|
"useMaterialYou": "Utilizzate il materiale che avete a disposizione",
|
||||||
"githubStarredRepos": "repository stellati da GitHub",
|
"githubStarredRepos": "repository stellati da GitHub",
|
||||||
"uname": "Nome utente",
|
"uname": "Nome utente",
|
||||||
"wrongArgNum": "Numero di argomenti forniti errato",
|
"wrongArgNum": "Numero di argomenti forniti errato",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Nessun nuovo aggiornamento.",
|
"noNewUpdates": "Nessun nuovo aggiornamento.",
|
||||||
"xHasAnUpdate": "Aggiornamento disponibile per {}",
|
"xHasAnUpdate": "Aggiornamento disponibile per {}",
|
||||||
"appsUpdated": "App aggiornate",
|
"appsUpdated": "App aggiornate",
|
||||||
|
"appsNotUpdated": "Impossibile aggiornare le applicazioni",
|
||||||
"appsUpdatedNotifDescription": "Notifica all'utente che una o più app sono state aggiornate in secondo piano",
|
"appsUpdatedNotifDescription": "Notifica all'utente che una o più app sono state aggiornate in secondo piano",
|
||||||
"xWasUpdatedToY": "{} è stato aggiornato alla {}.",
|
"xWasUpdatedToY": "{} è stato aggiornato alla {}.",
|
||||||
|
"xWasNotUpdatedToY": "Impossibile aggiornare {} a {}.",
|
||||||
"errorCheckingUpdates": "Controllo degli errori per gli aggiornamenti",
|
"errorCheckingUpdates": "Controllo degli errori per gli aggiornamenti",
|
||||||
"errorCheckingUpdatesNotifDescription": "Una notifica che mostra quando il controllo degli aggiornamenti in secondo piano fallisce",
|
"errorCheckingUpdatesNotifDescription": "Una notifica che mostra quando il controllo degli aggiornamenti in secondo piano fallisce",
|
||||||
"appsRemoved": "App rimosse",
|
"appsRemoved": "App rimosse",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Supporta URL fissi di APK",
|
"supportFixedAPKURL": "Supporta URL fissi di APK",
|
||||||
"selectX": "Seleziona {}",
|
"selectX": "Seleziona {}",
|
||||||
"parallelDownloads": "Permetti download paralleli",
|
"parallelDownloads": "Permetti download paralleli",
|
||||||
"installMethod": "Metodo d'installazione",
|
"useShizuku": "Utilizzare Shizuku o Sui per installare",
|
||||||
"normal": "Normale",
|
|
||||||
"root": "Root",
|
|
||||||
"shizukuBinderNotFound": "Shizuku non è in esecuzione",
|
"shizukuBinderNotFound": "Shizuku non è in esecuzione",
|
||||||
|
"shizukuOld": "Vecchia versione di Shizuku (<11) - aggiornarla",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku funziona su Android < 8.1 con ADB - aggiornare Android o utilizzare Sui al suo posto",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Impostare Google Play come fonte di installazione (se si usa Shizuku)",
|
||||||
"useSystemFont": "Usa i caratteri di sistema",
|
"useSystemFont": "Usa i caratteri di sistema",
|
||||||
"systemFontError": "Errore durante il caricamento dei caratteri di sistema: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Usa il codice versione dell'app come versione rilevata dal sistema operativo",
|
"useVersionCodeAsOSVersion": "Usa il codice versione dell'app come versione rilevata dal sistema operativo",
|
||||||
"requestHeader": "Intestazione della richiesta",
|
"requestHeader": "Intestazione della richiesta",
|
||||||
"useLatestAssetDateAsReleaseDate": "Usa l'ultimo caricamento della risorsa come data di rilascio",
|
"useLatestAssetDateAsReleaseDate": "Usa l'ultimo caricamento della risorsa come data di rilascio",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} e un'altra app sono state aggiornate.",
|
"one": "{} e un'altra app sono state aggiornate.",
|
||||||
"other": "{} e altre {} app sono state aggiornate."
|
"other": "{} e altre {} app sono state aggiornate."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Non è riuscito ad aggiornare {} e altre 1 app.",
|
||||||
|
"other": "Non è riuscito ad aggiornare {} e {} altre applicazioni."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} e un'altra app potrebbero essere state aggiornate.",
|
"one": "{} e un'altra app potrebbero essere state aggiornate.",
|
||||||
"other": "{} e altre {} app potrebbero essere state aggiornate."
|
"other": "{} e altre {} app potrebbero essere state aggiornate."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(必須)",
|
"requiredInBrackets": "(必須)",
|
||||||
"dropdownNoOptsError": "エラー: ドロップダウンには、少なくとも1つのオプションが必要です",
|
"dropdownNoOptsError": "エラー: ドロップダウンには、少なくとも1つのオプションが必要です",
|
||||||
"colour": "カラー",
|
"colour": "カラー",
|
||||||
|
"standard": "スタンダード",
|
||||||
|
"custom": "カスタム",
|
||||||
|
"useMaterialYou": "使用素材",
|
||||||
"githubStarredRepos": "Githubでスターしたリポジトリ",
|
"githubStarredRepos": "Githubでスターしたリポジトリ",
|
||||||
"uname": "ユーザー名",
|
"uname": "ユーザー名",
|
||||||
"wrongArgNum": "提供する引数の数が間違っています",
|
"wrongArgNum": "提供する引数の数が間違っています",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "新しいアップデートはありません",
|
"noNewUpdates": "新しいアップデートはありません",
|
||||||
"xHasAnUpdate": "{} のアップデートが利用可能です。",
|
"xHasAnUpdate": "{} のアップデートが利用可能です。",
|
||||||
"appsUpdated": "アプリをアップデートしました",
|
"appsUpdated": "アプリをアップデートしました",
|
||||||
|
"appsNotUpdated": "アプリケーションの更新に失敗",
|
||||||
"appsUpdatedNotifDescription": "1つまたは複数のAppのアップデートがバックグラウンドで適用されたことをユーザーに通知する",
|
"appsUpdatedNotifDescription": "1つまたは複数のAppのアップデートがバックグラウンドで適用されたことをユーザーに通知する",
|
||||||
"xWasUpdatedToY": "{} が {} にアップデートされました",
|
"xWasUpdatedToY": "{} が {} にアップデートされました",
|
||||||
|
"xWasNotUpdatedToY": "への更新に失敗しました。",
|
||||||
"errorCheckingUpdates": "アップデート確認中のエラー",
|
"errorCheckingUpdates": "アップデート確認中のエラー",
|
||||||
"errorCheckingUpdatesNotifDescription": "バックグラウンドでのアップデート確認に失敗した際に表示される通知",
|
"errorCheckingUpdatesNotifDescription": "バックグラウンドでのアップデート確認に失敗した際に表示される通知",
|
||||||
"appsRemoved": "削除されたアプリ",
|
"appsRemoved": "削除されたアプリ",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "固定されたAPKのURLをサポートする",
|
"supportFixedAPKURL": "固定されたAPKのURLをサポートする",
|
||||||
"selectX": "{} 選択",
|
"selectX": "{} 選択",
|
||||||
"parallelDownloads": "並行ダウンロードを許可する",
|
"parallelDownloads": "並行ダウンロードを許可する",
|
||||||
"installMethod": "インストール方法",
|
"useShizuku": "シズクまたはスイを使って設置する",
|
||||||
"normal": "通常",
|
|
||||||
"root": "Root",
|
|
||||||
"shizukuBinderNotFound": "Shizukuが起動していません",
|
"shizukuBinderNotFound": "Shizukuが起動していません",
|
||||||
|
"shizukuOld": "古い雫バージョン (<11) - アップデートしてください。",
|
||||||
|
"shizukuOldAndroidWithADB": "雫、Android < 8.1でADB動作 - Androidをアップデートするか、代わりにSuiを使うか",
|
||||||
|
"shizukuPretendToBeGooglePlay": "インストール元をGoogle Playに設定する(雫を使用する場合)",
|
||||||
"useSystemFont": "システムフォントを使用する",
|
"useSystemFont": "システムフォントを使用する",
|
||||||
"systemFontError": "システムフォントの読み込みエラー: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "アプリのバージョンコードをOSで検出されたバージョンとして使用する",
|
"useVersionCodeAsOSVersion": "アプリのバージョンコードをOSで検出されたバージョンとして使用する",
|
||||||
"requestHeader": "リクエストヘッダー",
|
"requestHeader": "リクエストヘッダー",
|
||||||
"useLatestAssetDateAsReleaseDate": "最新のアセットアップロードをリリース日として使用する",
|
"useLatestAssetDateAsReleaseDate": "最新のアセットアップロードをリリース日として使用する",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} とさらに {} 個のアプリがアップデートされました。",
|
"one": "{} とさらに {} 個のアプリがアップデートされました。",
|
||||||
"other": "{} とさらに {} 個のアプリがアップデートされました。"
|
"other": "{} とさらに {} 個のアプリがアップデートされました。"
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "更新に失敗しました。",
|
||||||
|
"other": "アプリのアップデートに失敗しました。"
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} とさらに 1 個のアプリがアップデートされた可能性があります。",
|
"one": "{} とさらに 1 個のアプリがアップデートされた可能性があります。",
|
||||||
"other": "{} とさらに {} 個のアプリがアップデートされた可能性があります。"
|
"other": "{} とさらに {} 個のアプリがアップデートされた可能性があります。"
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Verplicht)",
|
"requiredInBrackets": "(Verplicht)",
|
||||||
"dropdownNoOptsError": "FOUTMELDING: DROPDOWN MOET TENMINSTE ÉÉN OPT HEBBEN",
|
"dropdownNoOptsError": "FOUTMELDING: DROPDOWN MOET TENMINSTE ÉÉN OPT HEBBEN",
|
||||||
"colour": "Kleur",
|
"colour": "Kleur",
|
||||||
|
"standard": "Standaard",
|
||||||
|
"custom": "Aangepast",
|
||||||
|
"useMaterialYou": "Gebruik materiaal",
|
||||||
"githubStarredRepos": "GitHub-repo's met ster",
|
"githubStarredRepos": "GitHub-repo's met ster",
|
||||||
"uname": "Gebruikersnaam",
|
"uname": "Gebruikersnaam",
|
||||||
"wrongArgNum": "Onjuist aantal argumenten verstrekt.",
|
"wrongArgNum": "Onjuist aantal argumenten verstrekt.",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Geen nieuwe updates.",
|
"noNewUpdates": "Geen nieuwe updates.",
|
||||||
"xHasAnUpdate": "{} heeft een update.",
|
"xHasAnUpdate": "{} heeft een update.",
|
||||||
"appsUpdated": "Apps bijgewerkt",
|
"appsUpdated": "Apps bijgewerkt",
|
||||||
|
"appsNotUpdated": "Applicaties konden niet worden bijgewerkt",
|
||||||
"appsUpdatedNotifDescription": "Stelt de gebruiker op de hoogte dat updates voor één of meer apps in de achtergrond zijn toegepast.",
|
"appsUpdatedNotifDescription": "Stelt de gebruiker op de hoogte dat updates voor één of meer apps in de achtergrond zijn toegepast.",
|
||||||
"xWasUpdatedToY": "{} is bijgewerkt naar {}.",
|
"xWasUpdatedToY": "{} is bijgewerkt naar {}.",
|
||||||
|
"xWasNotUpdatedToY": "Het bijwerken van {} naar {} is mislukt.",
|
||||||
"errorCheckingUpdates": "Fout bij het controleren op updates",
|
"errorCheckingUpdates": "Fout bij het controleren op updates",
|
||||||
"errorCheckingUpdatesNotifDescription": "Een melding die verschijnt wanneer het controleren op updates in de achtergrond mislukt",
|
"errorCheckingUpdatesNotifDescription": "Een melding die verschijnt wanneer het controleren op updates in de achtergrond mislukt",
|
||||||
"appsRemoved": "Apps verwijderd",
|
"appsRemoved": "Apps verwijderd",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Ondersteuning vaste APK URL's",
|
"supportFixedAPKURL": "Ondersteuning vaste APK URL's",
|
||||||
"selectX": "Selecteer {}",
|
"selectX": "Selecteer {}",
|
||||||
"parallelDownloads": "Parallelle downloads toestaan",
|
"parallelDownloads": "Parallelle downloads toestaan",
|
||||||
"installMethod": "Installatiemethode",
|
"useShizuku": "Gebruik Shizuku of Sui om te installeren",
|
||||||
"normal": "Normaal",
|
|
||||||
"root": "Wortel",
|
|
||||||
"shizukuBinderNotFound": "Shizuku draait niet",
|
"shizukuBinderNotFound": "Shizuku draait niet",
|
||||||
|
"shizukuOld": "Oude Shizuku-versie (<11) - bijwerken",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku draait op Android < 8.1 met ADB - update Android of gebruik Sui in plaats daarvan",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Google Play instellen als installatiebron (als Shizuku wordt gebruikt)",
|
||||||
"useSystemFont": "Gebruik het systeemlettertype",
|
"useSystemFont": "Gebruik het systeemlettertype",
|
||||||
"systemFontError": "Fout bij het laden van het systeemlettertype: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Gebruik app versieCode als door OS gedetecteerde versie",
|
"useVersionCodeAsOSVersion": "Gebruik app versieCode als door OS gedetecteerde versie",
|
||||||
"requestHeader": "Verzoekkoptekst",
|
"requestHeader": "Verzoekkoptekst",
|
||||||
"useLatestAssetDateAsReleaseDate": "Gebruik laatste upload als releasedatum",
|
"useLatestAssetDateAsReleaseDate": "Gebruik laatste upload als releasedatum",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} en nog 1 app is bijgewerkt.",
|
"one": "{} en nog 1 app is bijgewerkt.",
|
||||||
"other": "{} en {} meer apps zijn bijgewerkt."
|
"other": "{} en {} meer apps zijn bijgewerkt."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Bijwerken mislukt {} en nog 1 app.",
|
||||||
|
"other": "Mislukt om {} en {} meer apps bij te werken."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} en nog 1 app zijn mogelijk bijgewerkt.",
|
"one": "{} en nog 1 app zijn mogelijk bijgewerkt.",
|
||||||
"other": "{} en {} meer apps zijn mogelijk bijgwerkt."
|
"other": "{} en {} meer apps zijn mogelijk bijgwerkt."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Wymagane)",
|
"requiredInBrackets": "(Wymagane)",
|
||||||
"dropdownNoOptsError": "BŁĄD: LISTA ROZWIJANA MUSI MIEĆ CO NAJMNIEJ JEDNĄ OPCJĘ",
|
"dropdownNoOptsError": "BŁĄD: LISTA ROZWIJANA MUSI MIEĆ CO NAJMNIEJ JEDNĄ OPCJĘ",
|
||||||
"colour": "Kolor",
|
"colour": "Kolor",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Niestandardowe",
|
||||||
|
"useMaterialYou": "Używaj materiałów",
|
||||||
"githubStarredRepos": "Repozytoria GitHub oznaczone gwiazdką",
|
"githubStarredRepos": "Repozytoria GitHub oznaczone gwiazdką",
|
||||||
"uname": "Nazwa użytkownika",
|
"uname": "Nazwa użytkownika",
|
||||||
"wrongArgNum": "Nieprawidłowa liczba podanych argumentów",
|
"wrongArgNum": "Nieprawidłowa liczba podanych argumentów",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Brak nowych aktualizacji.",
|
"noNewUpdates": "Brak nowych aktualizacji.",
|
||||||
"xHasAnUpdate": "{} ma aktualizację.",
|
"xHasAnUpdate": "{} ma aktualizację.",
|
||||||
"appsUpdated": "Zaktualizowano aplikacje",
|
"appsUpdated": "Zaktualizowano aplikacje",
|
||||||
|
"appsNotUpdated": "Nie udało się zaktualizować aplikacji",
|
||||||
"appsUpdatedNotifDescription": "Informuje, gdy co najmniej jedna aplikacja została zaktualizowana w tle",
|
"appsUpdatedNotifDescription": "Informuje, gdy co najmniej jedna aplikacja została zaktualizowana w tle",
|
||||||
"xWasUpdatedToY": "{} zaktualizowano do {}.",
|
"xWasUpdatedToY": "{} zaktualizowano do {}.",
|
||||||
|
"xWasNotUpdatedToY": "Nie udało się zaktualizować {} do {}.",
|
||||||
"errorCheckingUpdates": "Błąd sprawdzania aktualizacji",
|
"errorCheckingUpdates": "Błąd sprawdzania aktualizacji",
|
||||||
"errorCheckingUpdatesNotifDescription": "Jest wyświetlane, gdy sprawdzanie aktualizacji w tle nie powiedzie się",
|
"errorCheckingUpdatesNotifDescription": "Jest wyświetlane, gdy sprawdzanie aktualizacji w tle nie powiedzie się",
|
||||||
"appsRemoved": "Usunięte aplikacje",
|
"appsRemoved": "Usunięte aplikacje",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Obsługuj stałe adresy URL APK",
|
"supportFixedAPKURL": "Obsługuj stałe adresy URL APK",
|
||||||
"selectX": "Wybierz {}",
|
"selectX": "Wybierz {}",
|
||||||
"parallelDownloads": "Zezwól na pobieranie równoległe",
|
"parallelDownloads": "Zezwól na pobieranie równoległe",
|
||||||
"installMethod": "Metoda instalacji",
|
"useShizuku": "Użyj Shizuku lub Sui, aby zainstalować",
|
||||||
"normal": "Normalna",
|
|
||||||
"root": "Źródło",
|
|
||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
|
"shizukuOld": "Stara wersja Shizuku (<11) - zaktualizuj ją",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku działa na Androidzie < 8.1 z ADB - zaktualizuj Androida lub użyj zamiast tego Sui",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Ustaw Google Play jako źródło instalacji (jeśli używana jest aplikacja Shizuku).",
|
||||||
"useSystemFont": "Użyj czcionki systemowej",
|
"useSystemFont": "Użyj czcionki systemowej",
|
||||||
"systemFontError": "Błąd podczas ładowania czcionki systemowej: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Użyj kodu wersji aplikacji jako wersji wykrytej przez system operacyjny",
|
"useVersionCodeAsOSVersion": "Użyj kodu wersji aplikacji jako wersji wykrytej przez system operacyjny",
|
||||||
"requestHeader": "Nagłówek żądania",
|
"requestHeader": "Nagłówek żądania",
|
||||||
"useLatestAssetDateAsReleaseDate": "Użyj najnowszego przesłanego zasobu jako daty wydania",
|
"useLatestAssetDateAsReleaseDate": "Użyj najnowszego przesłanego zasobu jako daty wydania",
|
||||||
@@ -376,6 +381,10 @@
|
|||||||
"many": "{} i {} innych apek zostało zaktualizowanych.",
|
"many": "{} i {} innych apek zostało zaktualizowanych.",
|
||||||
"other": "{} i {} inne apki zostały zaktualizowane."
|
"other": "{} i {} inne apki zostały zaktualizowane."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Nie udało się zaktualizować {} i 1 innej aplikacji.",
|
||||||
|
"other": "Nie udało się zaktualizować {} i {} więcej aplikacji."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} i 1 inna apka mogły zostać zaktualizowane.",
|
"one": "{} i 1 inna apka mogły zostać zaktualizowane.",
|
||||||
"few": "{} i {} inne apki mogły zostać zaktualizowane.",
|
"few": "{} i {} inne apki mogły zostać zaktualizowane.",
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Necessário)",
|
"requiredInBrackets": "(Necessário)",
|
||||||
"dropdownNoOptsError": "ERRO: O DROPDOWN DEVE TER PELO MENOS UMA OPÇÃO",
|
"dropdownNoOptsError": "ERRO: O DROPDOWN DEVE TER PELO MENOS UMA OPÇÃO",
|
||||||
"colour": "Cor",
|
"colour": "Cor",
|
||||||
|
"standard": "Padrão",
|
||||||
|
"custom": "Personalizado",
|
||||||
|
"useMaterialYou": "Utilizar o material que",
|
||||||
"githubStarredRepos": "repositórios favoritos no GitHub",
|
"githubStarredRepos": "repositórios favoritos no GitHub",
|
||||||
"uname": "Nome de usuário",
|
"uname": "Nome de usuário",
|
||||||
"wrongArgNum": "Número de argumentos errado",
|
"wrongArgNum": "Número de argumentos errado",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Sem novas atualizações.",
|
"noNewUpdates": "Sem novas atualizações.",
|
||||||
"xHasAnUpdate": "{} tem uma atualização.",
|
"xHasAnUpdate": "{} tem uma atualização.",
|
||||||
"appsUpdated": "Aplicativos atualizados",
|
"appsUpdated": "Aplicativos atualizados",
|
||||||
|
"appsNotUpdated": "Falha na atualização das aplicações",
|
||||||
"appsUpdatedNotifDescription": "Notifica o usuário quando atualizações foram aplicadas em segundo-plano para um ou mais aplicativos ",
|
"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 {}.",
|
||||||
|
"xWasNotUpdatedToY": "Falha ao atualizar {} 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": "Aplicativos removidos",
|
"appsRemoved": "Aplicativos removidos",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Suporte a APK com URLs fixas",
|
"supportFixedAPKURL": "Suporte a APK com URLs fixas",
|
||||||
"selectX": "Selecionar {}",
|
"selectX": "Selecionar {}",
|
||||||
"parallelDownloads": "Permitir downloads paralelos",
|
"parallelDownloads": "Permitir downloads paralelos",
|
||||||
"installMethod": "Método de instalação",
|
"useShizuku": "Utilizar Shizuku ou Sui para instalar",
|
||||||
"normal": "Normal",
|
|
||||||
"root": "Root",
|
|
||||||
"shizukuBinderNotFound": "O Shizuku não está rodando",
|
"shizukuBinderNotFound": "O Shizuku não está rodando",
|
||||||
|
"shizukuOld": "Versão antiga do Shizuku (<11) - atualizar",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku a funcionar no Android < 8.1 com ADB - atualizar o Android ou utilizar o Sui",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Definir o Google Play como fonte de instalação (se for utilizado o Shizuku)",
|
||||||
"useSystemFont": "Usar fonte padrão do sistema",
|
"useSystemFont": "Usar fonte padrão do sistema",
|
||||||
"systemFontError": "Erro ao carregar a fonte do sistema: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Usar versionCode do aplicativo como versão detectada pelo sistema operacional",
|
"useVersionCodeAsOSVersion": "Usar versionCode do aplicativo como versão detectada pelo sistema operacional",
|
||||||
"requestHeader": "Requisitar cabeçalho",
|
"requestHeader": "Requisitar cabeçalho",
|
||||||
"useLatestAssetDateAsReleaseDate": "Use o último upload de recursos como data de lançamento",
|
"useLatestAssetDateAsReleaseDate": "Use o último upload de recursos como data de lançamento",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} e um outro aplicativo foram atualizado.",
|
"one": "{} e um outro aplicativo foram atualizado.",
|
||||||
"other": "{} e {} outros aplicativos foram atualizados."
|
"other": "{} e {} outros aplicativos foram atualizados."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Falha ao atualizar {} e mais 1 aplicação.",
|
||||||
|
"other": "Falha ao atualizar {} e {} mais aplicações."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} e um outro aplicativo podem ter sido atualizados.",
|
"one": "{} e um outro aplicativo podem ter sido atualizados.",
|
||||||
"other": "{} e {} outros aplicativos podem ter sido atualizados."
|
"other": "{} e {} outros aplicativos podem ter sido atualizados."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(обязательно)",
|
"requiredInBrackets": "(обязательно)",
|
||||||
"dropdownNoOptsError": "Ошибка: в выпадающем списке должна быть выбрана хотя бы одна настройка",
|
"dropdownNoOptsError": "Ошибка: в выпадающем списке должна быть выбрана хотя бы одна настройка",
|
||||||
"colour": "Цвет",
|
"colour": "Цвет",
|
||||||
|
"standard": "Стандартный",
|
||||||
|
"custom": "Индивидуальный",
|
||||||
|
"useMaterialYou": "Использовать Material You",
|
||||||
"githubStarredRepos": "Избранные репозитории GitHub",
|
"githubStarredRepos": "Избранные репозитории GitHub",
|
||||||
"uname": "Имя пользователя",
|
"uname": "Имя пользователя",
|
||||||
"wrongArgNum": "Неправильное количество предоставленных аргументов",
|
"wrongArgNum": "Неправильное количество предоставленных аргументов",
|
||||||
@@ -110,6 +113,7 @@
|
|||||||
"dark": "Тёмная",
|
"dark": "Тёмная",
|
||||||
"light": "Светлая",
|
"light": "Светлая",
|
||||||
"followSystem": "Системная",
|
"followSystem": "Системная",
|
||||||
|
"followSystemThemeExplanation": "Следование системной теме возможно только при использовании сторонних приложений",
|
||||||
"useBlackTheme": "Использовать чёрную тему",
|
"useBlackTheme": "Использовать чёрную тему",
|
||||||
"appSortBy": "Сортировка приложений",
|
"appSortBy": "Сортировка приложений",
|
||||||
"authorName": "Автор/Название",
|
"authorName": "Автор/Название",
|
||||||
@@ -143,8 +147,10 @@
|
|||||||
"noNewUpdates": "Нет новых обновлений",
|
"noNewUpdates": "Нет новых обновлений",
|
||||||
"xHasAnUpdate": "{} есть обновление",
|
"xHasAnUpdate": "{} есть обновление",
|
||||||
"appsUpdated": "Приложения обновлены",
|
"appsUpdated": "Приложения обновлены",
|
||||||
|
"appsNotUpdated": "Не удалось обновить приложения",
|
||||||
"appsUpdatedNotifDescription": "Уведомляет об обновлении одного или нескольких приложений в фоновом режиме",
|
"appsUpdatedNotifDescription": "Уведомляет об обновлении одного или нескольких приложений в фоновом режиме",
|
||||||
"xWasUpdatedToY": "{} была обновлена до версии {}",
|
"xWasUpdatedToY": "{} была обновлена до версии {}",
|
||||||
|
"xWasNotUpdatedToY": "Не удалось обновить {} до версии {}",
|
||||||
"errorCheckingUpdates": "Ошибка при проверке обновлений",
|
"errorCheckingUpdates": "Ошибка при проверке обновлений",
|
||||||
"errorCheckingUpdatesNotifDescription": "Уведомление о завершении проверки обновлений в фоновом режиме с ошибкой",
|
"errorCheckingUpdatesNotifDescription": "Уведомление о завершении проверки обновлений в фоновом режиме с ошибкой",
|
||||||
"appsRemoved": "Приложение удалено",
|
"appsRemoved": "Приложение удалено",
|
||||||
@@ -282,12 +288,12 @@
|
|||||||
"supportFixedAPKURL": "Поддержка фиксированных URL-адресов APK",
|
"supportFixedAPKURL": "Поддержка фиксированных URL-адресов APK",
|
||||||
"selectX": "Выбрать {}",
|
"selectX": "Выбрать {}",
|
||||||
"parallelDownloads": "Разрешить параллельные загрузки",
|
"parallelDownloads": "Разрешить параллельные загрузки",
|
||||||
"installMethod": "Метод установки",
|
"useShizuku": "Использовать Shizuku или Sui для установки",
|
||||||
"normal": "Нормальный",
|
"shizukuBinderNotFound": "Совместимый сервис Shizuku не найден, возможно он не запущен",
|
||||||
"root": "Суперпользователь",
|
"shizukuOld": "Устаревшая версия Shizuku (<11), обновите",
|
||||||
"shizukuBinderNotFound": "Совместимый сервис Shizuku не найден",
|
"shizukuOldAndroidWithADB": "Shizuku работает на Android < 8.1 с ADB, обновите Android или используйте Sui",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Указать Google Play как источник установки (если используется Shizuku)",
|
||||||
"useSystemFont": "Использовать системный шрифт",
|
"useSystemFont": "Использовать системный шрифт",
|
||||||
"systemFontError": "Ошибка загрузки системного шрифта: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Использовать код версии приложения как версию, обнаруженную ОС",
|
"useVersionCodeAsOSVersion": "Использовать код версии приложения как версию, обнаруженную ОС",
|
||||||
"requestHeader": "Заголовок запроса",
|
"requestHeader": "Заголовок запроса",
|
||||||
"useLatestAssetDateAsReleaseDate": "Использовать последнюю загрузку ресурса в качестве даты выпуска",
|
"useLatestAssetDateAsReleaseDate": "Использовать последнюю загрузку ресурса в качестве даты выпуска",
|
||||||
@@ -352,12 +358,16 @@
|
|||||||
"one": "{} и ещё 1 приложение были обновлены",
|
"one": "{} и ещё 1 приложение были обновлены",
|
||||||
"other": "{} и ещё {} приложений были обновлены"
|
"other": "{} и ещё {} приложений были обновлены"
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Не удалось обновить {} и ещё 1 приложение",
|
||||||
|
"other": "Не удалось обновить {} и ещё {} приложений"
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} и ещё 1 приложение могли быть обновлены",
|
"one": "{} и ещё 1 приложение могли быть обновлены",
|
||||||
"other": "{} и ещё {} приложений могли быть обновлены"
|
"other": "{} и ещё {} приложений могли быть обновлены"
|
||||||
},
|
},
|
||||||
"apk": {
|
"apk": {
|
||||||
"one": "{} APK",
|
"one": "{} APK",
|
||||||
"other": "{} APKs"
|
"other": "{} APKи"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Kräver)",
|
"requiredInBrackets": "(Kräver)",
|
||||||
"dropdownNoOptsError": "FEL: DROPDOWN MÅSTE HA MINST ETT OPT",
|
"dropdownNoOptsError": "FEL: DROPDOWN MÅSTE HA MINST ETT OPT",
|
||||||
"colour": "Färg",
|
"colour": "Färg",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Anpassad",
|
||||||
|
"useMaterialYou": "Använd material Du",
|
||||||
"githubStarredRepos": "GitHub Stjärnmärkta Förråd",
|
"githubStarredRepos": "GitHub Stjärnmärkta Förråd",
|
||||||
"uname": "Användarnamn",
|
"uname": "Användarnamn",
|
||||||
"wrongArgNum": "Fel antal argument har angetts",
|
"wrongArgNum": "Fel antal argument har angetts",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Inga nya uppdateringar.",
|
"noNewUpdates": "Inga nya uppdateringar.",
|
||||||
"xHasAnUpdate": "{} har en uppdatering.",
|
"xHasAnUpdate": "{} har en uppdatering.",
|
||||||
"appsUpdated": "Appar Uppdaterade",
|
"appsUpdated": "Appar Uppdaterade",
|
||||||
|
"appsNotUpdated": "Misslyckades med att uppdatera applikationer",
|
||||||
"appsUpdatedNotifDescription": "Meddelar användaren att uppdateringar av en eller flera appar har tillämpats i bakgrunden",
|
"appsUpdatedNotifDescription": "Meddelar användaren att uppdateringar av en eller flera appar har tillämpats i bakgrunden",
|
||||||
"xWasUpdatedToY": "{} uppdaterades till {}.",
|
"xWasUpdatedToY": "{} uppdaterades till {}.",
|
||||||
|
"xWasNotUpdatedToY": "Det gick inte att uppdatera {} till {}.",
|
||||||
"errorCheckingUpdates": "Fel vid uppdateringskoll",
|
"errorCheckingUpdates": "Fel vid uppdateringskoll",
|
||||||
"errorCheckingUpdatesNotifDescription": "En aviserings som visar när bakgrundsuppdateringarkollar misslyckas",
|
"errorCheckingUpdatesNotifDescription": "En aviserings som visar när bakgrundsuppdateringarkollar misslyckas",
|
||||||
"appsRemoved": "Appar borttagna",
|
"appsRemoved": "Appar borttagna",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Stöd fasta APK-webbadresser",
|
"supportFixedAPKURL": "Stöd fasta APK-webbadresser",
|
||||||
"selectX": "Välj {}",
|
"selectX": "Välj {}",
|
||||||
"parallelDownloads": "Tillåt parallella nedladdningar",
|
"parallelDownloads": "Tillåt parallella nedladdningar",
|
||||||
"installMethod": "Installationsmetod",
|
"useShizuku": "Använd Shizuku eller Sui för att installera",
|
||||||
"normal": "Vanligt",
|
|
||||||
"root": "Rot",
|
|
||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
|
"shizukuOld": "Gammal Shizuku-version (<11) - uppdatera den",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku körs på Android < 8.1 med ADB - uppdatera Android eller använd Sui istället",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Ange Google Play som installationskälla (om Shizuku används)",
|
||||||
"useSystemFont": "Använd systemteckensnittet",
|
"useSystemFont": "Använd systemteckensnittet",
|
||||||
"systemFontError": "Fel vid laddning av systemteckensnittet: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Använd appversionskoden som OS-upptäckt version",
|
"useVersionCodeAsOSVersion": "Använd appversionskoden som OS-upptäckt version",
|
||||||
"requestHeader": "Rubrik för begäran",
|
"requestHeader": "Rubrik för begäran",
|
||||||
"useLatestAssetDateAsReleaseDate": "Använd senaste tillgångsuppladdning som releasedatum",
|
"useLatestAssetDateAsReleaseDate": "Använd senaste tillgångsuppladdning som releasedatum",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} och 1 till app uppdaterades.",
|
"one": "{} och 1 till app uppdaterades.",
|
||||||
"other": "{} och {} appar till uppdaterades."
|
"other": "{} och {} appar till uppdaterades."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Misslyckades med att uppdatera {} och ytterligare 1 app.",
|
||||||
|
"other": "Det gick inte att uppdatera {} och {} fler appar."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} och 1 till app kan ha uppdaterats.",
|
"one": "{} och 1 till app kan ha uppdaterats.",
|
||||||
"other": "{} och {} appar till kan ha uppdaterats."
|
"other": "{} och {} appar till kan ha uppdaterats."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Gerekli)",
|
"requiredInBrackets": "(Gerekli)",
|
||||||
"dropdownNoOptsError": "HATA: DİPLOMADA EN AZ BİR SEÇENEK OLMALI",
|
"dropdownNoOptsError": "HATA: DİPLOMADA EN AZ BİR SEÇENEK OLMALI",
|
||||||
"colour": "Renk",
|
"colour": "Renk",
|
||||||
|
"standard": "Standart",
|
||||||
|
"custom": "Özel",
|
||||||
|
"useMaterialYou": "Sizin Malzemenizi Kullanın",
|
||||||
"githubStarredRepos": "GitHub'a Yıldızlı Depolar",
|
"githubStarredRepos": "GitHub'a Yıldızlı Depolar",
|
||||||
"uname": "Kullanıcı Adı",
|
"uname": "Kullanıcı Adı",
|
||||||
"wrongArgNum": "Hatalı argüman sayısı sağlandı",
|
"wrongArgNum": "Hatalı argüman sayısı sağlandı",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Yeni güncelleme yok.",
|
"noNewUpdates": "Yeni güncelleme yok.",
|
||||||
"xHasAnUpdate": "{} güncelleme alıyor.",
|
"xHasAnUpdate": "{} güncelleme alıyor.",
|
||||||
"appsUpdated": "Uygulamalar Güncellendi",
|
"appsUpdated": "Uygulamalar Güncellendi",
|
||||||
|
"appsNotUpdated": "Uygulamalar güncellenemedi",
|
||||||
"appsUpdatedNotifDescription": "Kullanıcıya bir veya daha fazla uygulamanın arka planda güncellendiğine dair bilgi verir",
|
"appsUpdatedNotifDescription": "Kullanıcıya bir veya daha fazla uygulamanın arka planda güncellendiğine dair bilgi verir",
|
||||||
"xWasUpdatedToY": "{} şu sürüme güncellendi: {}.",
|
"xWasUpdatedToY": "{} şu sürüme güncellendi: {}.",
|
||||||
|
"xWasNotUpdatedToY": "{} öğesi {} olarak güncellenemedi.",
|
||||||
"errorCheckingUpdates": "Güncellemeler Kontrol Edilirken Hata Oluştu",
|
"errorCheckingUpdates": "Güncellemeler Kontrol Edilirken Hata Oluştu",
|
||||||
"errorCheckingUpdatesNotifDescription": "Arka planda güncelleme kontrolü sırasında hata oluştuğunda görünen bir bildirim",
|
"errorCheckingUpdatesNotifDescription": "Arka planda güncelleme kontrolü sırasında hata oluştuğunda görünen bir bildirim",
|
||||||
"appsRemoved": "Uygulamalar Kaldırıldı",
|
"appsRemoved": "Uygulamalar Kaldırıldı",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Sabit APK URL'lerini destekleyin",
|
"supportFixedAPKURL": "Sabit APK URL'lerini destekleyin",
|
||||||
"selectX": "Seçme {}",
|
"selectX": "Seçme {}",
|
||||||
"parallelDownloads": "Paralel indirmelere izin ver",
|
"parallelDownloads": "Paralel indirmelere izin ver",
|
||||||
"installMethod": "Kurulum yöntemi",
|
"useShizuku": "Yüklemek için Shizuku veya Sui'yi kullanın",
|
||||||
"normal": "Normal",
|
|
||||||
"root": "Kök",
|
|
||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
|
"shizukuOld": "Eski Shizuku sürümü (<11) - güncelleyin",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku ADB ile Android < 8.1 üzerinde çalışıyor - Android'i güncelleyin veya bunun yerine Sui kullanın",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Google Play'i yükleme kaynağı olarak ayarlayın (Shizuku kullanılıyorsa)",
|
||||||
"useSystemFont": "Sistem yazı tipini kullan",
|
"useSystemFont": "Sistem yazı tipini kullan",
|
||||||
"systemFontError": "Sistem yazı tipi yüklenirken hata oluştu: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Uygulama versionCode'unu işletim sistemi tarafından algılanan sürüm olarak kullan",
|
"useVersionCodeAsOSVersion": "Uygulama versionCode'unu işletim sistemi tarafından algılanan sürüm olarak kullan",
|
||||||
"requestHeader": "Başlık talep et",
|
"requestHeader": "Başlık talep et",
|
||||||
"useLatestAssetDateAsReleaseDate": "Yayın tarihi olarak en son öğe yüklemesini kullan",
|
"useLatestAssetDateAsReleaseDate": "Yayın tarihi olarak en son öğe yüklemesini kullan",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} ve 1 diğer uygulama güncellendi.",
|
"one": "{} ve 1 diğer uygulama güncellendi.",
|
||||||
"other": "{} ve {} daha fazla uygulama güncellendi."
|
"other": "{} ve {} daha fazla uygulama güncellendi."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "{} ve 1 uygulama daha güncellenemedi.",
|
||||||
|
"other": "{} ve {} daha fazla uygulama güncellenemedi."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"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."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(Обов'язково)",
|
"requiredInBrackets": "(Обов'язково)",
|
||||||
"dropdownNoOptsError": "ПОМИЛКА: В ВИПАДАЮЧОМУ СПИСКУ МАЄ БУТИ ХОЧА Б ОДИН ЕЛЕМЕНТ",
|
"dropdownNoOptsError": "ПОМИЛКА: В ВИПАДАЮЧОМУ СПИСКУ МАЄ БУТИ ХОЧА Б ОДИН ЕЛЕМЕНТ",
|
||||||
"colour": "Колір",
|
"colour": "Колір",
|
||||||
|
"standard": "Стандартний",
|
||||||
|
"custom": "Нестандартний",
|
||||||
|
"useMaterialYou": "Використовуйте матеріал, який ви",
|
||||||
"githubStarredRepos": "Відзначені репозиторії GitHub",
|
"githubStarredRepos": "Відзначені репозиторії GitHub",
|
||||||
"uname": "Ім'я користувача",
|
"uname": "Ім'я користувача",
|
||||||
"wrongArgNum": "Надано неправильну кількість аргументів",
|
"wrongArgNum": "Надано неправильну кількість аргументів",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Немає нових оновлень.",
|
"noNewUpdates": "Немає нових оновлень.",
|
||||||
"xHasAnUpdate": "{} має оновлення.",
|
"xHasAnUpdate": "{} має оновлення.",
|
||||||
"appsUpdated": "Застосунки оновлено",
|
"appsUpdated": "Застосунки оновлено",
|
||||||
|
"appsNotUpdated": "Не вдалося оновити програми",
|
||||||
"appsUpdatedNotifDescription": "Повідомляє користувача, що оновлення одного чи декількох застосунків було застосовано в фоновому режимі",
|
"appsUpdatedNotifDescription": "Повідомляє користувача, що оновлення одного чи декількох застосунків було застосовано в фоновому режимі",
|
||||||
"xWasUpdatedToY": "{} було оновлено до {}.",
|
"xWasUpdatedToY": "{} було оновлено до {}.",
|
||||||
|
"xWasNotUpdatedToY": "Не вдалося оновити {} на {}.",
|
||||||
"errorCheckingUpdates": "Помилка перевірки оновлень",
|
"errorCheckingUpdates": "Помилка перевірки оновлень",
|
||||||
"errorCheckingUpdatesNotifDescription": "Повідомлення, яке з'являється, коли перевірка оновлень в фоновому режимі завершується невдачею",
|
"errorCheckingUpdatesNotifDescription": "Повідомлення, яке з'являється, коли перевірка оновлень в фоновому режимі завершується невдачею",
|
||||||
"appsRemoved": "Застосунки видалено",
|
"appsRemoved": "Застосунки видалено",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Підтримка фіксованих посилань на APK",
|
"supportFixedAPKURL": "Підтримка фіксованих посилань на APK",
|
||||||
"selectX": "Вибрати {}",
|
"selectX": "Вибрати {}",
|
||||||
"parallelDownloads": "Дозволити паралельні завантаження",
|
"parallelDownloads": "Дозволити паралельні завантаження",
|
||||||
"installMethod": "Метод встановлення",
|
"useShizuku": "Використовуйте Shizuku або Sui для встановлення",
|
||||||
"normal": "Звичайний",
|
|
||||||
"root": "Root",
|
|
||||||
"shizukuBinderNotFound": "Сумісний сервіс Shizuku не було знайдено",
|
"shizukuBinderNotFound": "Сумісний сервіс Shizuku не було знайдено",
|
||||||
|
"shizukuOld": "Стара версія Shizuku (<11) - оновіть її",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku працює на Android < 8.1 з ADB - оновіть Android або використовуйте Sui замість нього",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Виберіть Google Play як джерело встановлення (якщо використовується Shizuku)",
|
||||||
"useSystemFont": "Використовувати системний шрифт",
|
"useSystemFont": "Використовувати системний шрифт",
|
||||||
"systemFontError": "Помилка завантаження системного шрифту: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Використовувати код версії застосунку як версію, визначену операційною системою",
|
"useVersionCodeAsOSVersion": "Використовувати код версії застосунку як версію, визначену операційною системою",
|
||||||
"requestHeader": "Заголовок запиту",
|
"requestHeader": "Заголовок запиту",
|
||||||
"useLatestAssetDateAsReleaseDate": "Використовувати останню дату завантаження ресурсу як дату випуску",
|
"useLatestAssetDateAsReleaseDate": "Використовувати останню дату завантаження ресурсу як дату випуску",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} та ще 1 застосунок було оновлено.",
|
"one": "{} та ще 1 застосунок було оновлено.",
|
||||||
"other": "{} та ще {} застосунків було оновлено."
|
"other": "{} та ще {} застосунків було оновлено."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Не вдалося оновити {} та ще 1 програму.",
|
||||||
|
"other": "Не вдалося оновити {} і {} та інші програми."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} та ще 1 застосунок можливо було оновлено.",
|
"one": "{} та ще 1 застосунок можливо було оновлено.",
|
||||||
"other": "{} та ще {} застосунків можливо було оновлено."
|
"other": "{} та ще {} застосунків можливо було оновлено."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"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",
|
||||||
"colour": "Màu sắc",
|
"colour": "Màu sắc",
|
||||||
|
"standard": "Standard",
|
||||||
|
"custom": "Custom",
|
||||||
|
"useMaterialYou": "Use Material You",
|
||||||
"githubStarredRepos": "Kho lưu trữ có gắn dấu sao GitHub",
|
"githubStarredRepos": "Kho lưu trữ có gắn dấu sao GitHub",
|
||||||
"uname": "Tên người dùng",
|
"uname": "Tên người dùng",
|
||||||
"wrongArgNum": "Số lượng đối số được cung cấp sai",
|
"wrongArgNum": "Số lượng đối số được cung cấp sai",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "Không có bản cập nhật mới.",
|
"noNewUpdates": "Không có bản cập nhật mới.",
|
||||||
"xHasAnUpdate": "{} có bản cập nhật.",
|
"xHasAnUpdate": "{} có bản cập nhật.",
|
||||||
"appsUpdated": "Ứng dụng đã cập nhật ",
|
"appsUpdated": "Ứng dụng đã cập nhật ",
|
||||||
|
"appsNotUpdated": "Failed to update applications",
|
||||||
"appsUpdatedNotifDescription": "Thông báo cho người dùng rằng các bản cập nhật cho một hoặc nhiều Ứng dụng đã được áp dụng trong nền",
|
"appsUpdatedNotifDescription": "Thông báo cho người dùng rằng các bản cập nhật cho một hoặc nhiều Ứng dụng đã được áp dụng trong nền",
|
||||||
"xWasUpdatedToY": "{} đã được cập nhật thành {}.",
|
"xWasUpdatedToY": "{} đã được cập nhật thành {}.",
|
||||||
|
"xWasNotUpdatedToY": "Failed to update {} to {}.",
|
||||||
"errorCheckingUpdates": "Lỗi kiểm tra bản cập nhật",
|
"errorCheckingUpdates": "Lỗi kiểm tra bản cập nhật",
|
||||||
"errorCheckingUpdatesNotifDescription": "Thông báo hiển thị khi kiểm tra cập nhật nền không thành công",
|
"errorCheckingUpdatesNotifDescription": "Thông báo hiển thị khi kiểm tra cập nhật nền không thành công",
|
||||||
"appsRemoved": "Ứng dụng đã loại bỏ",
|
"appsRemoved": "Ứng dụng đã loại bỏ",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "Hỗ trợ URL APK cố định",
|
"supportFixedAPKURL": "Hỗ trợ URL APK cố định",
|
||||||
"selectX": "Lựa chọn {}",
|
"selectX": "Lựa chọn {}",
|
||||||
"parallelDownloads": "Cho phép tải đa luồng",
|
"parallelDownloads": "Cho phép tải đa luồng",
|
||||||
"installMethod": "Phương thức cài đặt",
|
"useShizuku": "Use Shizuku or Sui to install",
|
||||||
"normal": "Mặc định",
|
|
||||||
"root": "Root",
|
|
||||||
"shizukuBinderNotFound": "Shizuku chưa khởi động",
|
"shizukuBinderNotFound": "Shizuku chưa khởi động",
|
||||||
|
"shizukuOld": "Old Shizuku version (<11) - update it",
|
||||||
|
"shizukuOldAndroidWithADB": "Shizuku running on Android < 8.1 with ADB - update Android or use Sui instead",
|
||||||
|
"shizukuPretendToBeGooglePlay": "Set Google Play as the installation source (if Shizuku is used)",
|
||||||
"useSystemFont": "Sử dụng phông chữ hệ thống",
|
"useSystemFont": "Sử dụng phông chữ hệ thống",
|
||||||
"systemFontError": "Lỗi tải phông chữ hệ thống: {}",
|
|
||||||
"useVersionCodeAsOSVersion": "Sử dụng Mã phiên bản ứng dụng làm phiên bản do hệ điều hành phát hiện",
|
"useVersionCodeAsOSVersion": "Sử dụng Mã phiên bản ứng dụng làm phiên bản do hệ điều hành phát hiện",
|
||||||
"requestHeader": "Tiêu đề yêu cầu",
|
"requestHeader": "Tiêu đề yêu cầu",
|
||||||
"useLatestAssetDateAsReleaseDate": "Sử dụng nội dung tải lên mới nhất làm ngày phát hành",
|
"useLatestAssetDateAsReleaseDate": "Sử dụng nội dung tải lên mới nhất làm ngày phát hành",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} và 1 ứng dụng khác đã được cập nhật.",
|
"one": "{} và 1 ứng dụng khác đã được cập nhật.",
|
||||||
"other": "{} và {} ứng dụng khác đã được cập nhật."
|
"other": "{} và {} ứng dụng khác đã được cập nhật."
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "Failed to update {} and 1 more app.",
|
||||||
|
"other": "Failed to update {} and {} more apps."
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} và 1 ứng dụng khác có thể đã được cập nhật.",
|
"one": "{} và 1 ứng dụng khác có thể đã được cập nhật.",
|
||||||
"other": "{} và {} ứng dụng khác có thể đã được cập nhật."
|
"other": "{} và {} ứng dụng khác có thể đã được cập nhật."
|
||||||
|
@@ -22,6 +22,9 @@
|
|||||||
"requiredInBrackets": "(必填)",
|
"requiredInBrackets": "(必填)",
|
||||||
"dropdownNoOptsError": "错误:下拉菜单必须包含至少一个选项",
|
"dropdownNoOptsError": "错误:下拉菜单必须包含至少一个选项",
|
||||||
"colour": "配色",
|
"colour": "配色",
|
||||||
|
"standard": "标准",
|
||||||
|
"custom": "定制",
|
||||||
|
"useMaterialYou": "使用 Material You",
|
||||||
"githubStarredRepos": "已星标的 GitHub 仓库",
|
"githubStarredRepos": "已星标的 GitHub 仓库",
|
||||||
"uname": "用户名",
|
"uname": "用户名",
|
||||||
"wrongArgNum": "参数数量错误",
|
"wrongArgNum": "参数数量错误",
|
||||||
@@ -143,8 +146,10 @@
|
|||||||
"noNewUpdates": "全部应用已是最新。",
|
"noNewUpdates": "全部应用已是最新。",
|
||||||
"xHasAnUpdate": "“{}”可以更新了。",
|
"xHasAnUpdate": "“{}”可以更新了。",
|
||||||
"appsUpdated": "应用已更新",
|
"appsUpdated": "应用已更新",
|
||||||
|
"appsNotUpdated": "更新应用程序失败",
|
||||||
"appsUpdatedNotifDescription": "当应用在后台安装更新时发送通知",
|
"appsUpdatedNotifDescription": "当应用在后台安装更新时发送通知",
|
||||||
"xWasUpdatedToY": "“{}”已更新至 {}。",
|
"xWasUpdatedToY": "“{}”已更新至 {}。",
|
||||||
|
"xWasNotUpdatedToY": "未能将 {} 更新为 {}。",
|
||||||
"errorCheckingUpdates": "检查更新出错",
|
"errorCheckingUpdates": "检查更新出错",
|
||||||
"errorCheckingUpdatesNotifDescription": "当后台检查更新失败时显示的通知",
|
"errorCheckingUpdatesNotifDescription": "当后台检查更新失败时显示的通知",
|
||||||
"appsRemoved": "应用已删除",
|
"appsRemoved": "应用已删除",
|
||||||
@@ -185,7 +190,7 @@
|
|||||||
"downloadingX": "正在下载“{}”",
|
"downloadingX": "正在下载“{}”",
|
||||||
"downloadX": "下载 {}",
|
"downloadX": "下载 {}",
|
||||||
"downloadedX": "下载 {}",
|
"downloadedX": "下载 {}",
|
||||||
"releaseAsset": "释放资产",
|
"releaseAsset": "发行版",
|
||||||
"downloadNotifDescription": "提示应用的下载进度",
|
"downloadNotifDescription": "提示应用的下载进度",
|
||||||
"noAPKFound": "未找到 APK 文件",
|
"noAPKFound": "未找到 APK 文件",
|
||||||
"noVersionDetection": "禁用版本检测",
|
"noVersionDetection": "禁用版本检测",
|
||||||
@@ -252,8 +257,8 @@
|
|||||||
"exemptFromBackgroundUpdates": "禁用后台更新(如果已经全局启用)",
|
"exemptFromBackgroundUpdates": "禁用后台更新(如果已经全局启用)",
|
||||||
"bgUpdatesOnWiFiOnly": "未连接 Wi-Fi 时禁用后台更新",
|
"bgUpdatesOnWiFiOnly": "未连接 Wi-Fi 时禁用后台更新",
|
||||||
"autoSelectHighestVersionCode": "自动选择内部版本号最高的 APK 文件",
|
"autoSelectHighestVersionCode": "自动选择内部版本号最高的 APK 文件",
|
||||||
"versionExtractionRegEx": "版本号提取规则(正则表达式)",
|
"versionExtractionRegEx": "版本号匹配组规则(正则表达式)",
|
||||||
"matchGroupToUse": "引用的捕获组",
|
"matchGroupToUse": "引用匹配组规则,将用于版本字符串提取",
|
||||||
"highlightTouchTargets": "突出展示不明显的触摸区域",
|
"highlightTouchTargets": "突出展示不明显的触摸区域",
|
||||||
"pickExportDir": "选择导出文件夹",
|
"pickExportDir": "选择导出文件夹",
|
||||||
"autoExportOnChanges": "数据变更时自动导出",
|
"autoExportOnChanges": "数据变更时自动导出",
|
||||||
@@ -282,12 +287,12 @@
|
|||||||
"supportFixedAPKURL": "支持固定的 APK 文件链接",
|
"supportFixedAPKURL": "支持固定的 APK 文件链接",
|
||||||
"selectX": "选择{}",
|
"selectX": "选择{}",
|
||||||
"parallelDownloads": "启用并行下载",
|
"parallelDownloads": "启用并行下载",
|
||||||
"installMethod": "安装方式",
|
"useShizuku": "使用 Shizuku 或 Sui 安装",
|
||||||
"normal": "常规",
|
|
||||||
"root": "root",
|
|
||||||
"shizukuBinderNotFound": "未发现兼容的 Shizuku 服务",
|
"shizukuBinderNotFound": "未发现兼容的 Shizuku 服务",
|
||||||
|
"shizukuOld": "旧的 Shizuku 版本 (<11) - 更新它",
|
||||||
|
"shizukuOldAndroidWithADB": "使用 ADB 在 Android < 8.1 上运行 Shizuku - 更新 Android 或使用 Sui 代替",
|
||||||
|
"shizukuPretendToBeGooglePlay": "将 Google Play 设置为安装源(如果使用 Shizuku)",
|
||||||
"useSystemFont": "使用系统字体",
|
"useSystemFont": "使用系统字体",
|
||||||
"systemFontError": "加载系统字体出错:{}",
|
|
||||||
"useVersionCodeAsOSVersion": "使用内部版本号代替应用定义的版本号",
|
"useVersionCodeAsOSVersion": "使用内部版本号代替应用定义的版本号",
|
||||||
"requestHeader": "请求标头",
|
"requestHeader": "请求标头",
|
||||||
"useLatestAssetDateAsReleaseDate": "使用最近文件上传时间作为发行日期",
|
"useLatestAssetDateAsReleaseDate": "使用最近文件上传时间作为发行日期",
|
||||||
@@ -352,6 +357,10 @@
|
|||||||
"one": "{} 和另外 1 个应用已更新。",
|
"one": "{} 和另外 1 个应用已更新。",
|
||||||
"other": "“{}”和另外 {} 个应用已更新。"
|
"other": "“{}”和另外 {} 个应用已更新。"
|
||||||
},
|
},
|
||||||
|
"xAndNMoreUpdatesFailed": {
|
||||||
|
"one": "更新 {} 和另外 1 个应用程序失败。",
|
||||||
|
"other": "未能更新 {} 和 {} 更多应用程序。"
|
||||||
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} 和另外 1 个应用已尝试更新。",
|
"one": "{} 和另外 1 个应用已尝试更新。",
|
||||||
"other": "“{}”和另外 {} 个应用已尝试更新。"
|
"other": "“{}”和另外 {} 个应用已尝试更新。"
|
||||||
|
54
fastlane/metadata/android/ru/full_description.txt
Normal file
54
fastlane/metadata/android/ru/full_description.txt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<p>Obtainium позволяет вам устанавливать и обновлять приложения прямо с их объявлений о выпусках и получать уведомления о новых выпусках.</p>
|
||||||
|
<p>Для деталей читайте <a href="https://github.com/ImranR98/Obtainium/wiki">Вики</a></p>
|
||||||
|
<p>
|
||||||
|
<b>Поддерживаемые источники приложений:</b>
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<p>Свободное ПО - Общие:</p>
|
||||||
|
<ul>
|
||||||
|
<li>GitHub</li>
|
||||||
|
<li>GitLab</li>
|
||||||
|
<li>Codeberg</li>
|
||||||
|
<li>F-Droid</li>
|
||||||
|
<li>Third Party F-Droid Repos</li>
|
||||||
|
<li>IzzyOnDroid</li>
|
||||||
|
<li>SourceForge</li>
|
||||||
|
<li>SourceHut</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Другие - Общие:</p>
|
||||||
|
<ul>
|
||||||
|
<li>APKPure</li>
|
||||||
|
<li>Aptoide</li>
|
||||||
|
<li>Uptodowng</li>
|
||||||
|
<li>APKMirror (Track-Only)</li>
|
||||||
|
<li>Huawei AppGallery</li>
|
||||||
|
<li>Jenkins Jobs</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Свободное ПО - Для отдельных приложений:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Mullvad</li>
|
||||||
|
<li>Signal</li>
|
||||||
|
<li>VLC</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Другие - Для отдельных приложений:</p>
|
||||||
|
<ul>
|
||||||
|
<li>WhatsApp</li>
|
||||||
|
<li>Telegram App</li>
|
||||||
|
<li>Neutron Code</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><p>"HTML" (Подстраховка): Любой другой URL-адрес, который возвращает HTML-страницу со ссылками на APK-файлы.</p></li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<b>Ограничения:</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Для некоторых источников данные собираются с помощью веб-скрапинга и могут легко сломаться из-за изменений в дизайне веб-сайта. В таких случаях более надежные методы могут быть недоступны.
|
||||||
|
</p>
|
1
fastlane/metadata/android/ru/short_description.txt
Normal file
1
fastlane/metadata/android/ru/short_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Получайте обновления приложений прямо из источника
|
@@ -243,18 +243,28 @@ class HTML extends AppSource {
|
|||||||
if ((additionalSettings['customLinkFilterRegex'] as String?)?.isNotEmpty ==
|
if ((additionalSettings['customLinkFilterRegex'] as String?)?.isNotEmpty ==
|
||||||
true) {
|
true) {
|
||||||
var reg = RegExp(additionalSettings['customLinkFilterRegex']);
|
var reg = RegExp(additionalSettings['customLinkFilterRegex']);
|
||||||
links = allLinks
|
links = allLinks.where((element) {
|
||||||
.where((element) =>
|
var link = element.key;
|
||||||
reg.hasMatch(filterLinkByText ? element.value : element.key))
|
try {
|
||||||
.toList();
|
link = Uri.decodeFull(element.key);
|
||||||
|
} catch (e) {
|
||||||
|
// Some links may not have valid encoding
|
||||||
|
}
|
||||||
|
return reg.hasMatch(filterLinkByText ? element.value : link);
|
||||||
|
}).toList();
|
||||||
} else {
|
} else {
|
||||||
links = allLinks
|
links = allLinks.where((element) {
|
||||||
.where((element) =>
|
var link = element.key;
|
||||||
Uri.parse(filterLinkByText ? element.value : element.key)
|
try {
|
||||||
|
link = Uri.decodeFull(element.key);
|
||||||
|
} catch (e) {
|
||||||
|
// Some links may not have valid encoding
|
||||||
|
}
|
||||||
|
return Uri.parse(filterLinkByText ? element.value : link)
|
||||||
.path
|
.path
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.endsWith('.apk'))
|
.endsWith('.apk');
|
||||||
.toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
if (!skipSort) {
|
if (!skipSort) {
|
||||||
links.sort((a, b) => additionalSettings['sortByLastLinkSegment'] == true
|
links.sort((a, b) => additionalSettings['sortByLastLinkSegment'] == true
|
||||||
@@ -309,13 +319,19 @@ class HTML extends AppSource {
|
|||||||
links = [MapEntry(currentUrl, currentUrl)];
|
links = [MapEntry(currentUrl, currentUrl)];
|
||||||
}
|
}
|
||||||
var rel = links.last.key;
|
var rel = links.last.key;
|
||||||
|
var relDecoded = rel;
|
||||||
|
try {
|
||||||
|
relDecoded = Uri.decodeFull(rel);
|
||||||
|
} catch (e) {
|
||||||
|
// Some links may not have valid encoding
|
||||||
|
}
|
||||||
String? version;
|
String? version;
|
||||||
version = extractVersion(
|
version = extractVersion(
|
||||||
additionalSettings['versionExtractionRegEx'] as String?,
|
additionalSettings['versionExtractionRegEx'] as String?,
|
||||||
additionalSettings['matchGroupToUse'] as String?,
|
additionalSettings['matchGroupToUse'] as String?,
|
||||||
additionalSettings['versionExtractWholePage'] == true
|
additionalSettings['versionExtractWholePage'] == true
|
||||||
? versionExtractionWholePageString
|
? versionExtractionWholePageString
|
||||||
: rel);
|
: relDecoded);
|
||||||
version ??=
|
version ??=
|
||||||
additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash'
|
additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash'
|
||||||
? rel.hashCode.toString()
|
? rel.hashCode.toString()
|
||||||
|
@@ -84,7 +84,7 @@ class HuaweiAppGallery extends AppSource {
|
|||||||
}
|
}
|
||||||
var relDate = relDateStrAdj == null
|
var relDate = relDateStrAdj == null
|
||||||
? null
|
? null
|
||||||
: DateFormat('yy-MM-dd-HH-mm').parse(relDateStrAdj.join(''));
|
: DateFormat('yy-MM-dd-HH-mm', 'en_US').parse(relDateStrAdj.join(''));
|
||||||
if (relDateStr == null) {
|
if (relDateStr == null) {
|
||||||
throw NoVersionError();
|
throw NoVersionError();
|
||||||
}
|
}
|
||||||
|
@@ -245,8 +245,8 @@ class _GeneratedFormState extends State<GeneratedForm> {
|
|||||||
void someValueChanged({bool isBuilding = false, bool forceInvalid = false}) {
|
void someValueChanged({bool isBuilding = false, bool forceInvalid = false}) {
|
||||||
Map<String, dynamic> returnValues = values;
|
Map<String, dynamic> returnValues = values;
|
||||||
var valid = true;
|
var valid = true;
|
||||||
for (int r = 0; r < widget.items.length; r++) {
|
for (int r = 0; r < formInputs.length; r++) {
|
||||||
for (int i = 0; i < widget.items[r].length; i++) {
|
for (int i = 0; i < formInputs[r].length; i++) {
|
||||||
if (formInputs[r][i] is TextFormField) {
|
if (formInputs[r][i] is TextFormField) {
|
||||||
valid = valid && validateTextField(formInputs[r][i] as TextFormField);
|
valid = valid && validateTextField(formInputs[r][i] as TextFormField);
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:obtainium/pages/home.dart';
|
import 'package:obtainium/pages/home.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/notifications_provider.dart';
|
import 'package:obtainium/providers/notifications_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';
|
||||||
@@ -118,8 +119,6 @@ void main() async {
|
|||||||
BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
|
BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultThemeColour = Colors.deepPurple;
|
|
||||||
|
|
||||||
class Obtainium extends StatefulWidget {
|
class Obtainium extends StatefulWidget {
|
||||||
const Obtainium({super.key});
|
const Obtainium({super.key});
|
||||||
|
|
||||||
@@ -213,15 +212,13 @@ class _ObtainiumState extends State<Obtainium> {
|
|||||||
// Decide on a colour/brightness scheme based on OS and user settings
|
// Decide on a colour/brightness scheme based on OS and user settings
|
||||||
ColorScheme lightColorScheme;
|
ColorScheme lightColorScheme;
|
||||||
ColorScheme darkColorScheme;
|
ColorScheme darkColorScheme;
|
||||||
if (lightDynamic != null &&
|
if (lightDynamic != null && darkDynamic != null && settingsProvider.useMaterialYou) {
|
||||||
darkDynamic != null &&
|
|
||||||
settingsProvider.colour == ColourSettings.materialYou) {
|
|
||||||
lightColorScheme = lightDynamic.harmonized();
|
lightColorScheme = lightDynamic.harmonized();
|
||||||
darkColorScheme = darkDynamic.harmonized();
|
darkColorScheme = darkDynamic.harmonized();
|
||||||
} else {
|
} else {
|
||||||
lightColorScheme = ColorScheme.fromSeed(seedColor: defaultThemeColour);
|
lightColorScheme = ColorScheme.fromSeed(seedColor: settingsProvider.themeColor);
|
||||||
darkColorScheme = ColorScheme.fromSeed(
|
darkColorScheme = ColorScheme.fromSeed(
|
||||||
seedColor: defaultThemeColour, brightness: Brightness.dark);
|
seedColor: settingsProvider.themeColor, brightness: Brightness.dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the background and surface colors to pure black in the amoled theme
|
// set the background and surface colors to pure black in the amoled theme
|
||||||
@@ -231,6 +228,8 @@ class _ObtainiumState extends State<Obtainium> {
|
|||||||
.harmonized();
|
.harmonized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settingsProvider.useSystemFont) NativeFeatures.loadSystemFont();
|
||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Obtainium',
|
title: 'Obtainium',
|
||||||
localizationsDelegates: context.localizationDelegates,
|
localizationsDelegates: context.localizationDelegates,
|
||||||
|
@@ -882,11 +882,10 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
onPressed: selectedAppIds.isEmpty
|
onPressed: selectedAppIds.isEmpty
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
String urls =
|
String urls = '';
|
||||||
'<p>${tr('customLinkMessage')}:</p>\n\n<ul>\n';
|
|
||||||
for (var a in selectedApps) {
|
for (var a in selectedApps) {
|
||||||
urls +=
|
urls +=
|
||||||
' <li><a href="obtainium://app/${Uri.encodeComponent(jsonEncode({
|
'https://apps.obtainium.imranr.dev/redirect?r=obtainium://app/${Uri.encodeComponent(jsonEncode({
|
||||||
'id': a.id,
|
'id': a.id,
|
||||||
'url': a.url,
|
'url': a.url,
|
||||||
'author': a.author,
|
'author': a.author,
|
||||||
@@ -895,10 +894,8 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
a.preferredApkIndex,
|
a.preferredApkIndex,
|
||||||
'additionalSettings':
|
'additionalSettings':
|
||||||
jsonEncode(a.additionalSettings)
|
jsonEncode(a.additionalSettings)
|
||||||
}))}">${a.name}</a></li>\n';
|
}))}\n\n';
|
||||||
}
|
}
|
||||||
urls +=
|
|
||||||
'</ul>\n\n<p><a href="$obtainiumUrl">${tr('about')}</a></p>';
|
|
||||||
Share.share(urls,
|
Share.share(urls,
|
||||||
subject:
|
subject:
|
||||||
'Obtainium - ${tr('appsString')}');
|
'Obtainium - ${tr('appsString')}');
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:equations/equations.dart';
|
||||||
|
import 'package:flex_color_picker/flex_color_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:obtainium/components/custom_app_bar.dart';
|
import 'package:obtainium/components/custom_app_bar.dart';
|
||||||
import 'package:obtainium/components/generated_form.dart';
|
import 'package:obtainium/components/generated_form.dart';
|
||||||
@@ -12,6 +14,7 @@ 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';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
import 'package:shizuku_apk_installer/shizuku_apk_installer.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatefulWidget {
|
class SettingsPage extends StatefulWidget {
|
||||||
@@ -22,78 +25,178 @@ class SettingsPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SettingsPageState extends State<SettingsPage> {
|
class _SettingsPageState extends State<SettingsPage> {
|
||||||
|
List<int> updateIntervalNodes = [
|
||||||
|
15, 30, 60, 120, 180, 360, 720, 1440, 4320, 10080, 20160, 43200];
|
||||||
|
int updateInterval = 0;
|
||||||
|
late SplineInterpolation updateIntervalInterpolator; // 🤓
|
||||||
|
String updateIntervalLabel = tr('neverManualOnly');
|
||||||
|
bool showIntervalLabel = true;
|
||||||
|
final Map<ColorSwatch<Object>, String> colorsNameMap =
|
||||||
|
<ColorSwatch<Object>, String> {
|
||||||
|
ColorTools.createPrimarySwatch(obtainiumThemeColor): 'Obtainium'
|
||||||
|
};
|
||||||
|
|
||||||
|
void initUpdateIntervalInterpolator() {
|
||||||
|
List<InterpolationNode> nodes = [];
|
||||||
|
for (final (index, element) in updateIntervalNodes.indexed) {
|
||||||
|
nodes.add(InterpolationNode(x: index.toDouble()+1, y: element.toDouble()));
|
||||||
|
}
|
||||||
|
updateIntervalInterpolator = SplineInterpolation(nodes: nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void processIntervalSliderValue(double val) {
|
||||||
|
if (val < 0.5) {
|
||||||
|
updateInterval = 0;
|
||||||
|
updateIntervalLabel = tr('neverManualOnly');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int valInterpolated = 0;
|
||||||
|
if (val < 1) {
|
||||||
|
valInterpolated = 15;
|
||||||
|
} else {
|
||||||
|
valInterpolated = updateIntervalInterpolator.compute(val).round();
|
||||||
|
}
|
||||||
|
if (valInterpolated < 60) {
|
||||||
|
updateInterval = valInterpolated;
|
||||||
|
updateIntervalLabel = plural('minute', valInterpolated);
|
||||||
|
} else if (valInterpolated < 8 * 60) {
|
||||||
|
int valRounded = (valInterpolated / 15).floor() * 15;
|
||||||
|
updateInterval = valRounded;
|
||||||
|
updateIntervalLabel = plural('hour', valRounded ~/ 60);
|
||||||
|
int mins = valRounded % 60;
|
||||||
|
if (mins != 0) updateIntervalLabel += " ${plural('minute', mins)}";
|
||||||
|
} else if (valInterpolated < 24 * 60) {
|
||||||
|
int valRounded = (valInterpolated / 30).floor() * 30;
|
||||||
|
updateInterval = valRounded;
|
||||||
|
updateIntervalLabel = plural('hour', valRounded / 60);
|
||||||
|
} else if (valInterpolated < 7 * 24 * 60){
|
||||||
|
int valRounded = (valInterpolated / (12 * 60)).floor() * 12 * 60;
|
||||||
|
updateInterval = valRounded;
|
||||||
|
updateIntervalLabel = plural('day', valRounded / (24 * 60));
|
||||||
|
} else {
|
||||||
|
int valRounded = (valInterpolated / (24 * 60)).floor() * 24 * 60;
|
||||||
|
updateInterval = valRounded;
|
||||||
|
updateIntervalLabel = plural('day', valRounded ~/ (24 * 60));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SettingsProvider settingsProvider = context.watch<SettingsProvider>();
|
SettingsProvider settingsProvider = context.watch<SettingsProvider>();
|
||||||
SourceProvider sourceProvider = SourceProvider();
|
SourceProvider sourceProvider = SourceProvider();
|
||||||
if (settingsProvider.prefs == null) {
|
if (settingsProvider.prefs == null) settingsProvider.initializeSettings();
|
||||||
settingsProvider.initializeSettings();
|
initUpdateIntervalInterpolator();
|
||||||
|
processIntervalSliderValue(settingsProvider.updateIntervalSliderVal);
|
||||||
|
|
||||||
|
var followSystemThemeExplanation = FutureBuilder(
|
||||||
|
builder: (ctx, val) {
|
||||||
|
return ((val.data?.version.sdkInt ?? 30) < 29) ?
|
||||||
|
Text(tr('followSystemThemeExplanation'),
|
||||||
|
style: Theme.of(context).textTheme.labelSmall)
|
||||||
|
: const SizedBox.shrink();
|
||||||
|
},
|
||||||
|
future: DeviceInfoPlugin().androidInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<bool> colorPickerDialog() async {
|
||||||
|
return ColorPicker(
|
||||||
|
color: settingsProvider.themeColor,
|
||||||
|
onColorChanged: (Color color) =>
|
||||||
|
setState(() =>
|
||||||
|
settingsProvider.themeColor = color
|
||||||
|
),
|
||||||
|
actionButtons: const ColorPickerActionButtons(
|
||||||
|
okButton: true,
|
||||||
|
closeButton: true,
|
||||||
|
dialogActionButtons: false,
|
||||||
|
),
|
||||||
|
pickersEnabled: const <ColorPickerType, bool>{
|
||||||
|
ColorPickerType.both: false,
|
||||||
|
ColorPickerType.primary: false,
|
||||||
|
ColorPickerType.accent: false,
|
||||||
|
ColorPickerType.bw: false,
|
||||||
|
ColorPickerType.custom: true,
|
||||||
|
ColorPickerType.wheel: true,
|
||||||
|
},
|
||||||
|
pickerTypeLabels: <ColorPickerType, String>{
|
||||||
|
ColorPickerType.custom: tr('standard'),
|
||||||
|
ColorPickerType.wheel: tr('custom')
|
||||||
|
},
|
||||||
|
title: Text(tr('selectX', args: [tr('colour')]),
|
||||||
|
style: Theme.of(context).textTheme.titleLarge),
|
||||||
|
wheelDiameter: 192,
|
||||||
|
wheelSquareBorderRadius: 32,
|
||||||
|
width: 48,
|
||||||
|
height: 48,
|
||||||
|
borderRadius: 24,
|
||||||
|
spacing: 8,
|
||||||
|
runSpacing: 8,
|
||||||
|
enableShadesSelection: false,
|
||||||
|
customColorSwatchesAndNames: colorsNameMap,
|
||||||
|
showMaterialName: true,
|
||||||
|
showColorName: true,
|
||||||
|
materialNameTextStyle: Theme.of(context).textTheme.bodySmall,
|
||||||
|
colorNameTextStyle: Theme.of(context).textTheme.bodySmall,
|
||||||
|
copyPasteBehavior: const ColorPickerCopyPasteBehavior(longPressMenu: true),
|
||||||
|
).showPickerDialog(
|
||||||
|
context,
|
||||||
|
transitionBuilder: (BuildContext context,
|
||||||
|
Animation<double> a1, Animation<double> a2, Widget widget) {
|
||||||
|
final double curvedValue = Curves.easeInCubic.transform(a1.value);
|
||||||
|
return Transform(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
transform: Matrix4.diagonal3Values(curvedValue, curvedValue, 1),
|
||||||
|
child: Opacity(
|
||||||
|
opacity: curvedValue,
|
||||||
|
child: widget
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
transitionDuration: const Duration(milliseconds: 250),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var installMethodDropdown = DropdownButtonFormField(
|
var colorPicker = ListTile(
|
||||||
decoration: InputDecoration(labelText: tr('installMethod')),
|
dense: true,
|
||||||
value: settingsProvider.installMethod,
|
contentPadding: EdgeInsets.zero,
|
||||||
items: [
|
title: Text(tr('selectX', args: [tr('colour')])),
|
||||||
DropdownMenuItem(
|
subtitle: Text("${ColorTools.nameThatColor(settingsProvider.themeColor)} "
|
||||||
value: InstallMethodSettings.normal,
|
"(${ColorTools.materialNameAndCode(settingsProvider.themeColor,
|
||||||
child: Text(tr('normal')),
|
colorSwatchNameMap: colorsNameMap)})"),
|
||||||
),
|
trailing: ColorIndicator(
|
||||||
const DropdownMenuItem(
|
width: 40,
|
||||||
value: InstallMethodSettings.shizuku,
|
height: 40,
|
||||||
child: Text('Shizuku'),
|
borderRadius: 20,
|
||||||
),
|
color: settingsProvider.themeColor,
|
||||||
DropdownMenuItem(
|
onSelectFocus: false,
|
||||||
value: InstallMethodSettings.root,
|
onSelect: () async {
|
||||||
child: Text(tr('root')),
|
final Color colorBeforeDialog = settingsProvider.themeColor;
|
||||||
)
|
if (!(await colorPickerDialog())) {
|
||||||
],
|
setState(() {
|
||||||
onChanged: (value) {
|
settingsProvider.themeColor = colorBeforeDialog;
|
||||||
if (value != null) {
|
|
||||||
settingsProvider.installMethod = value;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
var themeDropdown = DropdownButtonFormField(
|
var useMaterialThemeSwitch = FutureBuilder(
|
||||||
decoration: InputDecoration(labelText: tr('theme')),
|
builder: (ctx, val) {
|
||||||
value: settingsProvider.theme,
|
return ((val.data?.version.sdkInt ?? 0) >= 31) ?
|
||||||
items: [
|
Row(
|
||||||
DropdownMenuItem(
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
value: ThemeSettings.dark,
|
children: [
|
||||||
child: Text(tr('dark')),
|
Flexible(child: Text(tr('useMaterialYou'))),
|
||||||
),
|
Switch(
|
||||||
DropdownMenuItem(
|
value: settingsProvider.useMaterialYou,
|
||||||
value: ThemeSettings.light,
|
|
||||||
child: Text(tr('light')),
|
|
||||||
),
|
|
||||||
DropdownMenuItem(
|
|
||||||
value: ThemeSettings.system,
|
|
||||||
child: Text(tr('followSystem')),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
if (value != null) {
|
settingsProvider.useMaterialYou = value;
|
||||||
settingsProvider.theme = value;
|
})
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var colourDropdown = DropdownButtonFormField(
|
|
||||||
decoration: InputDecoration(labelText: tr('colour')),
|
|
||||||
value: settingsProvider.colour,
|
|
||||||
items: const [
|
|
||||||
DropdownMenuItem(
|
|
||||||
value: ColourSettings.basic,
|
|
||||||
child: Text('Obtainium'),
|
|
||||||
),
|
|
||||||
DropdownMenuItem(
|
|
||||||
value: ColourSettings.materialYou,
|
|
||||||
child: Text('Material You'),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
onChanged: (value) {
|
) : const SizedBox.shrink();
|
||||||
if (value != null) {
|
},
|
||||||
settingsProvider.colour = value;
|
future: DeviceInfoPlugin().androidInfo
|
||||||
}
|
);
|
||||||
});
|
|
||||||
|
|
||||||
var sortDropdown = DropdownButtonFormField(
|
var sortDropdown = DropdownButtonFormField(
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
@@ -165,30 +268,29 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var intervalDropdown = DropdownButtonFormField(
|
var intervalSlider = Slider(
|
||||||
decoration: InputDecoration(labelText: tr('bgUpdateCheckInterval')),
|
value: settingsProvider.updateIntervalSliderVal,
|
||||||
value: settingsProvider.updateInterval,
|
max: updateIntervalNodes.length.toDouble(),
|
||||||
items: updateIntervals.map((e) {
|
divisions: updateIntervalNodes.length * 20,
|
||||||
int displayNum = (e < 60
|
label: updateIntervalLabel,
|
||||||
? e
|
onChanged: (double value) {
|
||||||
: e < 1440
|
setState(() {
|
||||||
? e / 60
|
settingsProvider.updateIntervalSliderVal = value;
|
||||||
: e / 1440)
|
processIntervalSliderValue(value);
|
||||||
.round();
|
|
||||||
String display = e == 0
|
|
||||||
? tr('neverManualOnly')
|
|
||||||
: (e < 60
|
|
||||||
? plural('minute', displayNum)
|
|
||||||
: e < 1440
|
|
||||||
? plural('hour', displayNum)
|
|
||||||
: plural('day', displayNum));
|
|
||||||
return DropdownMenuItem(value: e, child: Text(display));
|
|
||||||
}).toList(),
|
|
||||||
onChanged: (value) {
|
|
||||||
if (value != null) {
|
|
||||||
settingsProvider.updateInterval = value;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
onChangeStart: (double value) {
|
||||||
|
setState(() {
|
||||||
|
showIntervalLabel = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChangeEnd: (double value) {
|
||||||
|
setState(() {
|
||||||
|
showIntervalLabel = true;
|
||||||
|
settingsProvider.updateInterval = updateInterval;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
var sourceSpecificFields = sourceProvider.sources.map((e) {
|
var sourceSpecificFields = sourceProvider.sources.map((e) {
|
||||||
if (e.sourceConfigSettingFormItems.isNotEmpty) {
|
if (e.sourceConfigSettingFormItems.isNotEmpty) {
|
||||||
@@ -239,15 +341,19 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Theme.of(context).colorScheme.primary),
|
color: Theme.of(context).colorScheme.primary),
|
||||||
),
|
),
|
||||||
intervalDropdown,
|
//intervalDropdown,
|
||||||
|
height16,
|
||||||
|
if (showIntervalLabel) SizedBox(
|
||||||
|
child: Text("${tr('bgUpdateCheckInterval')}: $updateIntervalLabel")
|
||||||
|
) else const SizedBox(height: 16),
|
||||||
|
intervalSlider,
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
builder: (ctx, val) {
|
builder: (ctx, val) {
|
||||||
return (val.data?.version.sdkInt ?? 0) >= 30
|
return (settingsProvider.updateInterval > 0) && (((val.data?.version.sdkInt ?? 0) >= 30) || settingsProvider.useShizuku)
|
||||||
? Column(
|
? Column(
|
||||||
crossAxisAlignment:
|
crossAxisAlignment:
|
||||||
CrossAxisAlignment.start,
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
height16,
|
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
MainAxisAlignment
|
MainAxisAlignment
|
||||||
@@ -416,7 +522,34 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
})
|
})
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
installMethodDropdown,
|
height16,
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Flexible(child: Text(tr('useShizuku'))),
|
||||||
|
Switch(
|
||||||
|
value: settingsProvider.useShizuku,
|
||||||
|
onChanged: (useShizuku) {
|
||||||
|
if (useShizuku) {
|
||||||
|
ShizukuApkInstaller.checkPermission().then((resCode) {
|
||||||
|
settingsProvider.useShizuku = resCode!.startsWith('granted');
|
||||||
|
switch(resCode){
|
||||||
|
case 'binder_not_found':
|
||||||
|
showError(ObtainiumError(tr('shizukuBinderNotFound')), context);
|
||||||
|
case 'old_shizuku':
|
||||||
|
showError(ObtainiumError(tr('shizukuOld')), context);
|
||||||
|
case 'old_android_with_adb':
|
||||||
|
showError(ObtainiumError(tr('shizukuOldAndroidWithADB')), context);
|
||||||
|
case 'denied':
|
||||||
|
showError(ObtainiumError(tr('cancelled')), context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
settingsProvider.useShizuku = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
),
|
||||||
height32,
|
height32,
|
||||||
Text(
|
Text(
|
||||||
tr('sourceSpecific'),
|
tr('sourceSpecific'),
|
||||||
@@ -432,8 +565,33 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Theme.of(context).colorScheme.primary),
|
color: Theme.of(context).colorScheme.primary),
|
||||||
),
|
),
|
||||||
themeDropdown,
|
DropdownButtonFormField(
|
||||||
|
decoration: InputDecoration(labelText: tr('theme')),
|
||||||
|
value: settingsProvider.theme,
|
||||||
|
items: [
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: ThemeSettings.system,
|
||||||
|
child: Text(tr('followSystem')),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: ThemeSettings.light,
|
||||||
|
child: Text(tr('light')),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: ThemeSettings.dark,
|
||||||
|
child: Text(tr('dark')),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
settingsProvider.theme = value;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
height8,
|
||||||
|
if (settingsProvider.theme == ThemeSettings.system)
|
||||||
|
followSystemThemeExplanation,
|
||||||
height16,
|
height16,
|
||||||
|
if (settingsProvider.theme != ThemeSettings.light)
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
@@ -442,11 +600,13 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
value: settingsProvider.useBlackTheme,
|
value: settingsProvider.useBlackTheme,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settingsProvider.useBlackTheme = value;
|
settingsProvider.useBlackTheme = value;
|
||||||
})
|
}
|
||||||
],
|
)
|
||||||
|
]
|
||||||
),
|
),
|
||||||
colourDropdown,
|
height8,
|
||||||
height16,
|
useMaterialThemeSwitch,
|
||||||
|
if (!settingsProvider.useMaterialYou) colorPicker,
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@@ -460,6 +620,12 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
),
|
),
|
||||||
height16,
|
height16,
|
||||||
localeDropdown,
|
localeDropdown,
|
||||||
|
FutureBuilder(
|
||||||
|
builder: (ctx, val) {
|
||||||
|
return (val.data?.version.sdkInt ?? 0) >= 34
|
||||||
|
? Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
height16,
|
height16,
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
@@ -469,25 +635,20 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
value: settingsProvider.useSystemFont,
|
value: settingsProvider.useSystemFont,
|
||||||
onChanged: (useSystemFont) {
|
onChanged: (useSystemFont) {
|
||||||
if (useSystemFont) {
|
if (useSystemFont) {
|
||||||
NativeFeatures.loadSystemFont()
|
NativeFeatures.loadSystemFont().then((val) {
|
||||||
.then((fontLoadRes) {
|
settingsProvider.useSystemFont = true;
|
||||||
if (fontLoadRes == 'ok') {
|
|
||||||
settingsProvider.useSystemFont =
|
|
||||||
true;
|
|
||||||
} else {
|
|
||||||
showError(
|
|
||||||
ObtainiumError(tr(
|
|
||||||
'systemFontError',
|
|
||||||
args: [fontLoadRes])),
|
|
||||||
context);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
settingsProvider.useSystemFont = false;
|
settingsProvider.useSystemFont = false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
],
|
]
|
||||||
),
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink();
|
||||||
|
},
|
||||||
|
future: DeviceInfoPlugin().androidInfo),
|
||||||
height16,
|
height16,
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
@@ -34,7 +34,7 @@ import 'package:android_intent_plus/android_intent.dart';
|
|||||||
import 'package:flutter_archive/flutter_archive.dart';
|
import 'package:flutter_archive/flutter_archive.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:shared_storage/shared_storage.dart' as saf;
|
import 'package:shared_storage/shared_storage.dart' as saf;
|
||||||
import 'native_provider.dart';
|
import 'package:shizuku_apk_installer/shizuku_apk_installer.dart';
|
||||||
|
|
||||||
final pm = AndroidPackageManager();
|
final pm = AndroidPackageManager();
|
||||||
|
|
||||||
@@ -235,8 +235,9 @@ Future<File> downloadFile(
|
|||||||
var fullContentLength = response.contentLength;
|
var fullContentLength = response.contentLength;
|
||||||
if (useExisting && downloadedFile.existsSync()) {
|
if (useExisting && downloadedFile.existsSync()) {
|
||||||
var length = downloadedFile.lengthSync();
|
var length = downloadedFile.lengthSync();
|
||||||
if (fullContentLength == null) {
|
if (fullContentLength == null || !rangeFeatureEnabled) {
|
||||||
// Assume full
|
// If there is no content length reported, assume it the existing file is fully downloaded
|
||||||
|
// Also if the range feature is not supported, don't trust the content length if any (#1542)
|
||||||
client.close();
|
client.close();
|
||||||
return downloadedFile;
|
return downloadedFile;
|
||||||
} else {
|
} else {
|
||||||
@@ -291,14 +292,11 @@ Future<File> downloadFile(
|
|||||||
return s;
|
return s;
|
||||||
}).pipe(sink);
|
}).pipe(sink);
|
||||||
await sink.close();
|
await sink.close();
|
||||||
bool likelyCorruptFile = (progress ?? 0) > 101;
|
|
||||||
progress = null;
|
progress = null;
|
||||||
if (onProgress != null) {
|
if (onProgress != null) {
|
||||||
onProgress(progress);
|
onProgress(progress);
|
||||||
}
|
}
|
||||||
if (response.statusCode < 200 ||
|
if (response.statusCode < 200 || response.statusCode > 299) {
|
||||||
response.statusCode > 299 ||
|
|
||||||
likelyCorruptFile) {
|
|
||||||
tempDownloadedFile.deleteSync(recursive: true);
|
tempDownloadedFile.deleteSync(recursive: true);
|
||||||
throw response.reasonPhrase ?? tr('unexpectedError');
|
throw response.reasonPhrase ?? tr('unexpectedError');
|
||||||
}
|
}
|
||||||
@@ -392,12 +390,11 @@ class AppsProvider with ChangeNotifier {
|
|||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<File> handleAPKIDChange(App app, PackageInfo? newInfo,
|
Future<File> handleAPKIDChange(App app, PackageInfo newInfo,
|
||||||
File downloadedFile, String downloadUrl) async {
|
File downloadedFile, String downloadUrl) async {
|
||||||
// If the APK package ID is different from the App ID, it is either new (using a placeholder ID) or the ID has changed
|
// If the APK package ID is different from the App ID, it is either new (using a placeholder ID) or the ID has changed
|
||||||
// The former case should be handled (give the App its real ID), the latter is a security issue
|
// The former case should be handled (give the App its real ID), the latter is a security issue
|
||||||
var isTempIdBool = isTempId(app);
|
var isTempIdBool = isTempId(app);
|
||||||
if (newInfo != null) {
|
|
||||||
if (app.id != newInfo.packageName) {
|
if (app.id != newInfo.packageName) {
|
||||||
if (apps[app.id] != null && !isTempIdBool && !app.allowIdChange) {
|
if (apps[app.id] != null && !isTempIdBool && !app.allowIdChange) {
|
||||||
throw IDChangedError(newInfo.packageName!);
|
throw IDChangedError(newInfo.packageName!);
|
||||||
@@ -414,9 +411,6 @@ class AppsProvider with ChangeNotifier {
|
|||||||
onlyIfExists: !isTempIdBool && !idChangeWasAllowed);
|
onlyIfExists: !isTempIdBool && !idChangeWasAllowed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isTempIdBool) {
|
|
||||||
throw ObtainiumError('Could not get ID from APK');
|
|
||||||
}
|
|
||||||
return downloadedFile;
|
return downloadedFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,6 +473,10 @@ class AppsProvider with ChangeNotifier {
|
|||||||
newInfo =
|
newInfo =
|
||||||
await pm.getPackageArchiveInfo(archiveFilePath: apks.first.path);
|
await pm.getPackageArchiveInfo(archiveFilePath: apks.first.path);
|
||||||
}
|
}
|
||||||
|
if (newInfo == null) {
|
||||||
|
downloadedFile.delete();
|
||||||
|
throw ObtainiumError('Could not get ID from APK');
|
||||||
|
}
|
||||||
downloadedFile =
|
downloadedFile =
|
||||||
await handleAPKIDChange(app, newInfo, downloadedFile, downloadUrl);
|
await handleAPKIDChange(app, newInfo, downloadedFile, downloadUrl);
|
||||||
// Delete older versions of the file if any
|
// Delete older versions of the file if any
|
||||||
@@ -509,9 +507,6 @@ class AppsProvider with ChangeNotifier {
|
|||||||
.isNotEmpty;
|
.isNotEmpty;
|
||||||
|
|
||||||
Future<bool> canInstallSilently(App app) async {
|
Future<bool> canInstallSilently(App app) async {
|
||||||
if (app.id == obtainiumId) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!settingsProvider.enableBackgroundUpdates) {
|
if (!settingsProvider.enableBackgroundUpdates) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -519,8 +514,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (app.apkUrls.length > 1) {
|
if (app.apkUrls.length > 1) {
|
||||||
// Manual API selection means silent install is not possible
|
return false; // Manual API selection means silent install is not possible
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var osInfo = await DeviceInfoPlugin().androidInfo;
|
var osInfo = await DeviceInfoPlugin().androidInfo;
|
||||||
@@ -531,20 +525,30 @@ class AppsProvider with ChangeNotifier {
|
|||||||
?.installingPackageName
|
?.installingPackageName
|
||||||
: (await pm.getInstallerPackageName(packageName: app.id));
|
: (await pm.getInstallerPackageName(packageName: app.id));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Probably not installed - ignore
|
return false; // App probably not installed
|
||||||
}
|
|
||||||
if (installerPackageName != obtainiumId) {
|
|
||||||
// If we did not install the app (or it isn't installed), silent install is not possible
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int? targetSDK =
|
int? targetSDK =
|
||||||
(await getInstalledInfo(app.id))?.applicationInfo?.targetSdkVersion;
|
(await getInstalledInfo(app.id))?.applicationInfo?.targetSdkVersion;
|
||||||
|
// The APK should target a new enough API
|
||||||
|
// https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(int)
|
||||||
|
if (!(targetSDK != null && targetSDK >= (osInfo.version.sdkInt - 3))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// The OS must also be new enough and the APK should target a new enough API
|
if (settingsProvider.useShizuku) {
|
||||||
return osInfo.version.sdkInt >= 31 &&
|
return true;
|
||||||
targetSDK != null &&
|
}
|
||||||
targetSDK >= // https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(int)
|
|
||||||
(osInfo.version.sdkInt - 3);
|
if (app.id == obtainiumId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (installerPackageName != obtainiumId) {
|
||||||
|
// If we did not install the app, silent install is not possible
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// The OS must also be new enough
|
||||||
|
return osInfo.version.sdkInt >= 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> waitForUserToReturnToForeground(BuildContext context) async {
|
Future<void> waitForUserToReturnToForeground(BuildContext context) async {
|
||||||
@@ -568,7 +572,8 @@ class AppsProvider with ChangeNotifier {
|
|||||||
|
|
||||||
Future<bool> installXApkDir(
|
Future<bool> installXApkDir(
|
||||||
DownloadedXApkDir dir, BuildContext? firstTimeWithContext,
|
DownloadedXApkDir dir, BuildContext? firstTimeWithContext,
|
||||||
{bool needsBGWorkaround = false}) async {
|
{bool needsBGWorkaround = false,
|
||||||
|
bool shizukuPretendToBeGooglePlay = false}) async {
|
||||||
// We don't know which APKs in an XAPK are supported by the user's device
|
// We don't know which APKs in an XAPK are supported by the user's device
|
||||||
// So we try installing all of them and assume success if at least one installed
|
// So we try installing all of them and assume success if at least one installed
|
||||||
// If 0 APKs installed, throw the first install error encountered
|
// If 0 APKs installed, throw the first install error encountered
|
||||||
@@ -583,7 +588,8 @@ class AppsProvider with ChangeNotifier {
|
|||||||
somethingInstalled = somethingInstalled ||
|
somethingInstalled = somethingInstalled ||
|
||||||
await installApk(
|
await installApk(
|
||||||
DownloadedApk(dir.appId, file), firstTimeWithContext,
|
DownloadedApk(dir.appId, file), firstTimeWithContext,
|
||||||
needsBGWorkaround: needsBGWorkaround);
|
needsBGWorkaround: needsBGWorkaround,
|
||||||
|
shizukuPretendToBeGooglePlay: shizukuPretendToBeGooglePlay);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logs.add(
|
logs.add(
|
||||||
'Could not install APK from XAPK \'${file.path}\': ${e.toString()}');
|
'Could not install APK from XAPK \'${file.path}\': ${e.toString()}');
|
||||||
@@ -606,7 +612,8 @@ class AppsProvider with ChangeNotifier {
|
|||||||
|
|
||||||
Future<bool> installApk(
|
Future<bool> installApk(
|
||||||
DownloadedApk file, BuildContext? firstTimeWithContext,
|
DownloadedApk file, BuildContext? firstTimeWithContext,
|
||||||
{bool needsBGWorkaround = false}) async {
|
{bool needsBGWorkaround = false,
|
||||||
|
bool shizukuPretendToBeGooglePlay = false}) async {
|
||||||
if (firstTimeWithContext != null &&
|
if (firstTimeWithContext != null &&
|
||||||
settingsProvider.beforeNewInstallsShareToAppVerifier &&
|
settingsProvider.beforeNewInstallsShareToAppVerifier &&
|
||||||
(await getInstalledInfo('dev.soupslurpr.appverifier')) != null) {
|
(await getInstalledInfo('dev.soupslurpr.appverifier')) != null) {
|
||||||
@@ -634,8 +641,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
!(await canDowngradeApps())) {
|
!(await canDowngradeApps())) {
|
||||||
throw DowngradeError();
|
throw DowngradeError();
|
||||||
}
|
}
|
||||||
if (needsBGWorkaround &&
|
if (needsBGWorkaround) {
|
||||||
settingsProvider.installMethod == InstallMethodSettings.normal) {
|
|
||||||
// The below 'await' will never return if we are in a background process
|
// The below 'await' will never return if we are in a background process
|
||||||
// To work around this, we should assume the install will be successful
|
// To work around this, we should assume the install will be successful
|
||||||
// So we update the app's installed version first as we will never get to the later code
|
// So we update the app's installed version first as we will never get to the later code
|
||||||
@@ -647,20 +653,12 @@ class AppsProvider with ChangeNotifier {
|
|||||||
attemptToCorrectInstallStatus: false);
|
attemptToCorrectInstallStatus: false);
|
||||||
}
|
}
|
||||||
int? code;
|
int? code;
|
||||||
switch (settingsProvider.installMethod) {
|
if (!settingsProvider.useShizuku) {
|
||||||
case InstallMethodSettings.normal:
|
|
||||||
code = await AndroidPackageInstaller.installApk(
|
|
||||||
apkFilePath: file.file.path);
|
|
||||||
case InstallMethodSettings.shizuku:
|
|
||||||
code = (await NativeFeatures.installWithShizuku(
|
|
||||||
apkFileUri: file.file.uri.toString()))
|
|
||||||
? 0
|
|
||||||
: 1;
|
|
||||||
case InstallMethodSettings.root:
|
|
||||||
code =
|
code =
|
||||||
(await NativeFeatures.installWithRoot(apkFilePath: file.file.path))
|
await AndroidPackageInstaller.installApk(apkFilePath: file.file.path);
|
||||||
? 0
|
} else {
|
||||||
: 1;
|
code = await ShizukuApkInstaller.installAPK(file.file.uri.toString(),
|
||||||
|
shizukuPretendToBeGooglePlay ? "com.android.vending" : "");
|
||||||
}
|
}
|
||||||
bool installed = false;
|
bool installed = false;
|
||||||
if (code != null && code != 0 && code != 3) {
|
if (code != null && code != 0 && code != 3) {
|
||||||
@@ -718,8 +716,8 @@ class AppsProvider with ChangeNotifier {
|
|||||||
List<String> archs = (await DeviceInfoPlugin().androidInfo).supportedAbis;
|
List<String> archs = (await DeviceInfoPlugin().androidInfo).supportedAbis;
|
||||||
|
|
||||||
if (urlsToSelectFrom.length > 1 && context != null) {
|
if (urlsToSelectFrom.length > 1 && context != null) {
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
appFileUrl = await showDialog(
|
appFileUrl = await showDialog(
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext ctx) {
|
builder: (BuildContext ctx) {
|
||||||
return AppFilePicker(
|
return AppFilePicker(
|
||||||
@@ -739,10 +737,9 @@ class AppsProvider with ChangeNotifier {
|
|||||||
if (appFileUrl != null &&
|
if (appFileUrl != null &&
|
||||||
getHost(appFileUrl.value) != getHost(app.url) &&
|
getHost(appFileUrl.value) != getHost(app.url) &&
|
||||||
context != null) {
|
context != null) {
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
if (!(settingsProvider.hideAPKOriginWarning) &&
|
if (!(settingsProvider.hideAPKOriginWarning) &&
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
await showDialog(
|
await showDialog(
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext ctx) {
|
builder: (BuildContext ctx) {
|
||||||
return APKOriginWarningDialog(
|
return APKOriginWarningDialog(
|
||||||
@@ -830,25 +827,23 @@ class AppsProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
id = downloadedFile?.appId ?? downloadedDir!.appId;
|
id = downloadedFile?.appId ?? downloadedDir!.appId;
|
||||||
bool willBeSilent = await canInstallSilently(apps[id]!.app);
|
bool willBeSilent = await canInstallSilently(apps[id]!.app);
|
||||||
switch (settingsProvider.installMethod) {
|
if (!settingsProvider.useShizuku) {
|
||||||
case InstallMethodSettings.normal:
|
if (!(await settingsProvider.getInstallPermission(enforce: false))) {
|
||||||
if (!(await settingsProvider.getInstallPermission(
|
|
||||||
enforce: false))) {
|
|
||||||
throw ObtainiumError(tr('cancelled'));
|
throw ObtainiumError(tr('cancelled'));
|
||||||
}
|
}
|
||||||
case InstallMethodSettings.shizuku:
|
} else {
|
||||||
int code = await NativeFeatures.checkPermissionShizuku();
|
switch ((await ShizukuApkInstaller.checkPermission())!) {
|
||||||
if (code == -1) {
|
case 'binder_not_found':
|
||||||
throw ObtainiumError(tr('shizukuBinderNotFound'));
|
throw ObtainiumError(tr('shizukuBinderNotFound'));
|
||||||
} else if (code == 0) {
|
case 'old_shizuku':
|
||||||
throw ObtainiumError(tr('cancelled'));
|
throw ObtainiumError(tr('shizukuOld'));
|
||||||
}
|
case 'old_android_with_adb':
|
||||||
case InstallMethodSettings.root:
|
throw ObtainiumError(tr('shizukuOldAndroidWithADB'));
|
||||||
if (!(await NativeFeatures.checkPermissionRoot())) {
|
case 'denied':
|
||||||
throw ObtainiumError(tr('cancelled'));
|
throw ObtainiumError(tr('cancelled'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!willBeSilent && context != null) {
|
if (!willBeSilent && context != null && !settingsProvider.useShizuku) {
|
||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
await waitForUserToReturnToForeground(context);
|
await waitForUserToReturnToForeground(context);
|
||||||
}
|
}
|
||||||
@@ -859,27 +854,47 @@ class AppsProvider with ChangeNotifier {
|
|||||||
bool sayInstalled = true;
|
bool sayInstalled = true;
|
||||||
var contextIfNewInstall =
|
var contextIfNewInstall =
|
||||||
apps[id]?.installedInfo == null ? context : null;
|
apps[id]?.installedInfo == null ? context : null;
|
||||||
|
bool needBGWorkaround =
|
||||||
|
willBeSilent && context == null && !settingsProvider.useShizuku;
|
||||||
if (downloadedFile != null) {
|
if (downloadedFile != null) {
|
||||||
if (willBeSilent && context == null) {
|
if (needBGWorkaround) {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
installApk(downloadedFile, contextIfNewInstall,
|
installApk(downloadedFile, contextIfNewInstall,
|
||||||
needsBGWorkaround: true);
|
needsBGWorkaround: true);
|
||||||
} else {
|
} else {
|
||||||
sayInstalled =
|
// ignore: use_build_context_synchronously
|
||||||
await installApk(downloadedFile, contextIfNewInstall);
|
sayInstalled = await installApk(
|
||||||
|
downloadedFile, contextIfNewInstall,
|
||||||
|
shizukuPretendToBeGooglePlay:
|
||||||
|
apps[id]!.app.additionalSettings[
|
||||||
|
'shizukuPretendToBeGooglePlay'] ==
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (willBeSilent && context == null) {
|
if (needBGWorkaround) {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
installXApkDir(downloadedDir!, contextIfNewInstall,
|
installXApkDir(downloadedDir!, contextIfNewInstall,
|
||||||
needsBGWorkaround: true);
|
needsBGWorkaround: true);
|
||||||
} else {
|
} else {
|
||||||
sayInstalled =
|
// ignore: use_build_context_synchronously
|
||||||
await installXApkDir(downloadedDir!, contextIfNewInstall);
|
sayInstalled = await installXApkDir(
|
||||||
|
downloadedDir!, contextIfNewInstall,
|
||||||
|
shizukuPretendToBeGooglePlay:
|
||||||
|
apps[id]!.app.additionalSettings[
|
||||||
|
'shizukuPretendToBeGooglePlay'] ==
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (willBeSilent && context == null) {
|
if (willBeSilent && context == null) {
|
||||||
|
if (!settingsProvider.useShizuku) {
|
||||||
notificationsProvider?.notify(SilentUpdateAttemptNotification(
|
notificationsProvider?.notify(SilentUpdateAttemptNotification(
|
||||||
[apps[id]!.app],
|
[apps[id]!.app],
|
||||||
id: id.hashCode));
|
id: id.hashCode));
|
||||||
|
} else {
|
||||||
|
notificationsProvider?.notify(SilentUpdateNotification(
|
||||||
|
[apps[id]!.app], sayInstalled,
|
||||||
|
id: id.hashCode));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sayInstalled) {
|
if (sayInstalled) {
|
||||||
installedIds.add(id);
|
installedIds.add(id);
|
||||||
@@ -1712,7 +1727,7 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
|
|||||||
int maxRetryWaitSeconds = 5;
|
int maxRetryWaitSeconds = 5;
|
||||||
|
|
||||||
var netResult = await (Connectivity().checkConnectivity());
|
var netResult = await (Connectivity().checkConnectivity());
|
||||||
if (netResult == ConnectivityResult.none) {
|
if (netResult.contains(ConnectivityResult.none)) {
|
||||||
logs.add('BG update task: No network.');
|
logs.add('BG update task: No network.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1749,8 +1764,8 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
|
|||||||
|
|
||||||
var networkRestricted = false;
|
var networkRestricted = false;
|
||||||
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
|
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
|
||||||
networkRestricted = (netResult != ConnectivityResult.wifi) &&
|
networkRestricted = !netResult.contains(ConnectivityResult.wifi) &&
|
||||||
(netResult != ConnectivityResult.ethernet);
|
!netResult.contains(ConnectivityResult.ethernet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toCheck.isNotEmpty) {
|
if (toCheck.isNotEmpty) {
|
||||||
@@ -1794,8 +1809,8 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
|
|||||||
var networkRestricted = false;
|
var networkRestricted = false;
|
||||||
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
|
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
|
||||||
var netResult = await (Connectivity().checkConnectivity());
|
var netResult = await (Connectivity().checkConnectivity());
|
||||||
networkRestricted = (netResult != ConnectivityResult.wifi) &&
|
networkRestricted = !netResult.contains(ConnectivityResult.wifi) &&
|
||||||
(netResult != ConnectivityResult.ethernet);
|
!netResult.contains(ConnectivityResult.ethernet);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@@ -1,75 +1,22 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:android_system_font/android_system_font.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class NativeFeatures {
|
class NativeFeatures {
|
||||||
static const MethodChannel _channel = MethodChannel('native');
|
|
||||||
static bool _systemFontLoaded = false;
|
static bool _systemFontLoaded = false;
|
||||||
static bool _callbacksApplied = false;
|
|
||||||
static int _resPermShizuku = -2; // not set
|
|
||||||
|
|
||||||
static Future<ByteData> _readFileBytes(String path) async {
|
static Future<ByteData> _readFileBytes(String path) async {
|
||||||
var file = File(path);
|
var bytes = await File(path).readAsBytes();
|
||||||
var bytes = await file.readAsBytes();
|
|
||||||
return ByteData.view(bytes.buffer);
|
return ByteData.view(bytes.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future _handleCalls(MethodCall call) async {
|
static Future loadSystemFont() async {
|
||||||
if (call.method == 'resPermShizuku') {
|
if (_systemFontLoaded) return;
|
||||||
_resPermShizuku = call.arguments['res'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future _waitWhile(bool Function() test,
|
|
||||||
[Duration pollInterval = const Duration(milliseconds: 250)]) {
|
|
||||||
var completer = Completer();
|
|
||||||
check() {
|
|
||||||
if (test()) {
|
|
||||||
Timer(pollInterval, check);
|
|
||||||
} else {
|
|
||||||
completer.complete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
check();
|
|
||||||
return completer.future;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<String> loadSystemFont() async {
|
|
||||||
if (_systemFontLoaded) { return "ok"; }
|
|
||||||
var getFontRes = await _channel.invokeMethod('getSystemFont');
|
|
||||||
if (getFontRes[0] != '/') { return getFontRes; } // Error
|
|
||||||
var fontLoader = FontLoader('SystemFont');
|
var fontLoader = FontLoader('SystemFont');
|
||||||
fontLoader.addFont(_readFileBytes(getFontRes));
|
var fontFilePath = await AndroidSystemFont().getFilePath();
|
||||||
await fontLoader.load();
|
fontLoader.addFont(_readFileBytes(fontFilePath!));
|
||||||
|
fontLoader.load();
|
||||||
_systemFontLoaded = true;
|
_systemFontLoaded = true;
|
||||||
return "ok";
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<int> checkPermissionShizuku() async {
|
|
||||||
if (!_callbacksApplied) {
|
|
||||||
_channel.setMethodCallHandler(_handleCalls);
|
|
||||||
_callbacksApplied = true;
|
|
||||||
}
|
|
||||||
int res = await _channel.invokeMethod('checkPermissionShizuku');
|
|
||||||
if (res == -2) {
|
|
||||||
await _waitWhile(() => _resPermShizuku == -2);
|
|
||||||
res = _resPermShizuku;
|
|
||||||
_resPermShizuku = -2;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<bool> checkPermissionRoot() async {
|
|
||||||
return await _channel.invokeMethod('checkPermissionRoot');
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<bool> installWithShizuku({required String apkFileUri}) async {
|
|
||||||
return await _channel.invokeMethod(
|
|
||||||
'installWithShizuku', {'apkFileUri': apkFileUri});
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<bool> installWithRoot({required String apkFilePath}) async {
|
|
||||||
return await _channel.invokeMethod(
|
|
||||||
'installWithRoot', {'apkFilePath': apkFilePath});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,20 +41,26 @@ class UpdateNotification extends ObtainiumNotification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SilentUpdateNotification extends ObtainiumNotification {
|
class SilentUpdateNotification extends ObtainiumNotification {
|
||||||
SilentUpdateNotification(List<App> updates, {int? id})
|
SilentUpdateNotification(List<App> updates, bool succeeded, {int? id})
|
||||||
: super(
|
: super(
|
||||||
id ?? 3,
|
id ?? 3,
|
||||||
tr('appsUpdated'),
|
succeeded
|
||||||
|
? tr('appsUpdated')
|
||||||
|
: tr('appsNotUpdated'),
|
||||||
'',
|
'',
|
||||||
'APPS_UPDATED',
|
'APPS_UPDATED',
|
||||||
tr('appsUpdatedNotifChannel'),
|
tr('appsUpdatedNotifChannel'),
|
||||||
tr('appsUpdatedNotifDescription'),
|
tr('appsUpdatedNotifDescription'),
|
||||||
Importance.defaultImportance) {
|
Importance.defaultImportance) {
|
||||||
message = updates.length == 1
|
message = updates.length == 1
|
||||||
? tr('xWasUpdatedToY',
|
? tr(succeeded
|
||||||
|
? 'xWasUpdatedToY'
|
||||||
|
: 'xWasNotUpdatedToY',
|
||||||
args: [updates[0].finalName, updates[0].latestVersion])
|
args: [updates[0].finalName, updates[0].latestVersion])
|
||||||
: plural('xAndNMoreUpdatesInstalled', updates.length - 1,
|
: plural(succeeded
|
||||||
args: [updates[0].finalName, (updates.length - 1).toString()]);
|
? 'xAndNMoreUpdatesInstalled'
|
||||||
|
: "xAndNMoreUpdatesFailed",
|
||||||
|
updates.length - 1, args: [updates[0].finalName, (updates.length - 1).toString()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,41 +17,14 @@ import 'package:shared_storage/shared_storage.dart' as saf;
|
|||||||
String obtainiumTempId = 'imranr98_obtainium_${GitHub().hosts[0]}';
|
String obtainiumTempId = 'imranr98_obtainium_${GitHub().hosts[0]}';
|
||||||
String obtainiumId = 'dev.imranr.obtainium';
|
String obtainiumId = 'dev.imranr.obtainium';
|
||||||
String obtainiumUrl = 'https://github.com/ImranR98/Obtainium';
|
String obtainiumUrl = 'https://github.com/ImranR98/Obtainium';
|
||||||
|
Color obtainiumThemeColor = const Color(0xFF6438B5);
|
||||||
enum InstallMethodSettings { normal, shizuku, root }
|
|
||||||
|
|
||||||
enum ThemeSettings { system, light, dark }
|
enum ThemeSettings { system, light, dark }
|
||||||
|
|
||||||
enum ColourSettings { basic, materialYou }
|
|
||||||
|
|
||||||
enum SortColumnSettings { added, nameAuthor, authorName, releaseDate }
|
enum SortColumnSettings { added, nameAuthor, authorName, releaseDate }
|
||||||
|
|
||||||
enum SortOrderSettings { ascending, descending }
|
enum SortOrderSettings { ascending, descending }
|
||||||
|
|
||||||
const maxAPIRateLimitMinutes = 30;
|
|
||||||
const minUpdateIntervalMinutes = maxAPIRateLimitMinutes + 30;
|
|
||||||
const maxUpdateIntervalMinutes = 43200;
|
|
||||||
List<int> updateIntervals = [
|
|
||||||
15,
|
|
||||||
30,
|
|
||||||
60,
|
|
||||||
120,
|
|
||||||
180,
|
|
||||||
360,
|
|
||||||
720,
|
|
||||||
1440,
|
|
||||||
4320,
|
|
||||||
10080,
|
|
||||||
20160,
|
|
||||||
43200,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
.where((element) =>
|
|
||||||
(element >= minUpdateIntervalMinutes &&
|
|
||||||
element <= maxUpdateIntervalMinutes) ||
|
|
||||||
element == 0)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
class SettingsProvider with ChangeNotifier {
|
class SettingsProvider with ChangeNotifier {
|
||||||
SharedPreferences? prefs;
|
SharedPreferences? prefs;
|
||||||
String? defaultAppDir;
|
String? defaultAppDir;
|
||||||
@@ -75,13 +48,12 @@ class SettingsProvider with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallMethodSettings get installMethod {
|
bool get useShizuku{
|
||||||
return InstallMethodSettings.values[
|
return prefs?.getBool('useShizuku') ?? false;
|
||||||
prefs?.getInt('installMethod') ?? InstallMethodSettings.normal.index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set installMethod(InstallMethodSettings t) {
|
set useShizuku(bool useShizuku) {
|
||||||
prefs?.setInt('installMethod', t.index);
|
prefs?.setBool('useShizuku', useShizuku);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,13 +67,23 @@ class SettingsProvider with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
ColourSettings get colour {
|
Color get themeColor {
|
||||||
return ColourSettings
|
int? colorCode = prefs?.getInt('themeColor');
|
||||||
.values[prefs?.getInt('colour') ?? ColourSettings.basic.index];
|
return (colorCode != null) ?
|
||||||
|
Color(colorCode) : obtainiumThemeColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
set colour(ColourSettings t) {
|
set themeColor(Color themeColor) {
|
||||||
prefs?.setInt('colour', t.index);
|
prefs?.setInt('themeColor', themeColor.value);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get useMaterialYou {
|
||||||
|
return prefs?.getBool('useMaterialYou') ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set useMaterialYou(bool useMaterialYou) {
|
||||||
|
prefs?.setBool('useMaterialYou', useMaterialYou);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,21 +97,20 @@ class SettingsProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int get updateInterval {
|
int get updateInterval {
|
||||||
var min = prefs?.getInt('updateInterval') ?? 360;
|
return prefs?.getInt('updateInterval') ?? 360;
|
||||||
if (!updateIntervals.contains(min)) {
|
|
||||||
var temp = updateIntervals[0];
|
|
||||||
for (var i in updateIntervals) {
|
|
||||||
if (min > i && i != 0) {
|
|
||||||
temp = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
min = temp;
|
|
||||||
}
|
|
||||||
return min;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set updateInterval(int min) {
|
set updateInterval(int min) {
|
||||||
prefs?.setInt('updateInterval', (min < 15 && min != 0) ? 15 : min);
|
prefs?.setInt('updateInterval', min);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
double get updateIntervalSliderVal {
|
||||||
|
return prefs?.getDouble('updateIntervalSliderVal') ?? 6.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
set updateIntervalSliderVal(double val) {
|
||||||
|
prefs?.setDouble('updateIntervalSliderVal', val);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -521,6 +521,11 @@ abstract class AppSource {
|
|||||||
label: tr('autoApkFilterByArch'), defaultValue: true)
|
label: tr('autoApkFilterByArch'), defaultValue: true)
|
||||||
],
|
],
|
||||||
[GeneratedFormTextField('appName', label: tr('appName'), required: false)],
|
[GeneratedFormTextField('appName', label: tr('appName'), required: false)],
|
||||||
|
[
|
||||||
|
GeneratedFormSwitch('shizukuPretendToBeGooglePlay',
|
||||||
|
label: tr('shizukuPretendToBeGooglePlay'),
|
||||||
|
defaultValue: false)
|
||||||
|
],
|
||||||
[
|
[
|
||||||
GeneratedFormSwitch('exemptFromBackgroundUpdates',
|
GeneratedFormSwitch('exemptFromBackgroundUpdates',
|
||||||
label: tr('exemptFromBackgroundUpdates'))
|
label: tr('exemptFromBackgroundUpdates'))
|
||||||
|
164
pubspec.lock
164
pubspec.lock
@@ -5,10 +5,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: android_intent_plus
|
name: android_intent_plus
|
||||||
sha256: e92d14009f3f6ebafca6a601958aaebb793559fb03a1961fe3c5596db95af2cb
|
sha256: "2bfdbee8d65e7c26f88b66f0a91f2863da4d3596d8a658b4162c8de5cf04b074"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.1"
|
version: "5.0.2"
|
||||||
android_package_installer:
|
android_package_installer:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -26,6 +26,15 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.1"
|
version: "0.7.1"
|
||||||
|
android_system_font:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "."
|
||||||
|
ref: master
|
||||||
|
resolved-ref: "355f897e92a58a803f91d9270d389d9ec40ba550"
|
||||||
|
url: "https://github.com/re7gog/android_system_font"
|
||||||
|
source: git
|
||||||
|
version: "1.0.0"
|
||||||
animations:
|
animations:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -54,10 +63,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.5.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -70,10 +79,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: background_fetch
|
name: background_fetch
|
||||||
sha256: dbffec0317ccdef6e2014cb543e147f52441e29c4fcb53dfd23558c4d92ddece
|
sha256: "81d0d4eeecd17c971335438a5a55554c8302f479f92c7f7bc7f147f75d3f6074"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.3"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -126,10 +135,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: connectivity_plus
|
name: connectivity_plus
|
||||||
sha256: e9feae83b1849f61bad9f6f33ee00646e3410d54ce0821e02f262f9901dad3c9
|
sha256: db7a4e143dc72cc3cb2044ef9b052a7ebfe729513e6a82943bc3526f784365b8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.1"
|
version: "6.0.3"
|
||||||
connectivity_plus_platform_interface:
|
connectivity_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -174,10 +183,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
|
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "1.0.8"
|
||||||
dbus:
|
dbus:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -190,10 +199,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: device_info_plus
|
name: device_info_plus
|
||||||
sha256: "50fb435ed30c6d2525cbfaaa0f46851ea6131315f213c0d921b0e407b34e3b84"
|
sha256: eead12d1a1ed83d8283ab4c2f3fca23ac4082f29f25f29dff0f758f57d06ec91
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.1"
|
version: "10.1.0"
|
||||||
device_info_plus_platform_interface:
|
device_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -214,10 +223,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: easy_localization
|
name: easy_localization
|
||||||
sha256: c145aeb6584aedc7c862ab8c737c3277788f47488bfdf9bae0fe112bd0a4789c
|
sha256: "432698c31a488dd64c56d4759f20d04844baba5e9e4f2cb1abb9676257918b17"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.5"
|
version: "3.0.6"
|
||||||
easy_logger:
|
easy_logger:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -226,6 +235,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.2"
|
version: "0.0.2"
|
||||||
|
equations:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: equations
|
||||||
|
sha256: ae30e977d601e19aa1fc3409736c5eac01559d1d653a4c30141fbc4e86aa605c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.2"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -254,10 +271,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: file_picker
|
name: file_picker
|
||||||
sha256: d1d0ac3966b36dc3e66eeefb40280c17feb87fa2099c6e22e6a1fc959327bd03
|
sha256: "45c70b43df893027e441a6fa0aacc8f484fb9f9c60c746dc8f1dc4f774cf55cd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.0+1"
|
version: "8.0.2"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -266,6 +283,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
flex_color_picker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flex_color_picker
|
||||||
|
sha256: "5c846437069fb7afdd7ade6bf37e628a71d2ab0787095ddcb1253bf9345d5f3a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.4.1"
|
||||||
|
flex_seed_scheme:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flex_seed_scheme
|
||||||
|
sha256: "4cee2f1d07259f77e8b36f4ec5f35499d19e74e17c7dce5b819554914082bc01"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -275,10 +308,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_archive
|
name: flutter_archive
|
||||||
sha256: "004132780d382df5171589ab793e2efc9c3eef570fe72d78b4ccfbfbe52762ae"
|
sha256: "5ca235f304c12bf468979235f400f79846d204169d715939e39197106f5fc970"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.0"
|
version: "6.0.3"
|
||||||
flutter_fgbg:
|
flutter_fgbg:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -307,10 +340,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_local_notifications
|
name: flutter_local_notifications
|
||||||
sha256: f9a05409385b77b06c18f200a41c7c2711ebf7415669350bb0f8474c07bd40d1
|
sha256: "8cdc719114ab1c86c64bb7a86d3a679674c3637edd229e3a994797d4a1504ce4"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "17.0.0"
|
version: "17.1.0"
|
||||||
flutter_local_notifications_linux:
|
flutter_local_notifications_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -323,10 +356,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_local_notifications_platform_interface
|
name: flutter_local_notifications_platform_interface
|
||||||
sha256: "7cf643d6d5022f3baed0be777b0662cce5919c0a7b86e700299f22dc4ae660ef"
|
sha256: "340abf67df238f7f0ef58f4a26d2a83e1ab74c77ab03cd2b2d5018ac64db30b7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0+1"
|
version: "7.1.0"
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -336,18 +369,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_markdown
|
name: flutter_markdown
|
||||||
sha256: "31c12de79262b5431c5492e9c89948aa789158435f707d3519a7fdef6af28af7"
|
sha256: "9921f9deda326f8a885e202b1e35237eadfc1345239a0f6f0f1ff287e047547f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.22+1"
|
version: "0.7.1"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_plugin_android_lifecycle
|
name: flutter_plugin_android_lifecycle
|
||||||
sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
|
sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.17"
|
version: "2.0.19"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -362,10 +395,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fluttertoast
|
name: fluttertoast
|
||||||
sha256: dfdde255317af381bfc1c486ed968d5a43a2ded9c931e87cbecd88767d6a71c1
|
sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.2.4"
|
version: "8.2.5"
|
||||||
|
fraction:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fraction
|
||||||
|
sha256: "09e9504c9177bbd77df56e5d147abfbb3b43360e64bf61510059c14d6a82d524"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.2"
|
||||||
gtk:
|
gtk:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -538,18 +579,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
|
sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.3"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
|
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.2.4"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -634,10 +675,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: petitparser
|
name: petitparser
|
||||||
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
|
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.2"
|
version: "5.4.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -658,10 +699,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pointycastle
|
name: pointycastle
|
||||||
sha256: "70fe966348fe08c34bf929582f1d8247d9d9408130723206472b4687227e4333"
|
sha256: "79fbafed02cfdbe85ef3fd06c7f4bc2cbcba0177e61b765264853d4253b21744"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.8.0"
|
version: "3.9.0"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -674,34 +715,34 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: share_plus
|
name: share_plus
|
||||||
sha256: "05ec043470319bfbabe0adbc90d3a84cbff0426b9d9f3a6e2ad3e131fa5fa629"
|
sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.2"
|
version: "9.0.0"
|
||||||
share_plus_platform_interface:
|
share_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: share_plus_platform_interface
|
name: share_plus_platform_interface
|
||||||
sha256: "251eb156a8b5fa9ce033747d73535bf53911071f8d3b6f4f0b578505ce0d4496"
|
sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.0"
|
version: "4.0.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
|
sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.2.3"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
|
sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.2"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -750,6 +791,15 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.1"
|
version: "0.8.1"
|
||||||
|
shizuku_apk_installer:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "."
|
||||||
|
ref: master
|
||||||
|
resolved-ref: "25acc02612c2e0fcae40d312e047ac48106f8f6b"
|
||||||
|
url: "https://github.com/re7gog/shizuku_apk_installer"
|
||||||
|
source: git
|
||||||
|
version: "0.0.1"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -855,18 +905,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: url_launcher
|
name: url_launcher
|
||||||
sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
|
sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.2.5"
|
version: "6.2.6"
|
||||||
url_launcher_android:
|
url_launcher_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_android
|
name: url_launcher_android
|
||||||
sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745
|
sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.0"
|
version: "6.3.1"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -903,10 +953,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_web
|
name: url_launcher_web
|
||||||
sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d"
|
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.1"
|
||||||
url_launcher_windows:
|
url_launcher_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -919,10 +969,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: uuid
|
name: uuid
|
||||||
sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8
|
sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.3.3"
|
version: "4.4.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -991,10 +1041,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32_registry
|
name: win32_registry
|
||||||
sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a"
|
sha256: "10589e0d7f4e053f2c61023a31c9ce01146656a70b7b7f0828c0b46d7da2a9bb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.1.3"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1007,10 +1057,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.5.0"
|
version: "6.3.0"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1020,5 +1070,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.0 <4.0.0"
|
dart: ">=3.3.3 <4.0.0"
|
||||||
flutter: ">=3.19.0"
|
flutter: ">=3.19.0"
|
||||||
|
16
pubspec.yaml
16
pubspec.yaml
@@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.1.2+2259
|
version: 1.1.6+2263
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.0 <4.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
@@ -56,11 +56,11 @@ dependencies:
|
|||||||
url: https://github.com/ImranR98/android_package_installer
|
url: https://github.com/ImranR98/android_package_installer
|
||||||
ref: main
|
ref: main
|
||||||
android_package_manager: ^0.7.0
|
android_package_manager: ^0.7.0
|
||||||
share_plus: ^8.0.2
|
share_plus: ^9.0.0
|
||||||
sqflite: ^2.2.0+3
|
sqflite: ^2.2.0+3
|
||||||
easy_localization: ^3.0.1
|
easy_localization: ^3.0.1
|
||||||
android_intent_plus: ^5.0.1
|
android_intent_plus: ^5.0.1
|
||||||
flutter_markdown: ^0.6.14
|
flutter_markdown: ^0.7.1
|
||||||
flutter_archive: ^6.0.0
|
flutter_archive: ^6.0.0
|
||||||
hsluv: ^1.1.3
|
hsluv: ^1.1.3
|
||||||
connectivity_plus: ^6.0.1
|
connectivity_plus: ^6.0.1
|
||||||
@@ -68,6 +68,16 @@ dependencies:
|
|||||||
crypto: ^3.0.3
|
crypto: ^3.0.3
|
||||||
app_links: ^4.0.0
|
app_links: ^4.0.0
|
||||||
background_fetch: ^1.2.1
|
background_fetch: ^1.2.1
|
||||||
|
equations: ^5.0.2
|
||||||
|
flex_color_picker: ^3.4.1
|
||||||
|
android_system_font:
|
||||||
|
git:
|
||||||
|
url: https://github.com/re7gog/android_system_font
|
||||||
|
ref: master
|
||||||
|
shizuku_apk_installer:
|
||||||
|
git:
|
||||||
|
url: https://github.com/re7gog/shizuku_apk_installer
|
||||||
|
ref: master
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Reference in New Issue
Block a user