mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-22 18:07:55 +00:00
Compare commits
72 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
90f7b190dd | ||
|
f08b0f0f1c | ||
|
0fbbf1d6ed | ||
|
66db45b39e | ||
|
c9bdcbbf9b | ||
|
ccaccee653 | ||
|
2ced849bd0 | ||
|
f0b879e830 | ||
|
e84568ffb5 | ||
|
6cc41ab890 | ||
|
038c96fe35 | ||
|
56e4b20d1f | ||
|
689ccff843 | ||
|
4e83693dc7 | ||
|
a0a6accc66 | ||
|
f6f7d1e970 | ||
|
ddda58e896 | ||
|
4f796446d6 | ||
|
04f5863f6a | ||
|
c0c5ba1024 | ||
|
a733433551 | ||
|
c362f16837 | ||
|
90ff6df189 | ||
|
388b6f5a20 | ||
|
b463adda73 | ||
|
6687a09d2e | ||
|
63776ac57a | ||
|
925f428873 | ||
|
9e4c53aa1c | ||
|
f5ff06a4d0 | ||
|
07064a5766 | ||
|
a77ac7ac47 | ||
|
7cd06cf581 | ||
|
30fbc14a80 | ||
|
431d087b88 | ||
|
5678100352 | ||
|
c6b3d1b100 | ||
|
c0a41034fa | ||
|
5bc41367ed | ||
|
17010e533f | ||
|
d5c47a1c4c | ||
|
08b1a9dce4 | ||
|
74146b83e2 | ||
|
938df620fa | ||
|
d4b8a07ee7 | ||
|
44aa7824f7 | ||
|
feae6b54a9 | ||
|
dbbce2aee1 | ||
|
ed1dcdab52 | ||
|
e3ccfb1b25 | ||
|
4ae04ae060 | ||
|
801367458e | ||
|
26c72fae89 | ||
|
b981f9234b | ||
|
7f07e4658f | ||
|
f182d27ebe | ||
|
3b9d6ac61e | ||
|
6f24ac8d25 | ||
|
2891ec2092 | ||
|
fc1424c67c | ||
|
83efd6b355 | ||
|
05e14bb81c | ||
|
1236cbe4e3 | ||
|
5f9159a13f | ||
|
fbd9f8f216 | ||
|
e32b6b67e0 | ||
|
63a849b80a | ||
|
170bb5e717 | ||
|
f121e4982e | ||
|
937289730d | ||
|
624a9302fd | ||
|
e6f4b69464 |
@ -298,6 +298,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity" />
|
android:value="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity" />
|
||||||
</activity>
|
</activity>
|
||||||
|
<!-- TODO: Remove? This is only used by https://github.com/andOTP/andOTP, which is unmaintained since 2021. Do people use forks or can we remove this? -->
|
||||||
<activity
|
<activity
|
||||||
android:name="org.kde.kdeconnect.Plugins.MousePadPlugin.SendKeystrokesToHostActivity"
|
android:name="org.kde.kdeconnect.Plugins.MousePadPlugin.SendKeystrokesToHostActivity"
|
||||||
android:label="@string/pref_plugin_mousepad_send_keystrokes"
|
android:label="@string/pref_plugin_mousepad_send_keystrokes"
|
||||||
|
@ -40,8 +40,8 @@ android {
|
|||||||
applicationId = "org.kde.kdeconnect_tp"
|
applicationId = "org.kde.kdeconnect_tp"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 13303
|
versionCode = 13304
|
||||||
versionName = "1.33.3"
|
versionName = "1.33.4"
|
||||||
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
|
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
يوفر كِيدِي المتّصل مجموعة من الميزات لدمج سير عملك عبر الأجهزة:
|
يوفر جسر كِيدِي مجموعة من الميزات لدمج سير عملك عبر الأجهزة:
|
||||||
|
|
||||||
- نقل الملفات بين أجهزتك.
|
- نقل الملفات بين أجهزتك.
|
||||||
- الوصول إلى الملفات الموجودة على هاتفك من جهاز الكمبيوتر الخاص بك، دون أسلاك.
|
- الوصول إلى الملفات الموجودة على هاتفك من حاسوبك، دون أسلاك.
|
||||||
- الحافظة المشتركة: النسخ واللصق بين أجهزتك.
|
- الحافظة المشتركة: النسخ واللصق بين أجهزتك.
|
||||||
- الحصول على إشعارات للمكالمات والرسائل الواردة على جهاز الكمبيوتر الخاص بك.
|
- الحصول على إشعارات للمكالمات والرسائل الواردة على حاسوبك.
|
||||||
- لوحة اللمس الافتراضية: استخدم شاشة هاتفك كلوحة لمس لجهاز الكمبيوتر الخاص بك.
|
- لوحة اللمس افتراضية: استخدم شاشة هاتفك كلوحة لمس لحاسوبك.
|
||||||
- مزامنة الإشعارات: الوصول إلى إشعارات هاتفك من جهاز الكمبيوتر الخاص بك والرد على الرسائل.
|
- مزامنة الإشعارات: الوصول إلى إشعارات هاتفك من حاسوبك والرد على الرسائل.
|
||||||
- التحكم عن بعد في الوسائط المتعددة: استخدم هاتفك كجهاز تحكم عن بعد لمشغلات الوسائط لينكس.
|
- التحكم عن بعد في الوسائط المتعددة: استخدم هاتفك كجهاز تحكم عن بعد لمشغلات الوسائط لينكس.
|
||||||
- اتصال WiFi: لا حاجة إلى سلك USB أو بلوتوث.
|
- اتصال واي فاي: لا حاجة إلى سلك يو اس بي أو بلوتوث.
|
||||||
- تشفير TLS من البداية إلى النهاية: معلوماتك آمنة.
|
- تعمية TLS من البداية إلى النهاية: معلوماتك آمنة.
|
||||||
|
|
||||||
يرجى ملاحظة أنك ستحتاج إلى تثبيت كِيدِي المتّصل على حاسوبك حتى يعمل هذا التطبيق، والحفاظ على تحديث إصدار سطح المكتب بإصدار أندوريد حتى تعمل أحدث الميزات.
|
يرجى ملاحظة أنك ستحتاج إلى تثبيت جسر كِيدِي على حاسوبك حتى يعمل هذا التطبيق، والحفاظ على تحديث إصدار سطح المكتب بإصدار أندوريد حتى تعمل أحدث الميزات.
|
||||||
|
|
||||||
معلومات الأذونات الحساسة:
|
معلومات الأذونات الحساسة:
|
||||||
* إذن إمكانية الوصول: مطلوب لتلقي إدخال من جهاز آخر للتحكم في هاتف أندرويد خاص بك، إذا كنت تستخدم ميزة الإدخال عن بُعد.
|
* إذن إمكانية الوصول: مطلوب لتلقي إدخال من جهاز آخر للتحكم في هاتف أندرويد خاص بك، إذا كنت تستخدم ميزة الإدخال عن بُعد.
|
||||||
* إذن تحديد الموقع في الخلفية: مطلوب لمعرفة شبكة واي فاي التي تتصل بها، إذا كنت تستخدم ميزة الشبكات الموثوقة.
|
* إذن تحديد الموقع في الخلفية: مطلوب لمعرفة شبكة واي فاي التي تتصل بها، إذا كنت تستخدم ميزة الشبكات الموثوقة.
|
||||||
|
|
||||||
لا يرسل كِيدِي المتّصل أي معلومات إلى كيدي أو إلى أي طرف ثالث. يرسل كِيدِي المتّصل البيانات من جهاز إلى آخر مباشرةً باستخدام الشبكة المحلية، وليس عبر الإنترنت، وباستخدام التشفير من البداية إلى النهاية.
|
لا يرسل جسر كِيدِي أي معلومات إلى كيدي أو إلى أي طرف ثالث. يرسل جسر كِيدِي البيانات من جهاز إلى آخر مباشرةً باستخدام الشبكة المحلية، وليس عبر الإنترنت، وباستخدام التعمية من البداية إلى النهاية.
|
||||||
|
|
||||||
هذا التطبيق جزء من مشروع مفتوح المصدر وهو موجود بفضل جميع الأشخاص الذين ساهموا فيه. قم بزيارة الموقع الإلكتروني للحصول على الكود المصدر.
|
هذا التطبيق جزء من مشروع مفتوح المصدر وهو موجود بفضل جميع الأشخاص الذين ساهموا فيه. زر الموقع الإلكتروني للحصول على الشفرة المصدرية.
|
@ -1 +1 @@
|
|||||||
يقوم كِيدِي المتّصل بدمج هاتفك الذكي والحاسوب
|
يدمج جسر كِيدِي هاتفك الذكي مع حاسوبك
|
16
fastlane/metadata/android/en-US/changelogs/13304.txt
Normal file
16
fastlane/metadata/android/en-US/changelogs/13304.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
1.33.4
|
||||||
|
* Extend offline URL sharing behavior to direct share targets.
|
||||||
|
* Improve paring screen.
|
||||||
|
|
||||||
|
1.33.3
|
||||||
|
* Fix connection issues. Pairing again might be needed in some cases.
|
||||||
|
* Add a setting to export the application logs.
|
||||||
|
|
||||||
|
1.33.1
|
||||||
|
* Fix compatibility with GSConnect.
|
||||||
|
|
||||||
|
1.33.0
|
||||||
|
* Add support for PeerTube links.
|
||||||
|
* Allow filtering notifications from work profile.
|
||||||
|
* Fix bug where devices would unpair without user interaction.
|
||||||
|
* Verification key now changes every second (if both devices support it).
|
20
fastlane/metadata/android/ru-RU/full_description.txt
Normal file
20
fastlane/metadata/android/ru-RU/full_description.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
KDE Connect предоставляет набор функций для интеграции рабочего процесса между устройствами:
|
||||||
|
- Передача файлов между устройствами.
|
||||||
|
- Доступ к файлам на телефоне с компьютера без проводов.
|
||||||
|
- Общий буфер обмена: копирование и вставка между устройствами.
|
||||||
|
- Уведомления о входящих вызовах и сообщениях на компьютере.
|
||||||
|
- Виртуальный тачпад: использование экрана телефона в качестве тачпада для компьютера.
|
||||||
|
- Синхронизация уведомлений: доступ к уведомлениям телефона с компьютера и возможность отвечать на сообщения.
|
||||||
|
- Дистанционное управление мультимедиа: использование телефона как пульта для медиаплееров в Linux.
|
||||||
|
- Подключение по Wi-Fi: без проводов USB или Bluetooth.
|
||||||
|
- Сквозное шифрование TLS: безопасность передаваемой информации.
|
||||||
|
|
||||||
|
Обратите внимание, что для работы приложения требуется установка KDE Connect на компьютере. Для поддержки всех функций, версия на компьютере должна быть актуальной и соответствовать версии на Android .
|
||||||
|
|
||||||
|
Информация о чувствительных разрешениях:
|
||||||
|
|
||||||
|
- Разрешение «Специальные возможности»: необходимо для получения ввода с другого устройства при использовании функции дистанционного ввода.
|
||||||
|
- Разрешение «Фоновое определение местоположения»: необходимо для определения текущей Wi-Fi-сети при использовании функции «Доверенные сети».
|
||||||
|
|
||||||
|
KDE Connect никогда не отправляет данные ни в KDE, ни третьим лицам. Передача данных осуществляется напрямую между устройствами через локальную сеть, без использования интернета, с применением сквозного шифрования.
|
||||||
|
Приложение является частью проекта с открытым исходным кодом и существует благодаря сообществу участников. Исходный код доступен на официальном сайте.
|
1
fastlane/metadata/android/ru-RU/short_description.txt
Normal file
1
fastlane/metadata/android/ru-RU/short_description.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
KDE Connect позволяет соединить смартфон и компьютер
|
1
fastlane/metadata/android/ru-RU/title.txt
Normal file
1
fastlane/metadata/android/ru-RU/title.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
KDE Connect
|
@ -1,33 +1,33 @@
|
|||||||
[versions]
|
[versions]
|
||||||
activityCompose = "1.10.1"
|
activityCompose = "1.10.1"
|
||||||
androidDesugarJdkLibs = "2.1.5"
|
androidDesugarJdkLibs = "2.1.5"
|
||||||
androidGradlePlugin = "8.9.1"
|
androidGradlePlugin = "8.11.0"
|
||||||
androidSmsmms = "kdeconnect-1-21-0"
|
androidSmsmms = "kdeconnect-1-21-0"
|
||||||
appcompat = "1.7.0"
|
appcompat = "1.7.1"
|
||||||
bcpkixJdk15on = "1.70"
|
bcpkixJdk15on = "1.70"
|
||||||
classindexksp = "1.2"
|
classindexksp = "1.2"
|
||||||
commonsCollections4 = "4.4"
|
commonsCollections4 = "4.5.0"
|
||||||
commonsIo = "2.18.0"
|
commonsIo = "2.19.0"
|
||||||
commonsLang3 = "3.17.0"
|
commonsLang3 = "3.17.0"
|
||||||
constraintlayoutCompose = "1.1.1"
|
constraintlayoutCompose = "1.1.1"
|
||||||
coreKtx = "1.15.0"
|
coreKtx = "1.16.0"
|
||||||
dependencyLicenseReport = "2.9"
|
dependencyLicenseReport = "2.9"
|
||||||
disklrucache = "2.0.2"
|
disklrucache = "2.0.2"
|
||||||
documentfile = "1.0.1"
|
documentfile = "1.1.0"
|
||||||
gridlayout = "1.0.0"
|
gridlayout = "1.1.0"
|
||||||
jsonassert = "1.5.3"
|
jsonassert = "1.5.3"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
kotlin = "2.1.20"
|
kotlin = "2.2.0"
|
||||||
kspPlugin = "2.1.20-1.0.32"
|
kspPlugin = "2.2.0-2.0.2"
|
||||||
kotlinxCoroutinesCore = "1.10.1"
|
kotlinxCoroutinesCore = "1.10.2"
|
||||||
lifecycleExtensions = "2.2.0"
|
lifecycleExtensions = "2.2.0"
|
||||||
lifecycleRuntimeKtx = "2.8.7"
|
lifecycleRuntimeKtx = "2.9.1"
|
||||||
logger = "1.0.3"
|
logger = "1.0.3"
|
||||||
material = "1.12.0"
|
material = "1.12.0"
|
||||||
material3 = "1.3.1"
|
material3 = "1.3.2"
|
||||||
media = "1.7.0"
|
media = "1.7.0"
|
||||||
minaCore = "2.2.4"
|
minaCore = "2.2.4"
|
||||||
mockitoCore = "5.17.0"
|
mockitoCore = "5.18.0"
|
||||||
preferenceKtx = "1.2.1"
|
preferenceKtx = "1.2.1"
|
||||||
reactiveStreams = "1.0.4"
|
reactiveStreams = "1.0.4"
|
||||||
recyclerview = "1.4.0"
|
recyclerview = "1.4.0"
|
||||||
@ -35,7 +35,7 @@ rxjava = "2.2.21"
|
|||||||
sl4j = "2.0.13"
|
sl4j = "2.0.13"
|
||||||
sshdCore = "2.15.0"
|
sshdCore = "2.15.0"
|
||||||
swiperefreshlayout = "1.1.0"
|
swiperefreshlayout = "1.1.0"
|
||||||
uiToolingPreview = "1.7.8"
|
uiToolingPreview = "1.8.3"
|
||||||
univocityParsers = "2.9.1"
|
univocityParsers = "2.9.1"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,7 @@
|
|||||||
#Sat Sep 28 01:39:16 AM EDT 2024
|
#Sat Sep 28 01:39:16 AM EDT 2024
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
@ -5,7 +5,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
||||||
"PO-Revision-Date: 2025-02-09 17:40+0400\n"
|
"PO-Revision-Date: 2025-08-20 21:20+0400\n"
|
||||||
"Last-Translator: Zayed Al-Saidi <zayed.alsaidi@gmail.com>\n"
|
"Last-Translator: Zayed Al-Saidi <zayed.alsaidi@gmail.com>\n"
|
||||||
"Language-Team: ar\n"
|
"Language-Team: ar\n"
|
||||||
"Language: ar\n"
|
"Language: ar\n"
|
||||||
@ -13,7 +13,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||||
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
|
||||||
"X-Generator: Lokalize 23.08.5\n"
|
"X-Generator: Lokalize 23.08.5\n"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -49,26 +49,21 @@ msgid ""
|
|||||||
"This app is part of an open source project and it exists thanks to all the "
|
"This app is part of an open source project and it exists thanks to all the "
|
||||||
"people who contributed to it. Visit the website to grab the source code.\n"
|
"people who contributed to it. Visit the website to grab the source code.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"يوفر كِيدِي المتّصل مجموعة من الميزات لدمج سير عملك عبر الأجهزة:\n"
|
"يوفر جسر كِيدِي مجموعة من الميزات لدمج سير عملك عبر الأجهزة:\n"
|
||||||
"\n"
|
"\n"
|
||||||
"- نقل الملفات بين أجهزتك.\n"
|
"- نقل الملفات بين أجهزتك.\n"
|
||||||
"- الوصول إلى الملفات الموجودة على هاتفك من جهاز الكمبيوتر الخاص بك، دون "
|
"- الوصول إلى الملفات الموجودة على هاتفك من حاسوبك، دون أسلاك.\n"
|
||||||
"أسلاك.\n"
|
|
||||||
"- الحافظة المشتركة: النسخ واللصق بين أجهزتك.\n"
|
"- الحافظة المشتركة: النسخ واللصق بين أجهزتك.\n"
|
||||||
"- الحصول على إشعارات للمكالمات والرسائل الواردة على جهاز الكمبيوتر الخاص "
|
"- الحصول على إشعارات للمكالمات والرسائل الواردة على حاسوبك.\n"
|
||||||
"بك.\n"
|
"- لوحة اللمس افتراضية: استخدم شاشة هاتفك كلوحة لمس لحاسوبك.\n"
|
||||||
"- لوحة اللمس الافتراضية: استخدم شاشة هاتفك كلوحة لمس لجهاز الكمبيوتر الخاص "
|
"- مزامنة الإشعارات: الوصول إلى إشعارات هاتفك من حاسوبك والرد على الرسائل.\n"
|
||||||
"بك.\n"
|
|
||||||
"- مزامنة الإشعارات: الوصول إلى إشعارات هاتفك من جهاز الكمبيوتر الخاص بك "
|
|
||||||
"والرد على الرسائل.\n"
|
|
||||||
"- التحكم عن بعد في الوسائط المتعددة: استخدم هاتفك كجهاز تحكم عن بعد لمشغلات "
|
"- التحكم عن بعد في الوسائط المتعددة: استخدم هاتفك كجهاز تحكم عن بعد لمشغلات "
|
||||||
"الوسائط لينكس.\n"
|
"الوسائط لينكس.\n"
|
||||||
"- اتصال WiFi: لا حاجة إلى سلك USB أو بلوتوث.\n"
|
"- اتصال واي فاي: لا حاجة إلى سلك يو اس بي أو بلوتوث.\n"
|
||||||
"- تشفير TLS من البداية إلى النهاية: معلوماتك آمنة.\n"
|
"- تعمية TLS من البداية إلى النهاية: معلوماتك آمنة.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"يرجى ملاحظة أنك ستحتاج إلى تثبيت كِيدِي المتّصل على حاسوبك حتى يعمل هذا "
|
"يرجى ملاحظة أنك ستحتاج إلى تثبيت جسر كِيدِي على حاسوبك حتى يعمل هذا التطبيق، "
|
||||||
"التطبيق، والحفاظ على تحديث إصدار سطح المكتب بإصدار أندوريد حتى تعمل أحدث "
|
"والحفاظ على تحديث إصدار سطح المكتب بإصدار أندوريد حتى تعمل أحدث الميزات.\n"
|
||||||
"الميزات.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"معلومات الأذونات الحساسة:\n"
|
"معلومات الأذونات الحساسة:\n"
|
||||||
"* إذن إمكانية الوصول: مطلوب لتلقي إدخال من جهاز آخر للتحكم في هاتف أندرويد "
|
"* إذن إمكانية الوصول: مطلوب لتلقي إدخال من جهاز آخر للتحكم في هاتف أندرويد "
|
||||||
@ -76,9 +71,9 @@ msgstr ""
|
|||||||
"* إذن تحديد الموقع في الخلفية: مطلوب لمعرفة شبكة واي فاي التي تتصل بها، إذا "
|
"* إذن تحديد الموقع في الخلفية: مطلوب لمعرفة شبكة واي فاي التي تتصل بها، إذا "
|
||||||
"كنت تستخدم ميزة الشبكات الموثوقة.\n"
|
"كنت تستخدم ميزة الشبكات الموثوقة.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"لا يرسل كِيدِي المتّصل أي معلومات إلى كيدي أو إلى أي طرف ثالث. يرسل كِيدِي المتّصل "
|
"لا يرسل جسر كِيدِي أي معلومات إلى كيدي أو إلى أي طرف ثالث. يرسل جسر كِيدِي "
|
||||||
"البيانات من جهاز إلى آخر مباشرةً باستخدام الشبكة المحلية، وليس عبر الإنترنت، "
|
"البيانات من جهاز إلى آخر مباشرةً باستخدام الشبكة المحلية، وليس عبر الإنترنت، "
|
||||||
"وباستخدام التشفير من البداية إلى النهاية.\n"
|
"وباستخدام التعمية من البداية إلى النهاية.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"هذا التطبيق جزء من مشروع مفتوح المصدر وهو موجود بفضل جميع الأشخاص الذين "
|
"هذا التطبيق جزء من مشروع مفتوح المصدر وهو موجود بفضل جميع الأشخاص الذين "
|
||||||
"ساهموا فيه. قم بزيارة الموقع الإلكتروني للحصول على الكود المصدر.\n"
|
"ساهموا فيه. زر الموقع الإلكتروني للحصول على الشفرة المصدرية.\n"
|
||||||
|
@ -5,7 +5,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
||||||
"PO-Revision-Date: 2025-02-09 17:40+0400\n"
|
"PO-Revision-Date: 2025-05-31 17:30+0400\n"
|
||||||
"Last-Translator: Zayed Al-Saidi <zayed.alsaidi@gmail.com>\n"
|
"Last-Translator: Zayed Al-Saidi <zayed.alsaidi@gmail.com>\n"
|
||||||
"Language-Team: ar\n"
|
"Language-Team: ar\n"
|
||||||
"Language: ar\n"
|
"Language: ar\n"
|
||||||
@ -13,8 +13,8 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||||
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
|
||||||
"X-Generator: Lokalize 23.08.5\n"
|
"X-Generator: Lokalize 23.08.5\n"
|
||||||
|
|
||||||
msgid "KDE Connect integrates your smartphone and computer"
|
msgid "KDE Connect integrates your smartphone and computer"
|
||||||
msgstr "يقوم كِيدِي المتّصل بدمج هاتفك الذكي والحاسوب"
|
msgstr "يدمج جسر كِيدِي هاتفك الذكي مع حاسوبك"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Frederik Schwarzer <schwarzer@kde.org>, 2023.
|
# SPDX-FileCopyrightText: 2023 Frederik Schwarzer <schwarzer@kde.org>
|
||||||
# tobi <onewayme001@posteo.de>, 2024.
|
# SPDX-FileCopyrightText: 2024 tobi <onewayme001@posteo.de>
|
||||||
#. extracted from ./metadata/android/en-US/full_description.txt
|
#. extracted from ./metadata/android/en-US/full_description.txt
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Frederik Schwarzer <schwarzer@kde.org>, 2023.
|
# SPDX-FileCopyrightText: 2023 Frederik Schwarzer <schwarzer@kde.org>
|
||||||
#. extracted from ./metadata/android/en-US/short_description.txt
|
#. extracted from ./metadata/android/en-US/short_description.txt
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
# SPDX-FileCopyrightText: 2023 Víctor Rodrigo Córdoba <vrcordoba@gmail.com>
|
# Spanish translations for kdeconnect-android-store-full.po package.
|
||||||
|
# Copyright (C) 2023-2025 This file is copyright:
|
||||||
|
# This file is distributed under the same license as the kdeconnect-android package.
|
||||||
|
#
|
||||||
|
# SPDX-FileCopyrightText: 2023, 2025 Víctor Rodrigo Córdoba <vrcordoba@gmail.com>
|
||||||
#. extracted from ./metadata/android/en-US/full_description.txt
|
#. extracted from ./metadata/android/en-US/full_description.txt
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: kdeconnect-android-store-full\n"
|
"Project-Id-Version: kdeconnect-android-store-full\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
||||||
"PO-Revision-Date: 2023-09-30 18:49+0200\n"
|
"PO-Revision-Date: 2025-06-09 02:36+0100\n"
|
||||||
"Last-Translator: Víctor Rodrigo Córdoba <vrcordoba@gmail.com>\n"
|
"Last-Translator: Víctor Rodrigo Córdoba <vrcordoba@gmail.com>\n"
|
||||||
"Language-Team: Spanish <kde-l10n-es@kde.org>\n"
|
"Language-Team: Spanish <kde-l10n-es@kde.org>\n"
|
||||||
"Language: es\n"
|
"Language: es\n"
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
# SPDX-FileCopyrightText: 2023 Víctor Rodrigo Córdoba <vrcordoba@gmail.com>
|
# Spanish translations for kdeconnect-android-store-short.po package.
|
||||||
|
# Copyright (C) 2023-2025 This file is copyright:
|
||||||
|
# This file is distributed under the same license as the kdeconnect-android package.
|
||||||
|
#
|
||||||
|
# SPDX-FileCopyrightText: 2023, 2025 Víctor Rodrigo Córdoba <vrcordoba@gmail.com>
|
||||||
#. extracted from ./metadata/android/en-US/short_description.txt
|
#. extracted from ./metadata/android/en-US/short_description.txt
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: kdeconnect-android-store-short\n"
|
"Project-Id-Version: kdeconnect-android-store-short\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
||||||
"PO-Revision-Date: 2023-06-10 17:26+0200\n"
|
"PO-Revision-Date: 2025-06-09 02:36+0100\n"
|
||||||
"Last-Translator: Víctor Rodrigo Córdoba <vrcordoba@gmail.com>\n"
|
"Last-Translator: Víctor Rodrigo Córdoba <vrcordoba@gmail.com>\n"
|
||||||
"Language-Team: Spanish <kde-l10n-es@kde.org>\n"
|
"Language-Team: Spanish <kde-l10n-es@kde.org>\n"
|
||||||
"Language: es\n"
|
"Language: es\n"
|
||||||
|
83
po/ru/kdeconnect-android-store-full.po
Normal file
83
po/ru/kdeconnect-android-store-full.po
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
# Alexander Yavorskiy <kekcuha@gmail.com>, 2025.
|
||||||
|
#. extracted from ./metadata/android/en-US/full_description.txt
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
||||||
|
"PO-Revision-Date: 2025-05-30 20:22+0200\n"
|
||||||
|
"Last-Translator: Alexander Yavorskiy <kekcuha@gmail.com>\n"
|
||||||
|
"Language-Team: Russian <kde-russian@lists.kde.ru>\n"
|
||||||
|
"Language: ru\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Generator: Lokalize 21.08.3\n"
|
||||||
|
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||||
|
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"KDE Connect provides a set of features to integrate your workflow across "
|
||||||
|
"devices:\n"
|
||||||
|
"\n"
|
||||||
|
"- Transfer files between your devices.\n"
|
||||||
|
"- Access files on your phone from your computer, without wires.\n"
|
||||||
|
"- Shared clipboard: copy and paste between your devices.\n"
|
||||||
|
"- Get notifications for incoming calls and messages on your computer.\n"
|
||||||
|
"- Virtual touchpad: Use your phone screen as your computer's touchpad.\n"
|
||||||
|
"- Notifications sync: Access your phone notifications from your computer and "
|
||||||
|
"reply to messages.\n"
|
||||||
|
"- Multimedia remote control: Use your phone as a remote for Linux media "
|
||||||
|
"players.\n"
|
||||||
|
"- WiFi connection: no USB wire or bluetooth needed.\n"
|
||||||
|
"- End-to-end TLS encryption: your information is safe.\n"
|
||||||
|
"\n"
|
||||||
|
"Please note you will need to install KDE Connect on your computer for this "
|
||||||
|
"app to work, and keep the desktop version up-to-date with the Android "
|
||||||
|
"version for the latest features to work.\n"
|
||||||
|
"\n"
|
||||||
|
"Sensitive permissions information:\n"
|
||||||
|
"* Accessibility permission: Required to receive input from another device to "
|
||||||
|
"control your Android phone, if you use the Remote Input feature.\n"
|
||||||
|
"* Background location permission: Required to know to which WiFi network you "
|
||||||
|
"are connected to, if you use the Trusted Networks feature.\n"
|
||||||
|
"\n"
|
||||||
|
"KDE Connect never sends any information to KDE nor to any third party. KDE "
|
||||||
|
"Connect sends data from one device to the other directly using the local "
|
||||||
|
"network, never through the internet, and using end to end encryption.\n"
|
||||||
|
"\n"
|
||||||
|
"This app is part of an open source project and it exists thanks to all the "
|
||||||
|
"people who contributed to it. Visit the website to grab the source code.\n"
|
||||||
|
msgstr ""
|
||||||
|
"KDE Connect предоставляет набор функций для интеграции рабочего процесса "
|
||||||
|
"между устройствами:\n"
|
||||||
|
"- Передача файлов между устройствами.\n"
|
||||||
|
"- Доступ к файлам на телефоне с компьютера без проводов.\n"
|
||||||
|
"- Общий буфер обмена: копирование и вставка между устройствами.\n"
|
||||||
|
"- Уведомления о входящих вызовах и сообщениях на компьютере.\n"
|
||||||
|
"- Виртуальный тачпад: использование экрана телефона в качестве тачпада для "
|
||||||
|
"компьютера.\n"
|
||||||
|
"- Синхронизация уведомлений: доступ к уведомлениям телефона с компьютера и "
|
||||||
|
"возможность отвечать на сообщения.\n"
|
||||||
|
"- Дистанционное управление мультимедиа: использование телефона как пульта "
|
||||||
|
"для медиаплееров в Linux.\n"
|
||||||
|
"- Подключение по Wi-Fi: без проводов USB или Bluetooth.\n"
|
||||||
|
"- Сквозное шифрование TLS: безопасность передаваемой информации.\n"
|
||||||
|
"\n"
|
||||||
|
"Обратите внимание, что для работы приложения требуется установка KDE Connect "
|
||||||
|
"на компьютере. Для поддержки всех функций, версия на компьютере должна быть "
|
||||||
|
"актуальной и соответствовать версии на Android .\n"
|
||||||
|
"\n"
|
||||||
|
"Информация о чувствительных разрешениях:\n"
|
||||||
|
"\n"
|
||||||
|
"- Разрешение «Специальные возможности»: необходимо для получения ввода с "
|
||||||
|
"другого устройства при использовании функции дистанционного ввода.\n"
|
||||||
|
"- Разрешение «Фоновое определение местоположения»: необходимо для "
|
||||||
|
"определения текущей Wi-Fi-сети при использовании функции «Доверенные сети».\n"
|
||||||
|
"\n"
|
||||||
|
"KDE Connect никогда не отправляет данные ни в KDE, ни третьим лицам. "
|
||||||
|
"Передача данных осуществляется напрямую между устройствами через локальную "
|
||||||
|
"сеть, без использования интернета, с применением сквозного шифрования.\n"
|
||||||
|
"Приложение является частью проекта с открытым исходным кодом и существует "
|
||||||
|
"благодаря сообществу участников. Исходный код доступен на официальном "
|
||||||
|
"сайте.\n"
|
20
po/ru/kdeconnect-android-store-short.po
Normal file
20
po/ru/kdeconnect-android-store-short.po
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Alexander Yavorskiy <kekcuha@gmail.com>, 2025.
|
||||||
|
#. extracted from ./metadata/android/en-US/short_description.txt
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
|
||||||
|
"PO-Revision-Date: 2025-05-30 20:17+0200\n"
|
||||||
|
"Last-Translator: Alexander Yavorskiy <kekcuha@gmail.com>\n"
|
||||||
|
"Language-Team: Russian <kde-russian@lists.kde.ru>\n"
|
||||||
|
"Language: ru\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Generator: Lokalize 21.08.3\n"
|
||||||
|
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||||
|
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||||
|
|
||||||
|
msgid "KDE Connect integrates your smartphone and computer"
|
||||||
|
msgstr "KDE Connect позволяет соединить смартфон и компьютер"
|
25
res/layout-v23/pairing_explanation_duplicate_names.xml
Normal file
25
res/layout-v23/pairing_explanation_duplicate_names.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2023 Albert Vaca Cintora <albertvaka@gmail.com>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
-->
|
||||||
|
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:paddingTop="16dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:text="@string/pairing_duplicate_names"
|
||||||
|
app:drawableStartCompat="@drawable/ic_warning"
|
||||||
|
app:drawableTint="?attr/colorControlNormal">
|
||||||
|
|
||||||
|
</TextView>
|
@ -11,19 +11,21 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
android:id="@+id/refresh_list_layout"
|
android:id="@+id/refresh_list_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_margin="@dimen/activity_horizontal_margin">
|
>
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/devices_list"
|
android:id="@+id/devices_list"
|
||||||
|
android:scrollbarStyle="outsideOverlay"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:addStatesFromChildren="true"
|
android:addStatesFromChildren="true"
|
||||||
android:divider="@null"
|
android:divider="@null"
|
||||||
|
android:padding="@dimen/activity_horizontal_margin"
|
||||||
android:descendantFocusability="afterDescendants"
|
android:descendantFocusability="afterDescendants"
|
||||||
android:dividerHeight="12dp"
|
android:dividerHeight="12dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
tools:listitem="@layout/list_card_entry"
|
tools:listitem="@layout/list_item_device_entry"
|
||||||
tools:context=".MainActivity" />
|
tools:context=".MainActivity" />
|
||||||
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
SPDX-FileCopyrightText: 2023 Dmitry Yudin <dgyudin@gmail.com>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
-->
|
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="4dp"
|
|
||||||
style="@style/KdeConnectCardStyle.Filled"
|
|
||||||
app:contentPadding="@dimen/view_default_padding"
|
|
||||||
tools:layout_width="240dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:baselineAligned="false"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/list_item_entry_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:src="@drawable/ic_device_laptop_32dp"
|
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
android:importantForAccessibility="no"
|
|
||||||
app:tint="?attr/colorOnSurface" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/list_item_entry_title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:lines="2"
|
|
||||||
android:text=""
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:textColor="?attr/colorOnSurface"
|
|
||||||
tools:maxLength="30"
|
|
||||||
tools:text="@tools:sample/lorem/random" />
|
|
||||||
</LinearLayout>
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
71
res/layout/list_item_device_entry.xml
Normal file
71
res/layout/list_item_device_entry.xml
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2023 Dmitry Yudin <dgyudin@gmail.com>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
-->
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
android:focusable="true"
|
||||||
|
android:clickable="true"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
style="@style/KdeConnectCardStyle.Filled"
|
||||||
|
app:contentPadding="@dimen/view_default_padding">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:baselineAligned="false"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/list_item_entry_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:src="@drawable/ic_device_laptop_32dp"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
app:tint="?attr/colorControlNormal"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/list_item_entry_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="8dip"
|
||||||
|
android:text=""
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
tools:text="A very long device name that might wrap into multiple lines"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/list_item_entry_summary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dip"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text=""
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textColor="#CC2222"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:text="Other (optional) info"
|
||||||
|
tools:visibility="gone"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
@ -1,67 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
SPDX-FileCopyrightText: 2023 Albert Vaca Cintora <albertvaka@gmail.com>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
|
||||||
android:baselineAligned="false"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingRight="16dp">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:id="@+id/list_item_entry_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:src="@drawable/ic_device_laptop_32dp"
|
|
||||||
android:importantForAccessibility="no"
|
|
||||||
app:tint="?attr/colorControlNormal"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/list_item_entry_title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginStart="8dip"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:fadingEdge="horizontal"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text=""
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
tools:maxLength="20"
|
|
||||||
tools:text="@tools:sample/lorem/random"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/list_item_entry_summary"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dip"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text=""
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
|
||||||
android:textColor="#CC2222"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:text="Other (optional) info"
|
|
||||||
tools:visibility="visible"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
25
res/layout/pairing_explanation_duplicate_names.xml
Normal file
25
res/layout/pairing_explanation_duplicate_names.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2023 Albert Vaca Cintora <albertvaka@gmail.com>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
-->
|
||||||
|
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:paddingTop="16dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:text="@string/pairing_duplicate_names"
|
||||||
|
app:drawableStartCompat="@drawable/ic_warning"
|
||||||
|
app:drawableLeftCompat="@drawable/ic_warning">
|
||||||
|
|
||||||
|
</TextView>
|
@ -13,6 +13,4 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingHorizontal="@dimen/activity_horizontal_margin"
|
android:paddingHorizontal="@dimen/activity_horizontal_margin"
|
||||||
android:paddingVertical="@dimen/activity_vertical_margin">
|
android:paddingVertical="@dimen/activity_vertical_margin" />
|
||||||
|
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
|
||||||
|
@ -19,12 +19,6 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/pair_progress"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/pair_message"
|
android:id="@+id/pair_message"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -33,6 +27,13 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
android:text="@string/device_not_paired"
|
android:text="@string/device_not_paired"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pairing_explanation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="12dip"
|
||||||
|
android:text="@string/pairing_explanation" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/pair_verification"
|
android:id="@+id/pair_verification"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -43,6 +44,12 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
app:drawableStartCompat="@drawable/ic_key" />
|
app:drawableStartCompat="@drawable/ic_key" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/pair_progress"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/pair_button"
|
android:id="@+id/pair_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -7,11 +7,20 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="20dp">
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="10dip"
|
||||||
|
android:text="@string/pairing_title"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/run_commands_device_list"
|
android:id="@+id/run_commands_device_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -20,13 +29,12 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
android:addStatesFromChildren="true"
|
android:addStatesFromChildren="true"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:divider="@null"
|
android:divider="@null"
|
||||||
android:dividerHeight="0dp" />
|
android:dividerHeight="12dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/no_devices"
|
android:id="@+id/no_devices"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_margin="10dip"
|
android:layout_margin="10dip"
|
||||||
android:text="@string/device_list_empty"
|
android:text="@string/device_list_empty"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
@ -1,51 +1,69 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="kde_connect">كِيدِي المتّصل</string>
|
<string name="kde_connect">جسر كِيدِي</string>
|
||||||
<string name="manifest_label_share">أرسِل إلى جهاز</string>
|
<string name="manifest_label_share">أرسِل إلى جهاز</string>
|
||||||
<string name="foreground_notification_no_devices">غير متصل بأي جهاز</string>
|
<string name="foreground_notification_no_devices">غير متصل بأي جهاز</string>
|
||||||
<string name="foreground_notification_devices">متّصل بـ: %s</string>
|
<string name="foreground_notification_devices">متّصل بـ: %s</string>
|
||||||
<string name="foreground_notification_send_clipboard">أرسل الحافظة</string>
|
<string name="foreground_notification_send_clipboard">أرسل الحافظة</string>
|
||||||
<string name="pref_plugin_telephony">مُخطِر المهاتفة</string>
|
<string name="pref_plugin_telephony">مُخطِر المهاتفة</string>
|
||||||
<string name="pref_plugin_telephony_desc">أرسل إخطارات للمكالمات الواردة</string>
|
<string name="pref_plugin_telephony_desc">أرسل إشعارات للمكالمات الواردة</string>
|
||||||
<string name="pref_plugin_battery">تقرير البطّاريّة</string>
|
<string name="pref_plugin_battery">تقرير البطّاريّة</string>
|
||||||
<string name="pref_plugin_battery_desc">بلّغ عن حالة البطّاريّة دوريًّا</string>
|
<string name="pref_plugin_battery_desc">بلّغ عن حالة البطّاريّة دوريًّا</string>
|
||||||
<string name="pref_plugin_connectivity_report">تقرير الاتصال</string>
|
<string name="pref_plugin_connectivity_report">تقرير الاتصال</string>
|
||||||
|
<string name="pref_plugin_connectivity_report_desc">تقرير قوة إشارة الشبكة والحالة</string>
|
||||||
<string name="pref_plugin_sftp">اكشف نظام الملفّات</string>
|
<string name="pref_plugin_sftp">اكشف نظام الملفّات</string>
|
||||||
<string name="pref_plugin_sftp_desc">تسمح بتصفّح نظام ملفّات هذا الهاتف عن بعد</string>
|
<string name="pref_plugin_sftp_desc">تسمح بتصفّح نظام ملفّات هذا الهاتف عن بعد</string>
|
||||||
<string name="pref_plugin_clipboard">مزامنة الحافظة</string>
|
<string name="pref_plugin_clipboard">مزامنة الحافظة</string>
|
||||||
<string name="pref_plugin_clipboard_desc">شارك محتوى الحافظة</string>
|
<string name="pref_plugin_clipboard_desc">شارك محتوى الحافظة</string>
|
||||||
<string name="pref_plugin_clipboard_sent">أرسل الحافظة</string>
|
<string name="pref_plugin_clipboard_sent">أرسل للحافظة</string>
|
||||||
<string name="pref_plugin_mousepad">الدّخل البعيد</string>
|
<string name="pref_plugin_mousepad">الإدخال البعيد</string>
|
||||||
<string name="pref_plugin_mousepad_desc">استخدم الهاتف أو اللوحيّ كفأرة ولوحة مفاتيح</string>
|
<string name="pref_plugin_mousepad_desc">استخدم الهاتف أو اللوحيّ كفأرة ولوحة مفاتيح</string>
|
||||||
<string name="pref_plugin_presenter">متحكم العرض التقديمي</string>
|
<string name="pref_plugin_presenter">متحكم العرض التقديمي</string>
|
||||||
|
<string name="pref_plugin_presenter_desc">استخدام جهازك لتغيير الشرائح في العرض التقديمي</string>
|
||||||
|
<string name="pref_plugin_remotekeyboard">تلقي ضغطات المفاتيح البعيدة</string>
|
||||||
|
<string name="pref_plugin_remotekeyboard_desc">تلقي أحداث الضغط على المفاتيح من الأجهزة البعيدة</string>
|
||||||
<string name="pref_plugin_mpris">تحكّمات الوسائط المتعدّدة</string>
|
<string name="pref_plugin_mpris">تحكّمات الوسائط المتعدّدة</string>
|
||||||
<string name="pref_plugin_mpris_desc">توفّر تحكّمًا بعيدًا لمشغّل الوسائط</string>
|
<string name="pref_plugin_mpris_desc">توفّر تحكّمًا بعيدًا لمشغّل الوسائط</string>
|
||||||
<string name="pref_plugin_runcommand">شغّل أمرًا</string>
|
<string name="pref_plugin_runcommand">شغّل أمرًا</string>
|
||||||
<string name="pref_plugin_runcommand_desc">تحفّز أوامر عن بعد من الهاتف أو اللوحيّ</string>
|
<string name="pref_plugin_runcommand_desc">شغّل أوامر عن بعد من الهاتف أو اللوحيّ</string>
|
||||||
<string name="pref_plugin_contacts">مزامن المتراسلين</string>
|
<string name="pref_plugin_contacts">مزامن المتراسلين</string>
|
||||||
<string name="pref_plugin_ping">وخزة</string>
|
<string name="pref_plugin_contacts_desc">اسمح بمزامنة دفتر المتراسلين في الجهاز</string>
|
||||||
<string name="pref_plugin_ping_desc">أرسل واستقبل وخزات</string>
|
<string name="pref_plugin_ping">وخزة Ping</string>
|
||||||
<string name="pref_plugin_notifications">مزامنة الإخطارات</string>
|
<string name="pref_plugin_ping_desc">أرسل واستقبل وخزات Ping</string>
|
||||||
<string name="pref_plugin_notifications_desc">انفذ إلى إخطاراتك من أجهزة أخرى</string>
|
<string name="pref_plugin_notifications">مزامنة الإشعارات</string>
|
||||||
<string name="pref_plugin_receive_notifications">استقبل الإخطارات</string>
|
<string name="pref_plugin_notifications_desc">انفذ إلى إشعاراتك من أجهزة أخرى</string>
|
||||||
<string name="pref_plugin_receive_notifications_desc">استقبل الإخطارات من الجهاز الآخر واعرضها على أندرويد</string>
|
<string name="pref_plugin_receive_notifications">استقبل الإشعارات</string>
|
||||||
|
<string name="pref_plugin_receive_notifications_desc">استقبل الإشعارات من الجهاز الآخر واعرضها على أندرويد</string>
|
||||||
<string name="pref_plugin_sharereceiver">شارك واستقبل</string>
|
<string name="pref_plugin_sharereceiver">شارك واستقبل</string>
|
||||||
<string name="pref_plugin_sharereceiver_desc">شارك الملفّات والعناوين بين الجهازين</string>
|
<string name="pref_plugin_sharereceiver_desc">شارك الملفّات والعناوين بين الجهازين</string>
|
||||||
<string name="device_list_empty">لا أجهزة</string>
|
<string name="device_list_empty">لا توجد أجهزة</string>
|
||||||
<string name="ok">حسنًا</string>
|
<string name="ok">حسنًا</string>
|
||||||
<string name="sad_ok">حسنًا ):</string>
|
<string name="sad_ok">حسنًا ):</string>
|
||||||
<string name="cancel">ألغِ</string>
|
<string name="cancel">ألغِ</string>
|
||||||
<string name="open_settings">افتح الإعدادات</string>
|
<string name="open_settings">افتح الإعدادات</string>
|
||||||
<string name="no_permissions">عليك إعطاء التّطبيق صلاحيّات للنّفاذ إلى الإخطارات</string>
|
<string name="no_permissions">عليك إعطاء التّطبيق صلاحيّات للنّفاذ إلى الإشعارات</string>
|
||||||
<string name="send_ping">أرسل وخزة</string>
|
<string name="no_permission_mprisreceiver">لتكون قادرًا على التحكم في مشغلات الوسائط الخاصة بك، تحتاج إلى منح حق الوصول إلى الإشعارات</string>
|
||||||
<string name="open_mpris_controls">تحكّمات الوسائط المتعدّدة</string>
|
<string name="no_permissions_remotekeyboard">لتلقي ضغطات المفاتيح تحتاج إلى تنشيط لوحة المفاتيح البعيدة لجسر كِيدِي</string>
|
||||||
<string name="open_mousepad">الدّخل البعيد</string>
|
<string name="send_ping">أرسل وخزة ping</string>
|
||||||
<string name="mousepad_single_tap_settings_title">اضبط إجراء الطَرق بالأصبع</string>
|
<string name="open_mpris_controls">متحكّمات الوسائط المتعدّدة</string>
|
||||||
<string name="mousepad_double_tap_settings_title">اضبط إجراء اللمس بإصبعين</string>
|
<string name="remotekeyboard_editing_only_title">التعامل مع المفاتيح البعيدة فقط عند التحرير</string>
|
||||||
<string name="mousepad_triple_tap_settings_title">اضبط إجراء اللمس بثلاث أصابع</string>
|
<string name="remotekeyboard_not_connected">لا يوجد اتصال لوحة المفاتيح بعيدة نشط، وإنشاء واحد في جسر كِيدِي</string>
|
||||||
|
<string name="remotekeyboard_connected">اتصال لوحة المفاتيح بعيدة نشط</string>
|
||||||
|
<string name="remotekeyboard_multiple_connections">هناك أكثر من اتصال لوحة مفاتيح بعيدة، حدد الجهاز لتضبطه</string>
|
||||||
|
<string name="open_mousepad">الإدخال البعيد</string>
|
||||||
|
<string name="mousepad_info">حرك إصبعًا على الشاشة لتحريك مؤشر الفأرة. اطرق للنقرة، واستخدم اثنين أو ثلاث أصابع للأزرار اليمنى والوسطى. استخدام أصبعين للتمرير. استخدم الضغط طويلًا للسحب والإفلات. يمكن تمكين وظيفة الفأرة التوجيهية Gyro من تفضيلات الملحقة.</string>
|
||||||
|
<string name="mousepad_info_no_gestures">حرك إصبعًا على الشاشة لتحريك مؤشر الفأرة، اطرق للنقرة.</string>
|
||||||
|
<string name="mousepad_keyboard_input_not_supported">إدخال لوحة المفاتيح غير مدعوم من قبل الجهاز المقترن</string>
|
||||||
|
<string name="mousepad_single_tap_settings_title">اضبط إجراء الطَرق بأصبع واحدة</string>
|
||||||
|
<string name="mousepad_double_tap_settings_title">اضبط إجراء الطرق بأصبعين</string>
|
||||||
|
<string name="mousepad_triple_tap_settings_title">اضبط إجراء الطرق بثلاث أصابع</string>
|
||||||
<string name="mousepad_sensitivity_settings_title">اضبط حساسيّة لوحة اللمس</string>
|
<string name="mousepad_sensitivity_settings_title">اضبط حساسيّة لوحة اللمس</string>
|
||||||
|
<string name="mousepad_mouse_buttons_title">أظهر أزرار الفأرة</string>
|
||||||
<string name="mousepad_acceleration_profile_settings_title">عيّن تسارع المؤشر</string>
|
<string name="mousepad_acceleration_profile_settings_title">عيّن تسارع المؤشر</string>
|
||||||
<string name="mousepad_scroll_direction_title">اعكس اتّجاه التّمرير</string>
|
<string name="mousepad_scroll_direction_title">اعكس اتّجاه التّمرير</string>
|
||||||
|
<string name="mousepad_scroll_sensitivity_title">حساسية التمرير</string>
|
||||||
|
<string name="gyro_mouse_enabled_title">تمكين الفأر التوجيهي</string>
|
||||||
|
<string name="gyro_mouse_sensitivity_title">حساسية التوجيه</string>
|
||||||
<string-array name="mousepad_tap_entries">
|
<string-array name="mousepad_tap_entries">
|
||||||
<item>النّقر باليسار</item>
|
<item>النّقر باليسار</item>
|
||||||
<item>النقر باليمين</item>
|
<item>النقر باليمين</item>
|
||||||
@ -55,18 +73,33 @@
|
|||||||
<string-array name="mousepad_sensitivity_entries">
|
<string-array name="mousepad_sensitivity_entries">
|
||||||
<item>الأبطأ</item>
|
<item>الأبطأ</item>
|
||||||
<item>الأقل بطئًا</item>
|
<item>الأقل بطئًا</item>
|
||||||
<item>الافتراضيّ</item>
|
<item>المبدئيّ</item>
|
||||||
<item>الأسرع قليلًا</item>
|
<item>الأسرع قليلًا</item>
|
||||||
<item>الأسرع</item>
|
<item>الأسرع</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="mousepad_acceleration_profile_entries">
|
<string-array name="mousepad_acceleration_profile_entries">
|
||||||
<item>بدون تسريع</item>
|
<item>دون تسريع</item>
|
||||||
<item>الأكثر ضعفاً</item>
|
<item>الأكثر ضعفاً</item>
|
||||||
<item>ضعيف</item>
|
<item>ضعيف</item>
|
||||||
<item>متوسط</item>
|
<item>متوسط</item>
|
||||||
<item>أقوى</item>
|
<item>أقوى</item>
|
||||||
<item>الأقوى</item>
|
<item>الأقوى</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string name="sendkeystrokes_send_to">أرسل ضغطات المفاتيح إلى</string>
|
||||||
|
<string name="sendkeystrokes_textbox_hint">أرسل ضغطات المفاتيح إلى المضيف</string>
|
||||||
|
<string name="sendkeystrokes_disabled_toast">إرسال ضغطات المفاتيح معطل - تمكينه في الإعدادات</string>
|
||||||
|
<string name="sendkeystrokes_wrong_data">نوع ملف غير صحيح - يجب أن يكون \'text/x-keystrokes\'</string>
|
||||||
|
<string name="sendkeystrokes_sent_text">أرسل %1$s إلى جهاز %2$s</string>
|
||||||
|
<string name="sendkeystrokes_pref_category_summary">تسمح هذه الوحدة للتطبيقات الأخرى بمشاركة مقاطع النص على شكل ضغطات مفاتيح والتي ستُرسل إلى المضيف المتصل</string>
|
||||||
|
<string name="sendkeystrokes_pref_category_title">أرسل ضغطات المفاتيح</string>
|
||||||
|
<string name="sendkeystrokes_pref_enabled">مكّن إرسال ضغطات المفاتيح</string>
|
||||||
|
<string name="sendkeystrokes_pref_enabled_summary">ستمع إلى البيانات التي تحتوي على نوع ملف التعريف \'text/x-keystrokes\'</string>
|
||||||
|
<string name="sendkeystrokes_safe_text_enabled">أرسل نص آمن فورًا</string>
|
||||||
|
<string name="sendkeystrokes_safe_text_enabled_summary">أرسل سلاسل رقمية قصيرة فقط دون تأكيد</string>
|
||||||
|
<string name="pref_plugin_mousepad_send_keystrokes">أرسل كضغطات مفاتيح</string>
|
||||||
|
<string name="mouse_receiver_plugin_description">استقبل حركة الفأرة البعيدة</string>
|
||||||
|
<string name="mouse_receiver_plugin_name">مستقبل الفأرة</string>
|
||||||
|
<string name="mouse_receiver_no_permissions">لتلقي المدخلات التي تعمل باللمس عن بُعد، تحتاج إلى منح أذونات إمكانية الوصول للتحكم الكامل في جهازك</string>
|
||||||
<string name="view_status_title">الحالة</string>
|
<string name="view_status_title">الحالة</string>
|
||||||
<string name="battery_status_format">البطارية: %d%%</string>
|
<string name="battery_status_format">البطارية: %d%%</string>
|
||||||
<string name="battery_status_low_format">البطارية: %d%% منخفضة</string>
|
<string name="battery_status_low_format">البطارية: %d%% منخفضة</string>
|
||||||
@ -80,8 +113,9 @@
|
|||||||
<string name="cancel_pairing">ألغ الاقتران</string>
|
<string name="cancel_pairing">ألغ الاقتران</string>
|
||||||
<string name="unknown_device">جهاز مجهول</string>
|
<string name="unknown_device">جهاز مجهول</string>
|
||||||
<string name="error_not_reachable">الجهاز غير قابل الوصول</string>
|
<string name="error_not_reachable">الجهاز غير قابل الوصول</string>
|
||||||
<string name="error_already_paired">الجهاز مقترن بالفعل</string>
|
<string name="error_already_paired">الجهاز مقترن فعلًا</string>
|
||||||
<string name="error_timed_out">انتهت المهلة</string>
|
<string name="error_timed_out">انتهت المهلة</string>
|
||||||
|
<string name="error_clocks_not_match">ساعات الجهاز غير متزامنة</string>
|
||||||
<string name="error_canceled_by_user">ألغاه المستخدم</string>
|
<string name="error_canceled_by_user">ألغاه المستخدم</string>
|
||||||
<string name="error_canceled_by_other_peer">ألغاه ندّ آخر</string>
|
<string name="error_canceled_by_other_peer">ألغاه ندّ آخر</string>
|
||||||
<string name="encryption_info_title">معلومات التّعمية</string>
|
<string name="encryption_info_title">معلومات التّعمية</string>
|
||||||
@ -90,17 +124,84 @@
|
|||||||
<string name="pair_requested">طُلب الاقتران</string>
|
<string name="pair_requested">طُلب الاقتران</string>
|
||||||
<string name="pair_succeeded">نجح الاقتران</string>
|
<string name="pair_succeeded">نجح الاقتران</string>
|
||||||
<string name="pairing_request_from">اطلب اقتران من \'%1s\'</string>
|
<string name="pairing_request_from">اطلب اقتران من \'%1s\'</string>
|
||||||
|
<plurals name="incoming_file_title">
|
||||||
|
<item quantity="zero">لا يستقبل شيء</item>
|
||||||
|
<item quantity="one">يستقبل %1$d ملف من %2$s</item>
|
||||||
|
<item quantity="two">يستقبل %1$d ملفات من %2$s</item>
|
||||||
|
<item quantity="few">يستقبل %1$d ملفات من %2$s</item>
|
||||||
|
<item quantity="many">يستقبل %1$d ملفًا من %2$s</item>
|
||||||
|
<item quantity="other">يستقبل %1$d ملف من %2$s</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="incoming_files_text">
|
||||||
|
<item quantity="zero">ملف: %1s</item>
|
||||||
|
<item quantity="one">ملف: %1s</item>
|
||||||
|
<item quantity="two">(الملف %2$d من %3$d) : %1$s</item>
|
||||||
|
<item quantity="few">(الملف %2$d من %3$d) : %1$s</item>
|
||||||
|
<item quantity="many">(الملف %2$d من %3$d) : %1$s</item>
|
||||||
|
<item quantity="other">(الملف %2$d من %3$d) : %1$s</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="outgoing_file_title">
|
||||||
|
<item quantity="zero">لا يرسل شيء</item>
|
||||||
|
<item quantity="one">يرسل %1$d ملف إلى %2$s</item>
|
||||||
|
<item quantity="two">يرسل %1$d ملفات إلى %2$s</item>
|
||||||
|
<item quantity="few">يرسل %1$d ملفات إلى %2$s</item>
|
||||||
|
<item quantity="many">يرسل %1$d ملفًا إلى %2$s</item>
|
||||||
|
<item quantity="other">يرسل %1$d ملف إلى %2$s</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="outgoing_files_text">
|
||||||
|
<item quantity="zero">ملف: %1$s</item>
|
||||||
|
<item quantity="one">ملف: %1$s</item>
|
||||||
|
<item quantity="two">(الملف %2$d من %3$d) : %1$s</item>
|
||||||
|
<item quantity="few">(الملف %2$d من %3$d) : %1$s</item>
|
||||||
|
<item quantity="many">(الملف %2$d من %3$d) : %1$s</item>
|
||||||
|
<item quantity="other">(الملف %2$d من %3$d) : %1$s</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="received_files_title">
|
||||||
|
<item quantity="zero">لم استلم شيئًا</item>
|
||||||
|
<item quantity="one">استُلمت %2$d ملف من %1$s</item>
|
||||||
|
<item quantity="two">استُلمت ملفين من %1$s</item>
|
||||||
|
<item quantity="few">استُلمت %2$d ملفات من %1$s</item>
|
||||||
|
<item quantity="many">استُلمت %2$d ملفًا من %1$s</item>
|
||||||
|
<item quantity="other">استُلمت %2$d ملف من %1$s</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="received_files_fail_title">
|
||||||
|
<item quantity="zero">فشل استلام ملف من %1$s</item>
|
||||||
|
<item quantity="one">فشل استلام ملف من %1$s</item>
|
||||||
|
<item quantity="two">فشل استلام %2$d من %3$d ملفًا من %1$s</item>
|
||||||
|
<item quantity="few">فشل استلام %2$d من %3$d ملفًا من %1$s</item>
|
||||||
|
<item quantity="many">فشل استلام %2$d من %3$d ملفًا من %1$s</item>
|
||||||
|
<item quantity="other">فشل استلام %2$d من %3$d ملفًا من %1$s</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="sent_files_title">
|
||||||
|
<item quantity="zero">لم يرسل شيء إلى %1$s</item>
|
||||||
|
<item quantity="one">أرسل ملف إلى %1$s</item>
|
||||||
|
<item quantity="two">أرسل ملفين إلى %1$s</item>
|
||||||
|
<item quantity="few">أرسل %2$d ملفات إلى %1$s</item>
|
||||||
|
<item quantity="many">أرسل %2$d ملفًا إلى %1$s</item>
|
||||||
|
<item quantity="other">أرسل %2$d ملف إلى %1$s</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="send_files_fail_title">
|
||||||
|
<item quantity="zero">فشل في إرسال ملف إلى %1$s</item>
|
||||||
|
<item quantity="one">فشل في إرسال ملف إلى %1$s</item>
|
||||||
|
<item quantity="two">فشل في إرسال %2$d من %3$d ملفًا إلى %1$s</item>
|
||||||
|
<item quantity="few">فشل في إرسال %2$d من %3$d ملفًا إلى %1$s</item>
|
||||||
|
<item quantity="many">فشل في إرسال %2$d من %3$d ملفًا إلى %1$s</item>
|
||||||
|
<item quantity="other">فشل في إرسال %2$d من %3$d ملفًا إلى %1$s</item>
|
||||||
|
</plurals>
|
||||||
<string name="tap_to_open">اطرق لتفتح</string>
|
<string name="tap_to_open">اطرق لتفتح</string>
|
||||||
<string name="received_file_text">المس لفتح \'%1s\'</string>
|
<string name="received_file_text">اطرق لفتح \'%1s\'</string>
|
||||||
<string name="tap_to_answer">المس للإجابة</string>
|
<string name="cannot_create_file">تعذّر إنشاء الملف %s</string>
|
||||||
|
<string name="tap_to_answer">اطرق للإجابة</string>
|
||||||
<string name="left_click">أرسل نقرة باليسار</string>
|
<string name="left_click">أرسل نقرة باليسار</string>
|
||||||
<string name="right_click">أرسل نقرة باليمين</string>
|
<string name="right_click">أرسل نقرة باليمين</string>
|
||||||
<string name="middle_click">أرسل نقرة بالوسط</string>
|
<string name="middle_click">أرسل نقرة بالوسط</string>
|
||||||
<string name="show_keyboard">أظهر لوحة المفاتيح</string>
|
<string name="show_keyboard">أظهر لوحة المفاتيح</string>
|
||||||
<string name="device_not_paired">الجهاز غير مقترن</string>
|
<string name="device_not_paired">الجهاز غير مقترن</string>
|
||||||
|
<string name="pairing_duplicate_names">تنبيه: هناك عدة أجهزة تحمل نفس الاسم.</string>
|
||||||
<string name="request_pairing">اطلب الاقتران</string>
|
<string name="request_pairing">اطلب الاقتران</string>
|
||||||
<string name="pairing_accept">اقبل</string>
|
<string name="pairing_accept">اقبل</string>
|
||||||
<string name="pairing_reject">ارفض</string>
|
<string name="pairing_reject">ارفض</string>
|
||||||
|
<string name="pairing_explanation">سيؤدي إقران جهازين إلى منحهما إمكانية الوصول إلى بعضهما البعض. أقرن أجهزتك الخاصة بك فقط.</string>
|
||||||
<string name="settings">إعدادات</string>
|
<string name="settings">إعدادات</string>
|
||||||
<string name="mpris_play">شغّل</string>
|
<string name="mpris_play">شغّل</string>
|
||||||
<string name="mpris_pause">ألبث</string>
|
<string name="mpris_pause">ألبث</string>
|
||||||
@ -120,95 +221,165 @@
|
|||||||
<item>دقيقة واحدة</item>
|
<item>دقيقة واحدة</item>
|
||||||
<item>دقيقتان</item>
|
<item>دقيقتان</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string name="mpris_notifications_explanation">يلزم الحصول على إذن الإشعارات لإظهار الوسائط البعيدة في درج الإشعارات</string>
|
||||||
|
<string name="mpris_notification_settings_title">أظهر إشعار التحكم في الوسائط</string>
|
||||||
|
<string name="mpris_notification_settings_summary">اسمح بالتحكم في مشغلات الوسائط دون فتح جسر كِيدِي</string>
|
||||||
<string name="share_to">شارك مع…</string>
|
<string name="share_to">شارك مع…</string>
|
||||||
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
|
<string name="unreachable_device_url_share_text">شاركنا العناوين إلى جهاز لا يمكن الوصول إليه، ستُسلم إليه بمجرد أن يصبح الوصول إليه ممكناً.\n\n</string>
|
||||||
|
<string name="protocol_version">إصدار الميفاق:</string>
|
||||||
<string name="protocol_version_newer">يستخدم هذا الجهاز إصدار ميفاق أحدث</string>
|
<string name="protocol_version_newer">يستخدم هذا الجهاز إصدار ميفاق أحدث</string>
|
||||||
<string name="plugin_settings_with_name">إعدادات %s</string>
|
<string name="plugin_settings_with_name">إعدادات %s</string>
|
||||||
<string name="invalid_device_name">اسم جهاز غير صالح</string>
|
<string name="invalid_device_name">اسم جهاز غير صالح</string>
|
||||||
<string name="shareplugin_text_saved">استُقبل نصّ، حُفظ إلى الحافظة</string>
|
<string name="shareplugin_text_saved">استُقبل نصّ، حُفظ إلى الحافظة</string>
|
||||||
<string name="custom_devices_settings">قائمة أجهزة مخصّصة</string>
|
<string name="custom_devices_settings">قائمة أجهزة مخصّصة</string>
|
||||||
<string name="custom_device_list">أضف أجهزة بميفاق الإنترنت مإ</string>
|
<string name="custom_devices_settings_summary">%d أجهزة مضافة يدوياً</string>
|
||||||
|
<string name="custom_device_list">أضف أجهزة بعنوان IP</string>
|
||||||
<string name="custom_device_deleted">حُذف الجهاز المخصّص</string>
|
<string name="custom_device_deleted">حُذف الجهاز المخصّص</string>
|
||||||
|
<string name="custom_device_list_help">إذا لم يُكتشف جهازك آليّاً يمكنك إضافة عنوان IP الخاص به أو اسم المضيف الخاص به من خلال النقر على زر الإجراء العائم</string>
|
||||||
<string name="custom_device_fab_hint">أضف جهازاً</string>
|
<string name="custom_device_fab_hint">أضف جهازاً</string>
|
||||||
<string name="undo">تراجع</string>
|
<string name="undo">تراجع</string>
|
||||||
<string name="share_notification_preference">إخطارات مزعجة</string>
|
<string name="share_notification_preference">إشعارات مزعجة</string>
|
||||||
<string name="share_notification_preference_summary">اهتزّ وشغّل صوتًا عند استقبال ملفّ</string>
|
<string name="share_notification_preference_summary">اهتزّ وشغّل صوتًا عند استقبال ملفّ</string>
|
||||||
|
<string name="share_destination_customize">خصص مجلد المقصد</string>
|
||||||
|
<string name="share_destination_customize_summary_disabled">ستظهر الملفات المستلمة في التنزيلات</string>
|
||||||
|
<string name="share_destination_customize_summary_enabled">ستُخزن الملفات في المجلد أدناه</string>
|
||||||
<string name="share_destination_folder_preference">مجلد الوجهة</string>
|
<string name="share_destination_folder_preference">مجلد الوجهة</string>
|
||||||
<string name="share">شارك</string>
|
<string name="share">شارك</string>
|
||||||
<string name="share_received_file">شارك \"%s\"</string>
|
<string name="share_received_file">شارك \"%s\"</string>
|
||||||
<string name="title_activity_notification_filter">مرشّح الإخطارات</string>
|
<string name="title_activity_notification_filter">مرشّح الإشعارات</string>
|
||||||
<string name="filter_apps_info">ستُزامن الإخطارات من التّطبيقات المحدّدة.</string>
|
<string name="filter_apps_info">ستُزامن الإشعارات من التّطبيقات المحدّدة.</string>
|
||||||
|
<string name="show_notification_if_screen_off">أرسل إشعارات فقط إذا كانت الشاشة مغلقة</string>
|
||||||
<string name="add_device_dialog_title">أضف جهازاً</string>
|
<string name="add_device_dialog_title">أضف جهازاً</string>
|
||||||
<string name="add_device_hint">اسم المضيف أو عنوان IP</string>
|
<string name="add_device_hint">اسم المضيف أو عنوان IP</string>
|
||||||
|
<string name="sftp_preference_configured_storage_locations">أماكن التّخزين المضبوطة</string>
|
||||||
|
<string name="sftp_preference_add_storage_location_title">أضف مكان تخزين</string>
|
||||||
|
<string name="sftp_preference_edit_storage_location">حرر مكان التخزين</string>
|
||||||
|
<string name="sftp_storage_preference_storage_location">مكان التخزين</string>
|
||||||
|
<string name="sftp_storage_preference_storage_location_already_configured">هذا المكان مضبوط مسبقًا</string>
|
||||||
<string name="sftp_storage_preference_click_to_select">"انقر للاختيار "</string>
|
<string name="sftp_storage_preference_click_to_select">"انقر للاختيار "</string>
|
||||||
<string name="sftp_storage_preference_display_name">اسم العرض</string>
|
<string name="sftp_storage_preference_display_name">اسم العرض</string>
|
||||||
|
<string name="sftp_storage_preference_display_name_already_used">اسم العرض مستخدم مسبقًا</string>
|
||||||
|
<string name="sftp_storage_preference_display_name_cannot_be_empty">اسم العرض لا يمكن أن يكون فارغا</string>
|
||||||
<string name="sftp_action_mode_menu_delete">احذف</string>
|
<string name="sftp_action_mode_menu_delete">احذف</string>
|
||||||
|
<string name="sftp_no_storage_locations_configured">لا توجد مواقع تخزين مضبوطة</string>
|
||||||
|
<string name="sftp_saf_permission_explanation">للوصول إلى الملفات عن بُعد عليك ضبط مواقع التخزين</string>
|
||||||
|
<string name="sftp_manage_storage_permission_explanation">للسماح بالوصول عن بُعد إلى الملفات الموجودة على هذا الجهاز، يجب أن تسمح لـ جسر كِيدِي بإدارة التخزين.</string>
|
||||||
<string name="no_players_connected">لم يُعثر على مشغّلات</string>
|
<string name="no_players_connected">لم يُعثر على مشغّلات</string>
|
||||||
<string name="send_files">أرسل ملفّات</string>
|
<string name="send_files">أرسل ملفّات</string>
|
||||||
<string name="pairing_title">أجهزة «كِيدِي المتّصل»</string>
|
<string name="block_notification_contents">احظر محتويات الإشعار</string>
|
||||||
<string name="pairing_description">الأجهزة الأخرى التي تشغّل «كِيدِي المتّصل» وعلى نفس الشّبكة ستظهر هنا.</string>
|
<string name="block_notification_images">احظر صور الإشعار</string>
|
||||||
|
<string name="pairing_title">أجهزة «جسر كِيدِي»</string>
|
||||||
|
<string name="pairing_description">الأجهزة الأخرى التي تشغّل «جسر كِيدِي» وعلى نفس الشّبكة ستظهر هنا.</string>
|
||||||
<string name="device_rename_title">أعد تسمية الجهاز</string>
|
<string name="device_rename_title">أعد تسمية الجهاز</string>
|
||||||
<string name="device_rename_confirm">أعد التّسمية</string>
|
<string name="device_rename_confirm">أعد التّسمية</string>
|
||||||
<string name="refresh">أنعش</string>
|
<string name="refresh">حدّث</string>
|
||||||
<string name="unreachable_description">الجهاز المقترن هذا لا يمكن الوصول إليه. تأكّد من اتّصاله بنفس الشّبكة.</string>
|
<string name="unreachable_description">الجهاز المقترن هذا لا يمكن الوصول إليه. تأكّد من اتّصاله بنفس الشّبكة.</string>
|
||||||
|
<string name="no_wifi">أنت غير متصل بشبكة واي فاي، لذلك قد لا تتمكن من رؤية أي أجهزة. انقر هنا لتمكين واي فاي.</string>
|
||||||
|
<string name="on_non_trusted_message">ليس على شبكة موثوق بها: الاكتشاف الآليّ معطل.</string>
|
||||||
<string name="no_file_browser">لا متصفّحات ملفّات مثبّتة.</string>
|
<string name="no_file_browser">لا متصفّحات ملفّات مثبّتة.</string>
|
||||||
<string name="pref_plugin_telepathy">أرسل SMS</string>
|
<string name="pref_plugin_telepathy">أرسل رسالة نصية قصيرة</string>
|
||||||
<string name="pref_plugin_telepathy_desc">أرسل رسائل نصّيّة من سطح المكتب</string>
|
<string name="pref_plugin_telepathy_desc">أرسل رسائل نصّيّة من سطح المكتب</string>
|
||||||
<string name="pref_plugin_telepathy_mms">أرسل رسالة قصيرة</string>
|
<string name="pref_plugin_telepathy_mms">أرسل رسالة وسائط</string>
|
||||||
|
<string name="pref_plugin_telepathy_mms_desc">لتتمكن من إرسال رسائل الوسائط المتعددة من جسر كِيدِي، عليك تعيينه كتطبيق الرسائل القصيرة المبدئي.</string>
|
||||||
<string name="findmyphone_title">جِد جهازي</string>
|
<string name="findmyphone_title">جِد جهازي</string>
|
||||||
<string name="findmyphone_title_tablet">جِد جهازي اللوحيّ</string>
|
<string name="findmyphone_title_tablet">جِد جهازي اللوحيّ</string>
|
||||||
<string name="findmyphone_title_tv">جِد تلفازي</string>
|
<string name="findmyphone_title_tv">جِد تلفازي</string>
|
||||||
<string name="findmyphone_description">يرّن هذا الجهاز لتجده</string>
|
<string name="findmyphone_description">يرّن هذا الجهاز لتجده</string>
|
||||||
<string name="findmyphone_found">عثر عليه</string>
|
<string name="findmyphone_found">عثرت عليه</string>
|
||||||
<string name="open">افتح</string>
|
<string name="open">افتح</string>
|
||||||
<string name="close">أغلق</string>
|
<string name="close">أغلق</string>
|
||||||
|
<string name="plugins_need_permission">تحتاج بعض المُلحَقَات إلى أذونات للعمل (انقر للحصول على مزيد من المعلومات):</string>
|
||||||
|
<string name="permission_explanation">تحتاج هذه الملحقة إلى أذونات للعمل</string>
|
||||||
|
<string name="all_permissions_granted">جميع الأذونات ممنوحة 🎉</string>
|
||||||
|
<string name="optional_permission_explanation">تحتاج إلى منح أذونات إضافية لتمكين جميع الوظائف</string>
|
||||||
|
<string name="plugins_need_optional_permission">تحتوي بعض المُلحقات على ميزات معطلة بسبب عدم وجود إذن (انقر للحصول على مزيد من المعلومات):</string>
|
||||||
|
<string name="share_optional_permission_explanation">لتلقي الملفات تحتاج إلى السماح بالوصول إلى التخزين</string>
|
||||||
|
<string name="share_notifications_explanation">لرؤية التقدم المحرز عند إرسال واستقبال الملفات تحتاج إلى السماح بالإشعارات</string>
|
||||||
|
<string name="telepathy_permission_explanation">لقراءة الرسائل النصية القصيرة وكتابتها من سطح المكتب، تحتاج إلى منح الإذن للرسائل النصية القصيرة</string>
|
||||||
|
<string name="telephony_permission_explanation">للاطلاع على المكالمات الهاتفية على سطح المكتب، تحتاج إلى منح الإذن لسجلات المكالمات الهاتفية وحالة الهاتف</string>
|
||||||
|
<string name="telephony_optional_permission_explanation">للاطلاع على اسم المتراسل بدلاً من رقم الهاتف، تحتاج إلى منح حق الوصول إلى المتراسلين على الهاتف</string>
|
||||||
|
<string name="contacts_permission_explanation">لمشاركة دفتر متراسليك مع سطح المكتب، تحتاج إلى منح إذن الوصول إلى المتراسلين</string>
|
||||||
|
<string name="contacts_per_device_confirmation">ستُنسخ جهات اتصال هاتفك إلى هذا الجهاز، بحيث يمكن استخدامها من قبل تطبيق جسر كِيدِي للرسائل النصية القصيرة والتطبيقات الأخرى.</string>
|
||||||
<string name="select_ringtone">اختر النغمة</string>
|
<string name="select_ringtone">اختر النغمة</string>
|
||||||
<string name="telephony_pref_blocked_title">أرقام محظورة</string>
|
<string name="telephony_pref_blocked_title">أرقام محظورة</string>
|
||||||
|
<string name="telephony_pref_blocked_dialog_desc">لا تعرض المكالمات والرسائل النصية القصيرة من هذه الأرقام. يرجى تحديد رقم واحد لكل سطر</string>
|
||||||
<string name="mpris_coverart_description">الصورة الفنية للوسيط الحالي</string>
|
<string name="mpris_coverart_description">الصورة الفنية للوسيط الحالي</string>
|
||||||
<string name="settings_icon_description">أيقونة الإعدادات</string>
|
<string name="settings_icon_description">أيقونة الإعدادات</string>
|
||||||
<string name="presenter_fullscreen">ملء الشّاشة</string>
|
<string name="presenter_fullscreen">ملء الشّاشة</string>
|
||||||
<string name="presenter_exit">اخرج من العرض التقديمي</string>
|
<string name="presenter_exit">اخرج من العرض التقديمي</string>
|
||||||
|
<string name="presenter_lock_tip">يمكنك قفل جهازك واستخدام مفاتيح الصوت للانتقال إلى الشريحة السابقة/التالية</string>
|
||||||
<string name="add_command">أضف أمراً</string>
|
<string name="add_command">أضف أمراً</string>
|
||||||
<string name="addcommand_explanation">لا يوجد أوامر مسجلة</string>
|
<string name="addcommand_explanation">لا يوجد أوامر مسجلة</string>
|
||||||
|
<string name="addcommand_explanation2">يمكنك إضافة أوامر جديدة في إعدادات نظام جسر كِيدِي في إعدادات نظام جسر كِيدِي</string>
|
||||||
|
<string name="add_command_description">يمكنك إضافة أوامر على سطح المكتب</string>
|
||||||
<string name="pref_plugin_mprisreceiver">متحكم الوسائط</string>
|
<string name="pref_plugin_mprisreceiver">متحكم الوسائط</string>
|
||||||
<string name="notification_channel_default">إخطارات أخرى</string>
|
<string name="pref_plugin_mprisreceiver_desc">تحكم في مشغلات الوسائط في هاتفك من جهاز آخر</string>
|
||||||
|
<string name="notification_channel_default">الإشعارات الأخرى</string>
|
||||||
|
<string name="notification_channel_persistent">مؤشر مستمر</string>
|
||||||
<string name="notification_channel_media_control">متحكم الوسائط</string>
|
<string name="notification_channel_media_control">متحكم الوسائط</string>
|
||||||
|
<string name="notification_channel_filetransfer">نقل الملفات الواردة</string>
|
||||||
|
<string name="notification_channel_filetransfer_upload">نقل الملفات الصادرة</string>
|
||||||
|
<string name="notification_channel_filetransfer_error">خطأ في النقل الملف</string>
|
||||||
<string name="notification_channel_high_priority">مرتفعة الأولوية</string>
|
<string name="notification_channel_high_priority">مرتفعة الأولوية</string>
|
||||||
<string name="mpris_stop">أوقف المشغل الحالي</string>
|
<string name="mpris_stop">أوقف المشغل الحالي</string>
|
||||||
<string name="copy_url_to_clipboard">انسخ المسار إلى الحافظة</string>
|
<string name="copy_url_to_clipboard">انسخ المسار إلى الحافظة</string>
|
||||||
<string name="clipboard_toast">نُسخ إلى الحافظة</string>
|
<string name="clipboard_toast">نُسخ إلى الحافظة</string>
|
||||||
<string name="runcommand_notreachable">الجهاز غير قابل الوصول</string>
|
<string name="runcommand_notreachable">الجهاز غير قابل الوصول</string>
|
||||||
<string name="runcommand_notpaired">الجهاز غير مقترن</string>
|
<string name="runcommand_notpaired">الجهاز غير مقترن</string>
|
||||||
|
<string name="runcommand_nosuchdevice">لا يوجد جهاز من هذا القبيل</string>
|
||||||
|
<string name="runcommand_noruncommandplugin">لم يُمكّن ملحقة تشغيل الأوامر في هذا الجهاز</string>
|
||||||
<string name="runcommand_category_device_controls_title">متحكمات الجهاز</string>
|
<string name="runcommand_category_device_controls_title">متحكمات الجهاز</string>
|
||||||
|
<string name="runcommand_device_controls_summary">إذا كان جهازك يدعم عناصر تحكم الجهاز، فستظهر الأوامر التي ضبطتها هناك.</string>
|
||||||
|
<string name="set_runcommand_name_as_title">اجعل اسم الأمر كعنوان</string>
|
||||||
|
<string name="runcommand_name_as_title_title">اعرض الاسم كعنوان</string>
|
||||||
<string name="pref_plugin_findremotedevice">اعثر على جهاز بعيد</string>
|
<string name="pref_plugin_findremotedevice">اعثر على جهاز بعيد</string>
|
||||||
<string name="pref_plugin_findremotedevice_desc">رنّ على الجهاز البعيد</string>
|
<string name="pref_plugin_findremotedevice_desc">رنّ على الجهاز البعيد</string>
|
||||||
<string name="ring">رّن</string>
|
<string name="ring">رّن</string>
|
||||||
<string name="pref_plugin_systemvolume">صوت النظام</string>
|
<string name="pref_plugin_systemvolume">صوت النظام</string>
|
||||||
|
<string name="pref_plugin_systemvolume_desc">تحكّم في مستوى صوت النظام للجهاز البعيد</string>
|
||||||
<string name="mute">اكتم</string>
|
<string name="mute">اكتم</string>
|
||||||
<string name="all">الكلّ</string>
|
<string name="all">الكلّ</string>
|
||||||
<string name="devices">الأجهزة</string>
|
<string name="devices">الأجهزة</string>
|
||||||
<string name="settings_rename">اسم الجهاز</string>
|
<string name="settings_rename">اسم الجهاز</string>
|
||||||
<string name="settings_dark_mode">سمة مظلمة</string>
|
<string name="settings_dark_mode">سمة مظلمة</string>
|
||||||
|
<string name="settings_export_logs">صدّر سجل جسر كِيدِي</string>
|
||||||
|
<string name="settings_export_logs_text">أنشئ ملفًا يحتوي على معلومات التنفيذ التي يمكن أن تساعد في استكشاف المشكلات وإصلاحها.</string>
|
||||||
<string name="settings_more_settings_title">المزيد من الإعدادات</string>
|
<string name="settings_more_settings_title">المزيد من الإعدادات</string>
|
||||||
<string name="setting_persistent_notification_oreo">الإخطارات المستمرّة</string>
|
<string name="settings_more_settings_text">يمكن العثور على إعدادات لكل جهاز ضمن ”إعدادات الملحقة“ من داخل الجهاز.</string>
|
||||||
|
<string name="setting_persistent_notification">أظهر الإشعارات المستمرّة</string>
|
||||||
|
<string name="setting_persistent_notification_oreo">الإشعارات المستمرّة</string>
|
||||||
|
<string name="setting_persistent_notification_description">اطرق للتمكين/التعطيل في إعدادات الإشعارات</string>
|
||||||
<string name="extra_options">الخيارات الإضافية</string>
|
<string name="extra_options">الخيارات الإضافية</string>
|
||||||
<string name="privacy_options">خيارات الخصوصية</string>
|
<string name="privacy_options">خيارات الخصوصية</string>
|
||||||
<string name="set_privacy_options">حدد خيارات الخصوصية</string>
|
<string name="set_privacy_options">حدد خيارات الخصوصية</string>
|
||||||
<string name="block_contents">امنح محتويات الإخطارات</string>
|
<string name="block_contents">امنح محتويات الإشعارات</string>
|
||||||
<string name="block_images">امنع الصور في الإخطارات</string>
|
<string name="block_images">امنع الصور في الإشعارات</string>
|
||||||
<string name="notification_channel_receivenotification">إخطارات من أجهزة أخرى</string>
|
<string name="notification_channel_receivenotification">إشعارات من أجهزة أخرى</string>
|
||||||
|
<string name="no_app_for_opening">لا يوجد تطبيق مناسب لفتح هذا الملف</string>
|
||||||
|
<string name="remote_keyboard_service">لوحة مفاتيح بعيده لجسر كِيدِي</string>
|
||||||
<string name="presenter_pointer">المؤشر</string>
|
<string name="presenter_pointer">المؤشر</string>
|
||||||
<string name="trusted_networks">الشّبكات الموثوقة</string>
|
<string name="trusted_networks">الشّبكات الموثوقة</string>
|
||||||
<string name="add_trusted_network">أضف %s</string>
|
<string name="trusted_networks_desc">اقَصْر الاكتشاف الآليّ على الشبكات المعروفة</string>
|
||||||
|
<string name="add_trusted_network">أضف %1s</string>
|
||||||
|
<string name="empty_trusted_networks_list_text">لم تضف أي شبكة موثوق بها حتى الآن</string>
|
||||||
<string name="allow_all_networks_text">اسمح للكل</string>
|
<string name="allow_all_networks_text">اسمح للكل</string>
|
||||||
<string name="location_permission_needed_title">الإذن مطلوب</string>
|
<string name="location_permission_needed_title">الإذن مطلوب</string>
|
||||||
|
<string name="bluetooth_permission_needed_desc">يحتاج جسر كِيدِي إلى إذن للاتصال بالأجهزة القريبة لإتاحة الأجهزة المقترنة باستخدام البلوتوث في جسر كِيدِي.</string>
|
||||||
|
<string name="location_permission_needed_desc">يحتاج جسر كِيدِي إلى إذن الموقع في الخلفية لمعرفة شبكة الواي فاي التي تتصل بها حتى عندما يكون التطبيق في الخلفية. وذلك لأنه يمكن استخدام اسم شبكات الواي فاي من حولك للعثور على موقعك، حتى وإن لم يكن هذا ما يفعله جسر كِيدِي.</string>
|
||||||
|
<string name="clipboard_android_x_incompat">أزال أندرويد 10 الوصول للحافظة إلى جميع التطبيقات. ستعطل هذه الملحقة.</string>
|
||||||
|
<string name="mpris_open_url">استمر في التشغيل هنا</string>
|
||||||
|
<string name="cant_open_url">تعذر فتح العنوان للاستمرار في التشغيل</string>
|
||||||
<string name="bigscreen_home">المنزل</string>
|
<string name="bigscreen_home">المنزل</string>
|
||||||
<string name="bigscreen_up">أعلى</string>
|
<string name="bigscreen_up">أعلى</string>
|
||||||
<string name="bigscreen_left">يسار</string>
|
<string name="bigscreen_left">يسار</string>
|
||||||
<string name="bigscreen_select">اختر</string>
|
<string name="bigscreen_select">اختر</string>
|
||||||
<string name="bigscreen_right">يمين</string>
|
<string name="bigscreen_right">يمين</string>
|
||||||
<string name="bigscreen_down">أسفل</string>
|
<string name="bigscreen_down">أسفل</string>
|
||||||
<string name="bigscreen_mic">اللاقط</string>
|
<string name="bigscreen_mic">ميكروفون</string>
|
||||||
<string name="pref_plugin_bigscreen">متحكم الشاشة الكبيرة</string>
|
<string name="pref_plugin_bigscreen">متحكم الشاشة الكبيرة</string>
|
||||||
|
<string name="pref_plugin_bigscreen_desc">استخدم جهازك كجهاز تحكم عن بُعد لشاشة البلازما الكبيرة</string>
|
||||||
|
<string name="bigscreen_optional_permission_explanation">لمشاركة إدخال الميكروفون من هاتفك تحتاج إلى إتاحة الوصول إلى إدخال الصوت في الهاتف</string>
|
||||||
<string name="bigscreen_speech_extra_prompt">حديث</string>
|
<string name="bigscreen_speech_extra_prompt">حديث</string>
|
||||||
<string name="message_reply_label">ردّ</string>
|
<string name="message_reply_label">ردّ</string>
|
||||||
<string name="mark_as_read_label">علّم كمقروءة</string>
|
<string name="mark_as_read_label">علّم كمقروءة</string>
|
||||||
@ -227,13 +398,13 @@
|
|||||||
<string name="theme_dialog_title">اختر سمة</string>
|
<string name="theme_dialog_title">اختر سمة</string>
|
||||||
<string-array name="theme_list">
|
<string-array name="theme_list">
|
||||||
<item>معينة بواسطة حافظ البطارية</item>
|
<item>معينة بواسطة حافظ البطارية</item>
|
||||||
<item>خفيف</item>
|
<item>فاتح</item>
|
||||||
<item>مظلمة</item>
|
<item>مظلمة</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="theme_list_v28">
|
<string-array name="theme_list_v28">
|
||||||
<item>افتراضيات النظام</item>
|
<item>مبدئيات النظام</item>
|
||||||
<item>خفيف</item>
|
<item>فاتح</item>
|
||||||
<item>مظلمة</item>
|
<item>مظلم</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="report_bug">أبلغ عن علة</string>
|
<string name="report_bug">أبلغ عن علة</string>
|
||||||
<string name="donate">تبرّع</string>
|
<string name="donate">تبرّع</string>
|
||||||
@ -245,7 +416,7 @@
|
|||||||
<string name="thanks_to">الشكر إلى</string>
|
<string name="thanks_to">الشكر إلى</string>
|
||||||
<string name="easter_egg">بيض الفصح</string>
|
<string name="easter_egg">بيض الفصح</string>
|
||||||
<string name="email_contributor">راسل المساهم:\n%s</string>
|
<string name="email_contributor">راسل المساهم:\n%s</string>
|
||||||
<string name="visit_contributors_homepage">زر صفحة المساهم الرئيسية\n%s</string>
|
<string name="visit_contributors_homepage">زر صفحة المساهم الرئيسة\n%s</string>
|
||||||
<string name="version">الإصدار %s</string>
|
<string name="version">الإصدار %s</string>
|
||||||
<string name="about_kde">عن كِيدِي</string>
|
<string name="about_kde">عن كِيدِي</string>
|
||||||
<string name="kde_be_free">كِيدِي- كن حرًّا!</string>
|
<string name="kde_be_free">كِيدِي- كن حرًّا!</string>
|
||||||
@ -253,12 +424,44 @@
|
|||||||
<string name="konqi">كوينكي</string>
|
<string name="konqi">كوينكي</string>
|
||||||
<string name="rise_up">ارفع</string>
|
<string name="rise_up">ارفع</string>
|
||||||
<string name="rise_down">اخفض</string>
|
<string name="rise_down">اخفض</string>
|
||||||
<string name="click_here_to_type">اطُرق لتكتب</string>
|
<string name="click_here_to_type">اطُرق هنا لتكتب</string>
|
||||||
<string name="clear_compose">امسح</string>
|
<string name="clear_compose">امحُ</string>
|
||||||
<string name="send_compose">أرسل</string>
|
<string name="send_compose">أرسل</string>
|
||||||
<string name="open_compose_send">ألف نص</string>
|
<string name="compose_send_title">اكتب أرسل</string>
|
||||||
<string name="maintainer_and_developer">المصين ومطوّر</string>
|
<string name="open_compose_send">اكتب نصًا</string>
|
||||||
|
<string name="double_tap_to_drag">طرق مزدوج للسحب</string>
|
||||||
|
<string name="hold_to_drag">اضغط مع الاستمرار للسحب</string>
|
||||||
|
<string name="about_kde_about"><h1>حول</h1>" "<p>كيدي مجتمع عالمي من مهندسي البرمجيات والفنانين والكتاب والمترجمين والمبدعين الملتزمين بتطوير البرمجيات الحرة. تُنتج كيدي بيئة سطح المكتب بلازما، ومئات التطبيقات، والعديد من مكتبات البرمجيات التي تدعمها.</p>" "<p>كيدي مشروع تعاوني: لا تتحكم جهة واحدة في توجهاته أو منتجاته. بل نعمل معًا لتحقيق هدفنا المشترك المتمثل في بناء أفضل برمجيات حرة في العالم. الجميع مدعوون للانضمام والمساهمة في كيدي، بمن فيهم أنت.</p>" زر <a href=https://www.kde.org/>https://www.kde.org/</a> للحصول على مزيد من المعلومات حول مجتمع كيدي والبرمجيات التي ننتجها"</string>
|
||||||
|
<string name="about_kde_report_bugs_or_wishes"><h1>الإبلاغ عن الأخطاء أو الرغبات</h1> <p>يمكن دائمًا تحسين البرامج، وفريق كيدي مستعدٌّ لذلك. ومع ذلك، يجب عليك - كمستخدم - إبلاغنا عندما لا يعمل شيءٌ ما كما هو متوقع أو عندما يكون من الممكن تحسينه.</p> <p>تحتوي كيدي على نظام تتبع للأخطاء. تفضل بزيارة <a href=https://bugs.kde.org/>https://bugs.kde.org/</a> أو استخدم زر \"الإبلاغ عن خطأ\" من شاشة \"حول\" للإبلاغ عن الأخطاء.</p> إذا كانت لديك أي اقتراحات للتحسين، فنرحب بك باستخدام نظام تتبع الأخطاء لتسجيل رغبتك. تأكد من استخدام مستوى الخطورة المسمى \"قائمة الأمنيات\".</string>
|
||||||
|
<string name="about_kde_join_kde"><h1>انضم إلى كيدي</h1> <p>لا يلزم أن تكون مطور برامج لكي تكون عضوًا في فريق كيدي. يمكنك الانضمام إلى فرق اللغات التي تترجم واجهات البرامج. يمكنك توفير الرسومات والموضوعات والأصوات والوثائق المُحسّنة. القرار لك! <p>زر <a href=https://community.kde.org/Get_Involved>https://community.kde.org/Get_Involved</a> للحصول على معلومات حول بعض المشاريع التي يمكنك المشاركة فيها.</p> إذا كنت بحاجة إلى مزيد من المعلومات أو الوثائق، فإن زيارة <a href=https://techbase.kde.org/>https://techbase.kde.org/</a> ستوفر لك ما تحتاجه.</string>
|
||||||
|
<string name="about_kde_support_kde">"<h1>دعم كيدي</h1> <p>برامج كيدي متاحة دائمًا بالمجان، ولكن إنشاءها ليس مجانيًا.</p> <p>لدعم التطوير، أسس مجتمع كيدي KDE e.V.، وهي منظمة غير ربحية تأسست بشكل قانوني في ألمانيا. تمثل KDE e.V. مجتمع كيدي في الشؤون القانونية والمالية. انظر <a href=https://ev.kde.org/>https://ev.kde.org/</a> للحصول على معلومات حول KDE e.V.</p> <p>تستفيد كيدي من العديد من أنواع المساهمات، بما في ذلك المساهمات المالية. نحن نستخدم الأموال لتعويض الأعضاء وغيرهم عن النفقات التي يتكبد عند المساهمة. وتستخدم الأموال للدعم القانوني وتنظيم المؤتمرات والاجتماعات.</p> <p>نود أن نشجعكم على دعم جهودنا من خلال التبرع المالي، باستخدام إحدى الطرق الموضحة في <a href=https://www.kde.org/community/donations/>https://www.kde.org/community/donations/</a>.</p> نشكركم جزيل الشكر مقدمًا على دعمكم."</string>
|
||||||
|
<string name="maintainer_and_developer">الصائن ومطوّر</string>
|
||||||
<string name="developer">مطوّر</string>
|
<string name="developer">مطوّر</string>
|
||||||
|
<string name="apple_support">دعم ماك أو إس. العمل على دعم iOS</string>
|
||||||
<string name="bug_fixes_and_general_improvements">إصلاح علل وتحسينات عامة</string>
|
<string name="bug_fixes_and_general_improvements">إصلاح علل وتحسينات عامة</string>
|
||||||
|
<string name="samoilenko_yuri_task">تنفيذ SFTP، وإصلاح الأخطاء والتحسينات العامة</string>
|
||||||
|
<string name="aniket_kumar_task">تحسينات ملحق الرسائل النصية القصيرة</string>
|
||||||
|
<string name="alex_fiestas_task">تحسينات ملحق المتراسلين</string>
|
||||||
|
<string name="maxim_leshchenko_task">تحسينات واجهة المستخدم وصفحة ”حول“ هذه الصفحة</string>
|
||||||
|
<string name="holger_kaelberer_task">ملحق لوحة المفاتيح عن بُعد وإصلاح الأخطاء</string>
|
||||||
|
<string name="saikrishna_arcot_task">دعم استخدام لوحة المفاتيح في ملحق الإدخال عن بُعد، وإصلاح الأخطاء والتحسينات العامة</string>
|
||||||
|
<string name="shellwen_chen_task">تحسين أمان SFTP، وتحسين قابلية صيانة هذا المشروع، وإصلاح الأخطاء والتحسينات العامة</string>
|
||||||
|
<string name="everyone_else">كل من ساهم في جسر كِيدِي على مدار السنوات الماضية</string>
|
||||||
<string name="send_clipboard">أرسل الحافظة</string>
|
<string name="send_clipboard">أرسل الحافظة</string>
|
||||||
|
<string name="tap_to_execute">اطرق لتنفيذه</string>
|
||||||
|
<string name="plugin_stats">ملحقة الإحصائيات</string>
|
||||||
|
<string name="enable_udp_broadcast">مكّن اكتشاف الجهاز عن طريق UDP</string>
|
||||||
|
<string name="enable_bluetooth">مكّن بلوتوث (بيتا)</string>
|
||||||
|
<string name="receive_notifications_permission_explanation">يجب السماح بتلقي الإشعارات من الأجهزة الأخرى</string>
|
||||||
|
<string name="findmyphone_notifications_explanation">إذن الإشعارات مطلوب حتى يتمكن الهاتف من الرنين عندما يكون التطبيق في الخلفية</string>
|
||||||
|
<string name="no_notifications">الإشعارات معطلة، لن تتلقى إشعارات الأزواج الواردة.</string>
|
||||||
|
<string name="mpris_keepwatching">استمر في التشغيل</string>
|
||||||
|
<string name="mpris_keepwatching_settings_title">استمر في التشغيل</string>
|
||||||
|
<string name="mpris_keepwatching_settings_summary">أظهر إشعارًا صامتًا للمواصلة التشغيل على هذا الجهاز بعد إغلاق الوسائط</string>
|
||||||
|
<string name="notification_channel_keepwatching">استمر في التشغيل</string>
|
||||||
|
<string name="ping_result">تعقبت في %1$d ميلي ثانية</string>
|
||||||
|
<string name="ping_failed">تعذر الوصول إلى الجهاز</string>
|
||||||
|
<string name="ping_in_progress">يتعقب…</string>
|
||||||
|
<string name="device_host_invalid">المضيف غير صالح. استخدم اسم مضيف أو IPv4 أو IPv6 صالحاً</string>
|
||||||
|
<string name="device_host_duplicate">المضيف موجود مسبقًا في القائمة</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
<string name="error_not_reachable">Устройството е недостъпно</string>
|
<string name="error_not_reachable">Устройството е недостъпно</string>
|
||||||
<string name="error_already_paired">Устройството вече е сдвоено</string>
|
<string name="error_already_paired">Устройството вече е сдвоено</string>
|
||||||
<string name="error_timed_out">Просрочка</string>
|
<string name="error_timed_out">Просрочка</string>
|
||||||
|
<string name="error_clocks_not_match">Часовниците на устройствата не са синхронизирани</string>
|
||||||
<string name="error_canceled_by_user">Отхвърлена от потребителя</string>
|
<string name="error_canceled_by_user">Отхвърлена от потребителя</string>
|
||||||
<string name="error_canceled_by_other_peer">Отказана от другата страна</string>
|
<string name="error_canceled_by_other_peer">Отказана от другата страна</string>
|
||||||
<string name="encryption_info_title">Информация за криптиране</string>
|
<string name="encryption_info_title">Информация за криптиране</string>
|
||||||
@ -190,8 +191,8 @@
|
|||||||
<string name="mpris_notification_settings_title">Показване на известие за управление на медиите</string>
|
<string name="mpris_notification_settings_title">Показване на известие за управление на медиите</string>
|
||||||
<string name="mpris_notification_settings_summary">Разрешаване на управлението на медийните плейъри, без да отваряте KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Разрешаване на управлението на медийните плейъри, без да отваряте KDE Connect</string>
|
||||||
<string name="share_to">Споделяне към...</string>
|
<string name="share_to">Споделяне към...</string>
|
||||||
<string name="unreachable_device">%s (не е достъпно)</string>
|
|
||||||
<string name="unreachable_device_url_share_text">URL адресите, споделени към недостъпно устройство, ще бъдат доставени до него, когато то стане достъпно.\n\n</string>
|
<string name="unreachable_device_url_share_text">URL адресите, споделени към недостъпно устройство, ще бъдат доставени до него, когато то стане достъпно.\n\n</string>
|
||||||
|
<string name="protocol_version">Версия на протокол:</string>
|
||||||
<string name="protocol_version_newer">Това устройство използва по-нова версия на протокола</string>
|
<string name="protocol_version_newer">Това устройство използва по-нова версия на протокола</string>
|
||||||
<string name="plugin_settings_with_name">%s настройки</string>
|
<string name="plugin_settings_with_name">%s настройки</string>
|
||||||
<string name="invalid_device_name">Невалидно име на устройство</string>
|
<string name="invalid_device_name">Невалидно име на устройство</string>
|
||||||
@ -307,6 +308,8 @@
|
|||||||
<string name="devices">Устройства</string>
|
<string name="devices">Устройства</string>
|
||||||
<string name="settings_rename">Име на устройство</string>
|
<string name="settings_rename">Име на устройство</string>
|
||||||
<string name="settings_dark_mode">Тъмна тема</string>
|
<string name="settings_dark_mode">Тъмна тема</string>
|
||||||
|
<string name="settings_export_logs">Експортиране на дневниците на KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">Генерирайте файл с информация за изпълнени команди, която може да помогне за отстраняването на проблеми.</string>
|
||||||
<string name="settings_more_settings_title">Още настройки</string>
|
<string name="settings_more_settings_title">Още настройки</string>
|
||||||
<string name="settings_more_settings_text">Настройките за всяко устройство могат да бъдат намерени в раздел \"Настройки на плъгина\" в рамките на устройство.</string>
|
<string name="settings_more_settings_text">Настройките за всяко устройство могат да бъдат намерени в раздел \"Настройки на плъгина\" в рамките на устройство.</string>
|
||||||
<string name="setting_persistent_notification">Показване на постоянна нотификация</string>
|
<string name="setting_persistent_notification">Показване на постоянна нотификация</string>
|
||||||
|
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Envia un clic del mig</string>
|
<string name="middle_click">Envia un clic del mig</string>
|
||||||
<string name="show_keyboard">Mostra el teclat</string>
|
<string name="show_keyboard">Mostra el teclat</string>
|
||||||
<string name="device_not_paired">El dispositiu no està aparellat</string>
|
<string name="device_not_paired">El dispositiu no està aparellat</string>
|
||||||
|
<string name="pairing_duplicate_names">Precaució: hi ha diversos dispositius amb el mateix nom.</string>
|
||||||
<string name="request_pairing">Demana aparellar</string>
|
<string name="request_pairing">Demana aparellar</string>
|
||||||
<string name="pairing_accept">Accepta</string>
|
<string name="pairing_accept">Accepta</string>
|
||||||
<string name="pairing_reject">Rebutja</string>
|
<string name="pairing_reject">Rebutja</string>
|
||||||
|
<string name="pairing_explanation">L\'aparellament de dos dispositius els donarà accés l\'un a l\'altre. Només aparelleu els vostres propis dispositius.</string>
|
||||||
<string name="settings">Arranjament</string>
|
<string name="settings">Arranjament</string>
|
||||||
<string name="mpris_play">Reprodueix</string>
|
<string name="mpris_play">Reprodueix</string>
|
||||||
<string name="mpris_pause">Pausa</string>
|
<string name="mpris_pause">Pausa</string>
|
||||||
@ -191,7 +193,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Mostra les notificacions dels reproductors</string>
|
<string name="mpris_notification_settings_title">Mostra les notificacions dels reproductors</string>
|
||||||
<string name="mpris_notification_settings_summary">Permet controlar els reproductors multimèdia sense obrir el KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Permet controlar els reproductors multimèdia sense obrir el KDE Connect</string>
|
||||||
<string name="share_to">Comparteix amb…</string>
|
<string name="share_to">Comparteix amb…</string>
|
||||||
<string name="unreachable_device">%s (no s\'hi pot accedir)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Els URL compartits amb un dispositiu no accessible es lliuraran un cop s\'hi pugui accedir.\n\n</string>
|
<string name="unreachable_device_url_share_text">Els URL compartits amb un dispositiu no accessible es lliuraran un cop s\'hi pugui accedir.\n\n</string>
|
||||||
<string name="protocol_version">Versió del protocol:</string>
|
<string name="protocol_version">Versió del protocol:</string>
|
||||||
<string name="protocol_version_newer">Aquest dispositiu usa una versió nova del protocol</string>
|
<string name="protocol_version_newer">Aquest dispositiu usa una versió nova del protocol</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Dispositius</string>
|
<string name="devices">Dispositius</string>
|
||||||
<string name="settings_rename">Nom del dispositiu</string>
|
<string name="settings_rename">Nom del dispositiu</string>
|
||||||
<string name="settings_dark_mode">Tema fosc</string>
|
<string name="settings_dark_mode">Tema fosc</string>
|
||||||
|
<string name="settings_export_logs">Exporta els registres del KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">Genera un fitxer amb informació d\'execució que pot ajudar a resoldre problemes.</string>
|
||||||
<string name="settings_more_settings_title">Més opcions</string>
|
<string name="settings_more_settings_title">Més opcions</string>
|
||||||
<string name="settings_more_settings_text">La configuració per dispositiu es pot trobar a «Arranjament dels connectors» des d\'un dispositiu.</string>
|
<string name="settings_more_settings_text">La configuració per dispositiu es pot trobar a «Arranjament dels connectors» des d\'un dispositiu.</string>
|
||||||
<string name="setting_persistent_notification">Mostra les notificacions persistents</string>
|
<string name="setting_persistent_notification">Mostra les notificacions persistents</string>
|
||||||
@ -393,7 +397,7 @@
|
|||||||
<string name="send_compose">Envia</string>
|
<string name="send_compose">Envia</string>
|
||||||
<string name="compose_send_title">Títol de l\'enviament</string>
|
<string name="compose_send_title">Títol de l\'enviament</string>
|
||||||
<string name="open_compose_send">Redacta text</string>
|
<string name="open_compose_send">Redacta text</string>
|
||||||
<string name="double_tap_to_drag">Dos tocs per a arrossegar</string>
|
<string name="double_tap_to_drag">Toc doble per a arrossegar</string>
|
||||||
<string name="hold_to_drag">Mantenir premut per a arrossegar</string>
|
<string name="hold_to_drag">Mantenir premut per a arrossegar</string>
|
||||||
<string name="about_kde_about"><h1>Quant al</h1> <p>KDE és una comunitat mundial d\'enginyers, artistes, escriptors, traductors i creadors de programari compromesos amb el desenvolupament de <a href=https://www.gnu.org/philosophy/free-sw.html>programari lliure</a>. KDE produeix l\'entorn d\'escriptori Plasma, centenars d\'aplicacions i moltes biblioteques de programari que els donen suport.</p> <p>KDE és una empresa en cooperativa: cap entitat controla la seva direcció o els productes. En el seu lloc, treballem junts per a aconseguir l\'objectiu comú de construir el millor programari lliure del món. Tothom hi és benvingut a <a href=https://community.kde.org/Get_Involved>unir-se i contribuir</a> a KDE, inclosos vosaltres.</p> Visiteu <a href=https://www.kde.org/ca/>https://www.kde.org/ca/</a> per a obtenir més informació sobre la comunitat KDE i el programari que produïm.</string>
|
<string name="about_kde_about"><h1>Quant al</h1> <p>KDE és una comunitat mundial d\'enginyers, artistes, escriptors, traductors i creadors de programari compromesos amb el desenvolupament de <a href=https://www.gnu.org/philosophy/free-sw.html>programari lliure</a>. KDE produeix l\'entorn d\'escriptori Plasma, centenars d\'aplicacions i moltes biblioteques de programari que els donen suport.</p> <p>KDE és una empresa en cooperativa: cap entitat controla la seva direcció o els productes. En el seu lloc, treballem junts per a aconseguir l\'objectiu comú de construir el millor programari lliure del món. Tothom hi és benvingut a <a href=https://community.kde.org/Get_Involved>unir-se i contribuir</a> a KDE, inclosos vosaltres.</p> Visiteu <a href=https://www.kde.org/ca/>https://www.kde.org/ca/</a> per a obtenir més informació sobre la comunitat KDE i el programari que produïm.</string>
|
||||||
<string name="about_kde_report_bugs_or_wishes"><h1>Informeu dels errors o desitjos</h1> <p>El programari sempre es pot millorar, i l\'equip del KDE està a punt per a fer-ho. No obstant això, l\'usuari, ha de dir-nos quan alguna cosa no funciona com s\'esperava o si podria fer-se millor.</p> <p>El KDE té un sistema de seguiment d\'errors. Per a informar-ne d\'un, visiteu <a href=https://bugs.kde.org/>https://bugs.kde.org/</a> o useu el botó «Informeu d\'un error» des de la pantalla Quant al.</p> Si teniu un suggeriment de millora, podeu usar el sistema de seguiment d\'errors per a enregistrar el vostre desig. Assegureu-vos d\'usar la severitat anomenada «Llista de desitjos» (Wishlist).</string>
|
<string name="about_kde_report_bugs_or_wishes"><h1>Informeu dels errors o desitjos</h1> <p>El programari sempre es pot millorar, i l\'equip del KDE està a punt per a fer-ho. No obstant això, l\'usuari, ha de dir-nos quan alguna cosa no funciona com s\'esperava o si podria fer-se millor.</p> <p>El KDE té un sistema de seguiment d\'errors. Per a informar-ne d\'un, visiteu <a href=https://bugs.kde.org/>https://bugs.kde.org/</a> o useu el botó «Informeu d\'un error» des de la pantalla Quant al.</p> Si teniu un suggeriment de millora, podeu usar el sistema de seguiment d\'errors per a enregistrar el vostre desig. Assegureu-vos d\'usar la severitat anomenada «Llista de desitjos» (Wishlist).</string>
|
||||||
|
@ -206,7 +206,6 @@
|
|||||||
<string name="mpris_notification_settings_title">Obrazit oznámení pro ovládání médií</string>
|
<string name="mpris_notification_settings_title">Obrazit oznámení pro ovládání médií</string>
|
||||||
<string name="mpris_notification_settings_summary">Umožnit ovládání přehrávače médií bez otevření KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Umožnit ovládání přehrávače médií bez otevření KDE Connect</string>
|
||||||
<string name="share_to">Sdílet s...</string>
|
<string name="share_to">Sdílet s...</string>
|
||||||
<string name="unreachable_device">%s (nedostupná)</string>
|
|
||||||
<string name="unreachable_device_url_share_text">URL sdílená s nedostupným zařízením budou zaslána jakmile se stane dostupným.\n\n</string>
|
<string name="unreachable_device_url_share_text">URL sdílená s nedostupným zařízením budou zaslána jakmile se stane dostupným.\n\n</string>
|
||||||
<string name="protocol_version_newer">Toto zařízení používá novější verzi protokolu</string>
|
<string name="protocol_version_newer">Toto zařízení používá novější verzi protokolu</string>
|
||||||
<string name="plugin_settings_with_name">Nastavení %s</string>
|
<string name="plugin_settings_with_name">Nastavení %s</string>
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
<string name="sendkeystrokes_pref_category_title">Tastendrücke senden</string>
|
<string name="sendkeystrokes_pref_category_title">Tastendrücke senden</string>
|
||||||
<string name="sendkeystrokes_pref_enabled">Senden von Tastendrücken aktivieren</string>
|
<string name="sendkeystrokes_pref_enabled">Senden von Tastendrücken aktivieren</string>
|
||||||
<string name="sendkeystrokes_pref_enabled_summary">Auf Daten mit dem MIME-Typ „text/x-keystrokes“ warten</string>
|
<string name="sendkeystrokes_pref_enabled_summary">Auf Daten mit dem MIME-Typ „text/x-keystrokes“ warten</string>
|
||||||
|
<string name="sendkeystrokes_safe_text_enabled_summary">Kurze Ziffernfolgen ohne Bestätigung senden</string>
|
||||||
<string name="pref_plugin_mousepad_send_keystrokes">Als Tastendruck senden</string>
|
<string name="pref_plugin_mousepad_send_keystrokes">Als Tastendruck senden</string>
|
||||||
<string name="mouse_receiver_plugin_description">Empfänger für entfernte Mauseingaben</string>
|
<string name="mouse_receiver_plugin_description">Empfänger für entfernte Mauseingaben</string>
|
||||||
<string name="mouse_receiver_plugin_name">Maus-Empfänger</string>
|
<string name="mouse_receiver_plugin_name">Maus-Empfänger</string>
|
||||||
@ -112,6 +113,7 @@
|
|||||||
<string name="error_not_reachable">Das Gerät ist nicht erreichbar</string>
|
<string name="error_not_reachable">Das Gerät ist nicht erreichbar</string>
|
||||||
<string name="error_already_paired">Das Gerät ist bereits verbunden</string>
|
<string name="error_already_paired">Das Gerät ist bereits verbunden</string>
|
||||||
<string name="error_timed_out">Zeitüberschreitung</string>
|
<string name="error_timed_out">Zeitüberschreitung</string>
|
||||||
|
<string name="error_clocks_not_match">Uhren der Geräte sind nicht synchron</string>
|
||||||
<string name="error_canceled_by_user">Abbruch durch Benutzer</string>
|
<string name="error_canceled_by_user">Abbruch durch Benutzer</string>
|
||||||
<string name="error_canceled_by_other_peer">Abbruch durch Gegenstelle</string>
|
<string name="error_canceled_by_other_peer">Abbruch durch Gegenstelle</string>
|
||||||
<string name="encryption_info_title">Verschlüsselungsinformationen</string>
|
<string name="encryption_info_title">Verschlüsselungsinformationen</string>
|
||||||
@ -161,9 +163,11 @@
|
|||||||
<string name="middle_click">Mittelklick senden</string>
|
<string name="middle_click">Mittelklick senden</string>
|
||||||
<string name="show_keyboard">Tastatur anzeigen</string>
|
<string name="show_keyboard">Tastatur anzeigen</string>
|
||||||
<string name="device_not_paired">Das Gerät ist nicht verbunden</string>
|
<string name="device_not_paired">Das Gerät ist nicht verbunden</string>
|
||||||
|
<string name="pairing_duplicate_names">Achtung: Es gibt mehrere Geräte mit dem gleichen Namen.</string>
|
||||||
<string name="request_pairing">Kopplung anfordern</string>
|
<string name="request_pairing">Kopplung anfordern</string>
|
||||||
<string name="pairing_accept">Annehmen</string>
|
<string name="pairing_accept">Annehmen</string>
|
||||||
<string name="pairing_reject">Ablehnen</string>
|
<string name="pairing_reject">Ablehnen</string>
|
||||||
|
<string name="pairing_explanation">Zwei Geräte zu koppeln ermöglicht diesen, auf das jeweils andere zuzugreifen. Koppeln Sie nur Ihre eigenen Geräte.</string>
|
||||||
<string name="settings">Einstellungen</string>
|
<string name="settings">Einstellungen</string>
|
||||||
<string name="mpris_play">Wiedergabe</string>
|
<string name="mpris_play">Wiedergabe</string>
|
||||||
<string name="mpris_pause">Anhalten</string>
|
<string name="mpris_pause">Anhalten</string>
|
||||||
@ -186,14 +190,16 @@
|
|||||||
<string name="mpris_notifications_explanation">Benachrichtigungen müssen erlaubt sein, um entfernte Medien im Benachrichtigungsfenster zu zeigen.</string>
|
<string name="mpris_notifications_explanation">Benachrichtigungen müssen erlaubt sein, um entfernte Medien im Benachrichtigungsfenster zu zeigen.</string>
|
||||||
<string name="mpris_notification_settings_title">Benachrichtigung zur Medienkontrolle anzeigen</string>
|
<string name="mpris_notification_settings_title">Benachrichtigung zur Medienkontrolle anzeigen</string>
|
||||||
<string name="mpris_notification_settings_summary">Die Steuerung der Medienwiedergabe auch dann erlauben wenn KDE Connect nicht geöffnet ist</string>
|
<string name="mpris_notification_settings_summary">Die Steuerung der Medienwiedergabe auch dann erlauben wenn KDE Connect nicht geöffnet ist</string>
|
||||||
<string name="share_to">Freigeben für ...</string>
|
<string name="share_to">Freigeben für …</string>
|
||||||
<string name="unreachable_device">%s (nicht erreichbar)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">URLs, die mit einem nicht erreichbaren Gerät geteilt werden, werden zugestellt sobald es erreichbar wird.\n\n</string>
|
<string name="unreachable_device_url_share_text">URLs, die mit einem nicht erreichbaren Gerät geteilt werden, werden zugestellt sobald es erreichbar wird.\n\n</string>
|
||||||
|
<string name="protocol_version">Protokollversion:</string>
|
||||||
<string name="protocol_version_newer">Dieses Gerät verwendet eine neuere Protokollversion</string>
|
<string name="protocol_version_newer">Dieses Gerät verwendet eine neuere Protokollversion</string>
|
||||||
<string name="plugin_settings_with_name">%s-Einstellungen</string>
|
<string name="plugin_settings_with_name">%s-Einstellungen</string>
|
||||||
<string name="invalid_device_name">Ungültiger Gerätename</string>
|
<string name="invalid_device_name">Ungültiger Gerätename</string>
|
||||||
<string name="shareplugin_text_saved">Text empfangen und in die Zwischenablage kopiert</string>
|
<string name="shareplugin_text_saved">Text empfangen und in die Zwischenablage kopiert</string>
|
||||||
<string name="custom_devices_settings">Benutzerdefinierte Geräteliste</string>
|
<string name="custom_devices_settings">Benutzerdefinierte Geräteliste</string>
|
||||||
|
<string name="custom_devices_settings_summary">%d Geräte manuell hinzugefügt</string>
|
||||||
<string name="custom_device_list">Geräte nach IP-Adresse hinzufügen</string>
|
<string name="custom_device_list">Geräte nach IP-Adresse hinzufügen</string>
|
||||||
<string name="custom_device_deleted">Benutzerdefinierte Geräte gelöscht</string>
|
<string name="custom_device_deleted">Benutzerdefinierte Geräte gelöscht</string>
|
||||||
<string name="custom_device_list_help">Falls Ihr Gerät nicht automatisch erkannt wird, können Sie es über die IP-Adresse oder den Gerätenamen hinzufügen. Klicken Sie dafür auf den schwebenden Aktionsknopf</string>
|
<string name="custom_device_list_help">Falls Ihr Gerät nicht automatisch erkannt wird, können Sie es über die IP-Adresse oder den Gerätenamen hinzufügen. Klicken Sie dafür auf den schwebenden Aktionsknopf</string>
|
||||||
@ -360,7 +366,7 @@
|
|||||||
<item>Hell</item>
|
<item>Hell</item>
|
||||||
<item>Dunkel</item>
|
<item>Dunkel</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="report_bug">Probleme oder Wünsche berichten</string>
|
<string name="report_bug">Problem melden</string>
|
||||||
<string name="donate">Spenden</string>
|
<string name="donate">Spenden</string>
|
||||||
<string name="source_code">Quelltext</string>
|
<string name="source_code">Quelltext</string>
|
||||||
<string name="licenses">Lizenzen</string>
|
<string name="licenses">Lizenzen</string>
|
||||||
@ -376,6 +382,7 @@
|
|||||||
<string name="kde_be_free">KDE - Freiheit genießen.</string>
|
<string name="kde_be_free">KDE - Freiheit genießen.</string>
|
||||||
<string name="kde">KDE</string>
|
<string name="kde">KDE</string>
|
||||||
<string name="konqi">Konqi</string>
|
<string name="konqi">Konqi</string>
|
||||||
|
<string name="click_here_to_type">Hier tippen, um zu schreiben</string>
|
||||||
<string name="clear_compose">Leeren</string>
|
<string name="clear_compose">Leeren</string>
|
||||||
<string name="send_compose">Senden</string>
|
<string name="send_compose">Senden</string>
|
||||||
<string name="open_compose_send">Text schreiben</string>
|
<string name="open_compose_send">Text schreiben</string>
|
||||||
@ -392,10 +399,14 @@
|
|||||||
<string name="everyone_else">Jeder, der über die Jahre noch zu KDE Connect beigetragen hat</string>
|
<string name="everyone_else">Jeder, der über die Jahre noch zu KDE Connect beigetragen hat</string>
|
||||||
<string name="send_clipboard">Zwischenablage senden</string>
|
<string name="send_clipboard">Zwischenablage senden</string>
|
||||||
<string name="tap_to_execute">Tippen um auszuführen</string>
|
<string name="tap_to_execute">Tippen um auszuführen</string>
|
||||||
|
<string name="plugin_stats">Modul-Statistik</string>
|
||||||
<string name="enable_udp_broadcast">UDP-Geräteerkennung einschalten</string>
|
<string name="enable_udp_broadcast">UDP-Geräteerkennung einschalten</string>
|
||||||
|
<string name="enable_bluetooth">Bluetooth aktivieren (Beta)</string>
|
||||||
<string name="findmyphone_notifications_explanation">Benachrichtigungen müssen erlaubt sein, damit das Telefon klingeln kann, wenn die App im Hintergrund ist</string>
|
<string name="findmyphone_notifications_explanation">Benachrichtigungen müssen erlaubt sein, damit das Telefon klingeln kann, wenn die App im Hintergrund ist</string>
|
||||||
<string name="no_notifications">Benachrichtigungen sind abgeschaltet, Sie erhalten keine Benachrichtigungen für eingehende Verbindungen.</string>
|
<string name="no_notifications">Benachrichtigungen sind abgeschaltet, Sie erhalten keine Benachrichtigungen für eingehende Verbindungen.</string>
|
||||||
<string name="mpris_keepwatching">Wiedergabe fortsetzen</string>
|
<string name="mpris_keepwatching">Wiedergabe fortsetzen</string>
|
||||||
<string name="mpris_keepwatching_settings_title">Wiedergabe fortsetzen</string>
|
<string name="mpris_keepwatching_settings_title">Wiedergabe fortsetzen</string>
|
||||||
<string name="notification_channel_keepwatching">Wiedergabe fortsetzen</string>
|
<string name="notification_channel_keepwatching">Wiedergabe fortsetzen</string>
|
||||||
|
<string name="ping_result">Ping-Dauer: %1$d Millisekunden</string>
|
||||||
|
<string name="ping_in_progress">Ping läuft …</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -190,7 +190,6 @@
|
|||||||
<string name="mpris_notification_settings_title">Show media control notification</string>
|
<string name="mpris_notification_settings_title">Show media control notification</string>
|
||||||
<string name="mpris_notification_settings_summary">Allow controlling your media players without opening KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Allow controlling your media players without opening KDE Connect</string>
|
||||||
<string name="share_to">Share to…</string>
|
<string name="share_to">Share to…</string>
|
||||||
<string name="unreachable_device">%s (Unreachable)</string>
|
|
||||||
<string name="unreachable_device_url_share_text">URLs shared to an unreachable device will be delivered to it once it becomes reachable.\n\n</string>
|
<string name="unreachable_device_url_share_text">URLs shared to an unreachable device will be delivered to it once it becomes reachable.\n\n</string>
|
||||||
<string name="protocol_version_newer">This device uses a newer protocol version</string>
|
<string name="protocol_version_newer">This device uses a newer protocol version</string>
|
||||||
<string name="plugin_settings_with_name">%s settings</string>
|
<string name="plugin_settings_with_name">%s settings</string>
|
||||||
|
@ -191,7 +191,6 @@
|
|||||||
<string name="mpris_notification_settings_title">Montri sciigon pri rego de amaskomunikiloj</string>
|
<string name="mpris_notification_settings_title">Montri sciigon pri rego de amaskomunikiloj</string>
|
||||||
<string name="mpris_notification_settings_summary">Permesu mastrumi viajn plurmediajn ludilojn sen malfermi KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Permesu mastrumi viajn plurmediajn ludilojn sen malfermi KDE Connect</string>
|
||||||
<string name="share_to">Kunhavigi al…</string>
|
<string name="share_to">Kunhavigi al…</string>
|
||||||
<string name="unreachable_device">%s (Neatingebla)</string>
|
|
||||||
<string name="unreachable_device_url_share_text">URL-oj kundividitaj al neatingebla aparato estos liveritaj al ĝi post kiam ĝi fariĝos atingebla.\n\n</string>
|
<string name="unreachable_device_url_share_text">URL-oj kundividitaj al neatingebla aparato estos liveritaj al ĝi post kiam ĝi fariĝos atingebla.\n\n</string>
|
||||||
<string name="protocol_version">Protokolversio:</string>
|
<string name="protocol_version">Protokolversio:</string>
|
||||||
<string name="protocol_version_newer">Ĉi tiu aparato uzas pli novan protokolversion</string>
|
<string name="protocol_version_newer">Ĉi tiu aparato uzas pli novan protokolversion</string>
|
||||||
|
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Enviar clic del botón central</string>
|
<string name="middle_click">Enviar clic del botón central</string>
|
||||||
<string name="show_keyboard">Mostrar teclado</string>
|
<string name="show_keyboard">Mostrar teclado</string>
|
||||||
<string name="device_not_paired">Dispositivo no vinculado</string>
|
<string name="device_not_paired">Dispositivo no vinculado</string>
|
||||||
|
<string name="pairing_duplicate_names">Precaución: Hay varios dispositivos con el mismo nombre.</string>
|
||||||
<string name="request_pairing">Solicitar vinculación</string>
|
<string name="request_pairing">Solicitar vinculación</string>
|
||||||
<string name="pairing_accept">Aceptar</string>
|
<string name="pairing_accept">Aceptar</string>
|
||||||
<string name="pairing_reject">Rechazar</string>
|
<string name="pairing_reject">Rechazar</string>
|
||||||
|
<string name="pairing_explanation">Vincular dos dispositivos les dará acceso recíproco. Vincule solo dispositivos que le pertenezcan.</string>
|
||||||
<string name="settings">Preferencias</string>
|
<string name="settings">Preferencias</string>
|
||||||
<string name="mpris_play">Reproducir</string>
|
<string name="mpris_play">Reproducir</string>
|
||||||
<string name="mpris_pause">Pausar</string>
|
<string name="mpris_pause">Pausar</string>
|
||||||
@ -190,8 +192,8 @@
|
|||||||
<string name="mpris_notifications_explanation">Se necesita el permiso de notificaciones para mostrar los medios remotos en el panel de notificaciones</string>
|
<string name="mpris_notifications_explanation">Se necesita el permiso de notificaciones para mostrar los medios remotos en el panel de notificaciones</string>
|
||||||
<string name="mpris_notification_settings_title">Mostrar notificación del control de medios</string>
|
<string name="mpris_notification_settings_title">Mostrar notificación del control de medios</string>
|
||||||
<string name="mpris_notification_settings_summary">Permite controlar sus reproductores de medios sin abrir KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Permite controlar sus reproductores de medios sin abrir KDE Connect</string>
|
||||||
<string name="share_to">Compartir con...</string>
|
<string name="share_to">Compartir con…</string>
|
||||||
<string name="unreachable_device">%s (no accesible)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Las URLs compartidas con dispositivos no accesibles se entregarán una vez que vuelvan a estar accesibles.\n\n</string>
|
<string name="unreachable_device_url_share_text">Las URLs compartidas con dispositivos no accesibles se entregarán una vez que vuelvan a estar accesibles.\n\n</string>
|
||||||
<string name="protocol_version">Versión del protocolo:</string>
|
<string name="protocol_version">Versión del protocolo:</string>
|
||||||
<string name="protocol_version_newer">Este dispositivo usa una versión más reciente del protocolo</string>
|
<string name="protocol_version_newer">Este dispositivo usa una versión más reciente del protocolo</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Dispositivos</string>
|
<string name="devices">Dispositivos</string>
|
||||||
<string name="settings_rename">Nombre del dispositivo</string>
|
<string name="settings_rename">Nombre del dispositivo</string>
|
||||||
<string name="settings_dark_mode">Tema oscuro</string>
|
<string name="settings_dark_mode">Tema oscuro</string>
|
||||||
|
<string name="settings_export_logs">Exportar registros de KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">Generar un archivo con la información de ejecución que puede ayudar a solventar problemas.</string>
|
||||||
<string name="settings_more_settings_title">Más preferencias</string>
|
<string name="settings_more_settings_title">Más preferencias</string>
|
||||||
<string name="settings_more_settings_text">Las preferencias por dispositivo se pueden encontrar bajo «Preferencias del complemento» dentro de cada dispositivo.</string>
|
<string name="settings_more_settings_text">Las preferencias por dispositivo se pueden encontrar bajo «Preferencias del complemento» dentro de cada dispositivo.</string>
|
||||||
<string name="setting_persistent_notification">Mostrar notificación persistente</string>
|
<string name="setting_persistent_notification">Mostrar notificación persistente</string>
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
<string name="error_not_reachable">Gailua ez dago eskuragarri</string>
|
<string name="error_not_reachable">Gailua ez dago eskuragarri</string>
|
||||||
<string name="error_already_paired">Gailua dagoeneko parekatuta</string>
|
<string name="error_already_paired">Gailua dagoeneko parekatuta</string>
|
||||||
<string name="error_timed_out">Denbora-muga agortu da</string>
|
<string name="error_timed_out">Denbora-muga agortu da</string>
|
||||||
|
<string name="error_clocks_not_match">Gailuetako erlojuak ez daude sinkronizatuta</string>
|
||||||
<string name="error_canceled_by_user">Erabiltzaileak utzita</string>
|
<string name="error_canceled_by_user">Erabiltzaileak utzita</string>
|
||||||
<string name="error_canceled_by_other_peer">Beste kideak utzita</string>
|
<string name="error_canceled_by_other_peer">Beste kideak utzita</string>
|
||||||
<string name="encryption_info_title">Zifratze informazioa</string>
|
<string name="encryption_info_title">Zifratze informazioa</string>
|
||||||
@ -164,9 +165,11 @@
|
|||||||
<string name="middle_click">Bidali erdiko klik</string>
|
<string name="middle_click">Bidali erdiko klik</string>
|
||||||
<string name="show_keyboard">Erakutsi teklatua</string>
|
<string name="show_keyboard">Erakutsi teklatua</string>
|
||||||
<string name="device_not_paired">Gailua parekatu gabe</string>
|
<string name="device_not_paired">Gailua parekatu gabe</string>
|
||||||
|
<string name="pairing_duplicate_names">Kontuz: Izen bereko hainbat gailu daude.</string>
|
||||||
<string name="request_pairing">Eskatu parekatzea</string>
|
<string name="request_pairing">Eskatu parekatzea</string>
|
||||||
<string name="pairing_accept">Onartu</string>
|
<string name="pairing_accept">Onartu</string>
|
||||||
<string name="pairing_reject">Errefusatu</string>
|
<string name="pairing_reject">Errefusatu</string>
|
||||||
|
<string name="pairing_explanation">Bi gailu parekatzea elkarren sarbidea emango die. Zure gailu propioak baino ez parekatu.</string>
|
||||||
<string name="settings">Ezarpenak</string>
|
<string name="settings">Ezarpenak</string>
|
||||||
<string name="mpris_play">Jo</string>
|
<string name="mpris_play">Jo</string>
|
||||||
<string name="mpris_pause">Eten</string>
|
<string name="mpris_pause">Eten</string>
|
||||||
@ -189,9 +192,10 @@
|
|||||||
<string name="mpris_notifications_explanation">Urruneko euskarria jakinarazpen tiraderan erakusteko jakinarazpen-baimena behar da</string>
|
<string name="mpris_notifications_explanation">Urruneko euskarria jakinarazpen tiraderan erakusteko jakinarazpen-baimena behar da</string>
|
||||||
<string name="mpris_notification_settings_title">Erakutsi euskarri kontrolaren jakinarazpena</string>
|
<string name="mpris_notification_settings_title">Erakutsi euskarri kontrolaren jakinarazpena</string>
|
||||||
<string name="mpris_notification_settings_summary">Utzi zure euskarri-jotzaileak kontrolatzen KDE Connect ireki gabe</string>
|
<string name="mpris_notification_settings_summary">Utzi zure euskarri-jotzaileak kontrolatzen KDE Connect ireki gabe</string>
|
||||||
<string name="share_to">Partekatu honekin...</string>
|
<string name="share_to">Partekatu honekin…</string>
|
||||||
<string name="unreachable_device">%s (eskuraezin)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Gailu eskuraezinekin partekatutako URLak, hartara bidaliko dira eskuragarri dagoenean.\n\n</string>
|
<string name="unreachable_device_url_share_text">Gailu eskuraezinekin partekatutako URLak, hartara bidaliko dira eskuragarri dagoenean.\n\n</string>
|
||||||
|
<string name="protocol_version">Protokoloaren bertsioa:</string>
|
||||||
<string name="protocol_version_newer">Gailu honek protokoloaren bertsio berriago bat erabiltzen du</string>
|
<string name="protocol_version_newer">Gailu honek protokoloaren bertsio berriago bat erabiltzen du</string>
|
||||||
<string name="plugin_settings_with_name">%s ezarpenak</string>
|
<string name="plugin_settings_with_name">%s ezarpenak</string>
|
||||||
<string name="invalid_device_name">Gailuaren izen baliogabea</string>
|
<string name="invalid_device_name">Gailuaren izen baliogabea</string>
|
||||||
@ -307,6 +311,8 @@
|
|||||||
<string name="devices">Gailuak</string>
|
<string name="devices">Gailuak</string>
|
||||||
<string name="settings_rename">Gailuaren izena</string>
|
<string name="settings_rename">Gailuaren izena</string>
|
||||||
<string name="settings_dark_mode">Gai iluna</string>
|
<string name="settings_dark_mode">Gai iluna</string>
|
||||||
|
<string name="settings_export_logs">Esportatu KDE Connect-en egunkariak</string>
|
||||||
|
<string name="settings_export_logs_text">Sortu arazoak konpontzen lagun dezakeen exekuzio informazioa duen fitxategi bat.</string>
|
||||||
<string name="settings_more_settings_title">Ezarpen gehiago</string>
|
<string name="settings_more_settings_title">Ezarpen gehiago</string>
|
||||||
<string name="settings_more_settings_text">Gailu-bakoitzeko ezarpenak aurki daitezke \'Pluginen ezarpenak\' barruan.</string>
|
<string name="settings_more_settings_text">Gailu-bakoitzeko ezarpenak aurki daitezke \'Pluginen ezarpenak\' barruan.</string>
|
||||||
<string name="setting_persistent_notification">Erakutsi jakinarazpen iraunkorra</string>
|
<string name="setting_persistent_notification">Erakutsi jakinarazpen iraunkorra</string>
|
||||||
@ -423,7 +429,7 @@
|
|||||||
<string name="notification_channel_keepwatching">Jarraitu jotzen</string>
|
<string name="notification_channel_keepwatching">Jarraitu jotzen</string>
|
||||||
<string name="ping_result">«Ping» %1$d milisegundotan egin da</string>
|
<string name="ping_result">«Ping» %1$d milisegundotan egin da</string>
|
||||||
<string name="ping_failed">Ezin izan dio gailuari «ping» egin</string>
|
<string name="ping_failed">Ezin izan dio gailuari «ping» egin</string>
|
||||||
<string name="ping_in_progress">«Ping» egiten...</string>
|
<string name="ping_in_progress">«Ping» egiten…</string>
|
||||||
<string name="device_host_invalid">Ostalaria baliogabea da. Erabili balio duen ostalari-izen bat, IPv4, edo IPv6</string>
|
<string name="device_host_invalid">Ostalaria baliogabea da. Erabili balio duen ostalari-izen bat, IPv4, edo IPv6</string>
|
||||||
<string name="device_host_duplicate">Ostalaria jada zerrendan dago</string>
|
<string name="device_host_duplicate">Ostalaria jada zerrendan dago</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Lähetä keskipainikkeen napsautus</string>
|
<string name="middle_click">Lähetä keskipainikkeen napsautus</string>
|
||||||
<string name="show_keyboard">Näytä näppäimistö</string>
|
<string name="show_keyboard">Näytä näppäimistö</string>
|
||||||
<string name="device_not_paired">Laitetta ei ole kytketty pariksi</string>
|
<string name="device_not_paired">Laitetta ei ole kytketty pariksi</string>
|
||||||
|
<string name="pairing_duplicate_names">Varoitus: Useammalla laitteella on sama nimi.</string>
|
||||||
<string name="request_pairing">Pyydä pariksi kytkemistä</string>
|
<string name="request_pairing">Pyydä pariksi kytkemistä</string>
|
||||||
<string name="pairing_accept">Hyväksy</string>
|
<string name="pairing_accept">Hyväksy</string>
|
||||||
<string name="pairing_reject">Hylkää</string>
|
<string name="pairing_reject">Hylkää</string>
|
||||||
|
<string name="pairing_explanation">Laitteiden paritus sallii niiden käyttää toisiaan. Parita vain omia laitteitasi.</string>
|
||||||
<string name="settings">Asetukset</string>
|
<string name="settings">Asetukset</string>
|
||||||
<string name="mpris_play">Toista</string>
|
<string name="mpris_play">Toista</string>
|
||||||
<string name="mpris_pause">Tauko</string>
|
<string name="mpris_pause">Tauko</string>
|
||||||
@ -191,7 +193,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Näytä mediasäädinilmoitukset</string>
|
<string name="mpris_notification_settings_title">Näytä mediasäädinilmoitukset</string>
|
||||||
<string name="mpris_notification_settings_summary">Sallii mediasoitintesi hallinnan KDE Connectia avaamatta</string>
|
<string name="mpris_notification_settings_summary">Sallii mediasoitintesi hallinnan KDE Connectia avaamatta</string>
|
||||||
<string name="share_to">Jaa…</string>
|
<string name="share_to">Jaa…</string>
|
||||||
<string name="unreachable_device">%s (tavoittamattomissa)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Tavoittamattomissa olevalle laitteelle jaetut verkko-osoitteet välitetään heti kun laite tavoitetaan.\n\n</string>
|
<string name="unreachable_device_url_share_text">Tavoittamattomissa olevalle laitteelle jaetut verkko-osoitteet välitetään heti kun laite tavoitetaan.\n\n</string>
|
||||||
<string name="protocol_version">Yhteyskäytäntöversio:</string>
|
<string name="protocol_version">Yhteyskäytäntöversio:</string>
|
||||||
<string name="protocol_version_newer">Laite käyttää uudempaa yhteyskäytäntöversiota</string>
|
<string name="protocol_version_newer">Laite käyttää uudempaa yhteyskäytäntöversiota</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Laitteet</string>
|
<string name="devices">Laitteet</string>
|
||||||
<string name="settings_rename">Laitenimi</string>
|
<string name="settings_rename">Laitenimi</string>
|
||||||
<string name="settings_dark_mode">Tumma teema</string>
|
<string name="settings_dark_mode">Tumma teema</string>
|
||||||
|
<string name="settings_export_logs">Vie KDE Connectin lokit</string>
|
||||||
|
<string name="settings_export_logs_text">Luo suoritustietotiedosto, josta voi olla apua ongelmien selvityksessä.</string>
|
||||||
<string name="settings_more_settings_title">Lisää asetuksia</string>
|
<string name="settings_more_settings_title">Lisää asetuksia</string>
|
||||||
<string name="settings_more_settings_text">Laitekohtaiset asetukset löytyvät laitteen ”Liitännäisasetuksista”.</string>
|
<string name="settings_more_settings_text">Laitekohtaiset asetukset löytyvät laitteen ”Liitännäisasetuksista”.</string>
|
||||||
<string name="setting_persistent_notification">Näytä pysyvä ilmoitus</string>
|
<string name="setting_persistent_notification">Näytä pysyvä ilmoitus</string>
|
||||||
|
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Envoyer un clic central</string>
|
<string name="middle_click">Envoyer un clic central</string>
|
||||||
<string name="show_keyboard">Afficher le clavier</string>
|
<string name="show_keyboard">Afficher le clavier</string>
|
||||||
<string name="device_not_paired">Périphérique non associé</string>
|
<string name="device_not_paired">Périphérique non associé</string>
|
||||||
|
<string name="pairing_duplicate_names">Attention : Il existe plusieurs périphériques portant le même nom.</string>
|
||||||
<string name="request_pairing">Demande d\'association</string>
|
<string name="request_pairing">Demande d\'association</string>
|
||||||
<string name="pairing_accept">Accepter</string>
|
<string name="pairing_accept">Accepter</string>
|
||||||
<string name="pairing_reject">Rejeter</string>
|
<string name="pairing_reject">Rejeter</string>
|
||||||
|
<string name="pairing_explanation">L\'association de deux périphériques leur donnera un accès réciproque. Veuillez n\'associer que vos propres périphériques.</string>
|
||||||
<string name="settings">Configuration</string>
|
<string name="settings">Configuration</string>
|
||||||
<string name="mpris_play">Lire</string>
|
<string name="mpris_play">Lire</string>
|
||||||
<string name="mpris_pause">Pause</string>
|
<string name="mpris_pause">Pause</string>
|
||||||
@ -191,7 +193,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Afficher la notification de contrôle du lecteur multimédia</string>
|
<string name="mpris_notification_settings_title">Afficher la notification de contrôle du lecteur multimédia</string>
|
||||||
<string name="mpris_notification_settings_summary">Vous permet de contrôler vos lecteurs multimédia sans ouvrir KDEConnect.</string>
|
<string name="mpris_notification_settings_summary">Vous permet de contrôler vos lecteurs multimédia sans ouvrir KDEConnect.</string>
|
||||||
<string name="share_to">Partager vers…</string>
|
<string name="share_to">Partager vers…</string>
|
||||||
<string name="unreachable_device">%s (Inaccessible)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Les URL partagées vers un appareil inaccessible lui seront transmises une fois qu\'il re-deviendra accessible.\n\n</string>
|
<string name="unreachable_device_url_share_text">Les URL partagées vers un appareil inaccessible lui seront transmises une fois qu\'il re-deviendra accessible.\n\n</string>
|
||||||
<string name="protocol_version">Version de protocole :</string>
|
<string name="protocol_version">Version de protocole :</string>
|
||||||
<string name="protocol_version_newer">Le périphérique utilise une version plus récente du protocole</string>
|
<string name="protocol_version_newer">Le périphérique utilise une version plus récente du protocole</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Périphériques</string>
|
<string name="devices">Périphériques</string>
|
||||||
<string name="settings_rename">Nom du périphérique</string>
|
<string name="settings_rename">Nom du périphérique</string>
|
||||||
<string name="settings_dark_mode">Thème sombre</string>
|
<string name="settings_dark_mode">Thème sombre</string>
|
||||||
|
<string name="settings_export_logs">Exporter les journaux de KDEConnect</string>
|
||||||
|
<string name="settings_export_logs_text">Générez un fichier avec des informations d\'exécution pouvant aider à résoudre les problèmes.</string>
|
||||||
<string name="settings_more_settings_title">Plus de paramètres</string>
|
<string name="settings_more_settings_title">Plus de paramètres</string>
|
||||||
<string name="settings_more_settings_text">Les paramètres par appareil sont disponibles dans la rubrique « Paramètres des modules externes » sur l\'appareil.</string>
|
<string name="settings_more_settings_text">Les paramètres par appareil sont disponibles dans la rubrique « Paramètres des modules externes » sur l\'appareil.</string>
|
||||||
<string name="setting_persistent_notification">Afficher une notification persistante</string>
|
<string name="setting_persistent_notification">Afficher une notification persistante</string>
|
||||||
|
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Enviar un clic central</string>
|
<string name="middle_click">Enviar un clic central</string>
|
||||||
<string name="show_keyboard">Amosar o teclado</string>
|
<string name="show_keyboard">Amosar o teclado</string>
|
||||||
<string name="device_not_paired">O dispositivo non está emparellado</string>
|
<string name="device_not_paired">O dispositivo non está emparellado</string>
|
||||||
|
<string name="pairing_duplicate_names">Ollo: Hai varios dispositivos co mesmo nome.</string>
|
||||||
<string name="request_pairing">Solicitar emparellarse</string>
|
<string name="request_pairing">Solicitar emparellarse</string>
|
||||||
<string name="pairing_accept">Aceptar</string>
|
<string name="pairing_accept">Aceptar</string>
|
||||||
<string name="pairing_reject">Rexeitar</string>
|
<string name="pairing_reject">Rexeitar</string>
|
||||||
|
<string name="pairing_explanation">Emparellar dispositivos permítelles acceder o un ao outro. Emparelle só os seus propios dispositivos.</string>
|
||||||
<string name="settings">Configuración</string>
|
<string name="settings">Configuración</string>
|
||||||
<string name="mpris_play">Reproducir</string>
|
<string name="mpris_play">Reproducir</string>
|
||||||
<string name="mpris_pause">Deter</string>
|
<string name="mpris_pause">Deter</string>
|
||||||
@ -191,7 +193,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Amosar a notificación de control de reprodución.</string>
|
<string name="mpris_notification_settings_title">Amosar a notificación de control de reprodución.</string>
|
||||||
<string name="mpris_notification_settings_summary">Permitir controlar os reprodutores sen abrir KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Permitir controlar os reprodutores sen abrir KDE Connect</string>
|
||||||
<string name="share_to">Compartir con…</string>
|
<string name="share_to">Compartir con…</string>
|
||||||
<string name="unreachable_device">%s (inaccesíbel)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Os URL que se compartan cun dispositivo inaccesíbel entregaranse cando o dispositivo estea accesíbel.\n\n</string>
|
<string name="unreachable_device_url_share_text">Os URL que se compartan cun dispositivo inaccesíbel entregaranse cando o dispositivo estea accesíbel.\n\n</string>
|
||||||
<string name="protocol_version">Versión do protocolo:</string>
|
<string name="protocol_version">Versión do protocolo:</string>
|
||||||
<string name="protocol_version_newer">Este dispositivo usa unha versión máis nova do protocolo.</string>
|
<string name="protocol_version_newer">Este dispositivo usa unha versión máis nova do protocolo.</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Dispositivos</string>
|
<string name="devices">Dispositivos</string>
|
||||||
<string name="settings_rename">Nome do dispositivo</string>
|
<string name="settings_rename">Nome do dispositivo</string>
|
||||||
<string name="settings_dark_mode">Tema escuro</string>
|
<string name="settings_dark_mode">Tema escuro</string>
|
||||||
|
<string name="settings_export_logs">Exportar os rexistros de KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">Xerar un ficheiro con información de execución que pode axudar a solucionar problemas.</string>
|
||||||
<string name="settings_more_settings_title">Máis opcións</string>
|
<string name="settings_more_settings_title">Máis opcións</string>
|
||||||
<string name="settings_more_settings_text">As opcións específicas dun dispositivo atópanse en «Configuración dos complementos» no dispositivo.</string>
|
<string name="settings_more_settings_text">As opcións específicas dun dispositivo atópanse en «Configuración dos complementos» no dispositivo.</string>
|
||||||
<string name="setting_persistent_notification">Amosar unha notificación persistente</string>
|
<string name="setting_persistent_notification">Amosar unha notificación persistente</string>
|
||||||
|
@ -1,143 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
|
||||||
<resources>
|
|
||||||
<string name="pref_plugin_telephony">התראות טלפוניות</string>
|
|
||||||
<string name="pref_plugin_battery">דיווח סוללה</string>
|
|
||||||
<string name="pref_plugin_battery_desc">מדווח על אחוז הסוללה למחשב</string>
|
|
||||||
<string name="pref_plugin_sftp">גישה לקבצים</string>
|
|
||||||
<string name="pref_plugin_sftp_desc">אפשר להתקן המרוחק לדפדף בקבצים של הפלאפון מרחוק</string>
|
|
||||||
<string name="pref_plugin_clipboard">סנכרון לוח העתקה</string>
|
|
||||||
<string name="pref_plugin_clipboard_desc">שתף בין המחשבים את כל מה שמועתק</string>
|
|
||||||
<string name="pref_plugin_mousepad">שליטה מרחוק</string>
|
|
||||||
<string name="pref_plugin_mousepad_desc">השתמש בפלאפון כדי לשלוט בעכבר ובמקלדת של ההתקן המרוחק</string>
|
|
||||||
<string name="pref_plugin_remotekeyboard">קבלת לחיצות מרחוק</string>
|
|
||||||
<string name="pref_plugin_remotekeyboard_desc">קבלת אירועי מקלדת מהתקן מרוחק</string>
|
|
||||||
<string name="pref_plugin_mpris">שליטה במדיה</string>
|
|
||||||
<string name="pref_plugin_mpris_desc">מספק שליטה מרוחקת על נגן המדיה שלך</string>
|
|
||||||
<string name="pref_plugin_runcommand">הרץ פקודה</string>
|
|
||||||
<string name="pref_plugin_runcommand_desc">הרץ פקודה במחשב מהמכשיר שלך</string>
|
|
||||||
<string name="pref_plugin_ping">פינג</string>
|
|
||||||
<string name="pref_plugin_ping_desc">שלח וקבל פינגים</string>
|
|
||||||
<string name="pref_plugin_notifications">סנכרון התראות</string>
|
|
||||||
<string name="pref_plugin_notifications_desc">הראה את ההתראות מהפלאפון בהתקן אחר</string>
|
|
||||||
<string name="pref_plugin_receive_notifications">קבלת התראות</string>
|
|
||||||
<string name="pref_plugin_receive_notifications_desc">קבל התראות מהתקן אחר והצג אותם במכשיר שלך</string>
|
|
||||||
<string name="pref_plugin_sharereceiver">שתף וקבל קבצים וכתובות</string>
|
|
||||||
<string name="pref_plugin_sharereceiver_desc">שתף וקבל קבצים וכתובת אינטרנט בין התקנים</string>
|
|
||||||
<string name="device_list_empty">אין התקנים</string>
|
|
||||||
<string name="ok">אישור</string>
|
|
||||||
<string name="cancel">בטל</string>
|
|
||||||
<string name="open_settings">פתח הגדרות</string>
|
|
||||||
<string name="no_permissions">אתה צריך לתת הרשאות לגישה להתראות</string>
|
|
||||||
<string name="send_ping">שלח פינג</string>
|
|
||||||
<string name="open_mpris_controls">שליטה על המדיה</string>
|
|
||||||
<string name="remotekeyboard_editing_only_title">השתמש במקשים מרוחקים רק בעת עריכה</string>
|
|
||||||
<string name="remotekeyboard_not_connected">אין מקלדת מרוחקת מופעלת, הוסף אחת ל־kdeconnect</string>
|
|
||||||
<string name="remotekeyboard_connected">חיבור המקדלת המרוחקת פעיל</string>
|
|
||||||
<string name="remotekeyboard_multiple_connections">ישנם כמה מקלדות מרוחקות מחוברות, בחר את ההתקן להגדרה</string>
|
|
||||||
<string name="open_mousepad">שליטה מרחוק</string>
|
|
||||||
<string name="mousepad_double_tap_settings_title">הגדר פעולה ללחיצת שתי אצבעות</string>
|
|
||||||
<string name="mousepad_triple_tap_settings_title">הגדר פעולה ללחיצת שלוש אצבעות</string>
|
|
||||||
<string name="mousepad_sensitivity_settings_title">הגדר רגישות משטח המגע</string>
|
|
||||||
<string name="mousepad_scroll_direction_title">הפוך את כיוון הגלילה</string>
|
|
||||||
<string-array name="mousepad_tap_entries">
|
|
||||||
<item>"לחיצה ימנית "</item>
|
|
||||||
<item>לחיצה אצמעית (גלגלת)</item>
|
|
||||||
<item>שום דבר</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="mousepad_sensitivity_entries">
|
|
||||||
<item>הכי איטי</item>
|
|
||||||
<item>יותר מההכי איטי</item>
|
|
||||||
<item>ברירת החדל</item>
|
|
||||||
<item>יותר מהברירת מחדל</item>
|
|
||||||
<item>הכי מהיר</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="mousepad_acceleration_profile_entries">
|
|
||||||
<item>No Acceleration</item>
|
|
||||||
<item>Weakest</item>
|
|
||||||
<item>Weaker</item>
|
|
||||||
<item>Medium</item>
|
|
||||||
<item>Stronger</item>
|
|
||||||
<item>Strongest</item>
|
|
||||||
</string-array>
|
|
||||||
<string name="category_connected_devices">התקנים מחוברים</string>
|
|
||||||
<string name="category_not_paired_devices">התקנים זמינים</string>
|
|
||||||
<string name="category_remembered_devices">התקנים זכורים</string>
|
|
||||||
<string name="device_menu_plugins">הגדרות תוספים</string>
|
|
||||||
<string name="device_menu_unpair">בטל התאמה</string>
|
|
||||||
<string name="pair_new_device">התאם התקן חדש</string>
|
|
||||||
<string name="unknown_device">התקן לא ידוע</string>
|
|
||||||
<string name="error_not_reachable">ההתקן לא זמין</string>
|
|
||||||
<string name="error_already_paired">ההתקן כבר מותאם</string>
|
|
||||||
<string name="error_could_not_send_package">לא יכול לשלוח חבילה</string>
|
|
||||||
<string name="error_timed_out">נגמר הזמן</string>
|
|
||||||
<string name="error_canceled_by_user">בוטל על ידי המשתמש</string>
|
|
||||||
<string name="error_canceled_by_other_peer">בוטל על ידי מישהו אחר</string>
|
|
||||||
<string name="encryption_info_title">פרטי הצפנה</string>
|
|
||||||
<string name="encryption_info_msg_no_ssl">ההתקן השני אינו משתמש בגרסה האחרונה של KDE Connect, משתמש בשיטת ההצפנה הישנה.</string>
|
|
||||||
<string name="my_device_fingerprint">טביעת האצבע SHA1 של ההתקן היא:</string>
|
|
||||||
<string name="remote_device_fingerprint">"טביעת האצבע SHA1 של ההתקן המרוחק היא: "</string>
|
|
||||||
<string name="pair_requested">בקשת התאמה</string>
|
|
||||||
<string name="pairing_request_from">בוקשה התאמה מ־%1s</string>
|
|
||||||
<string name="received_file_text">לחץ כדי לפתוח את \"%1s\"</string>
|
|
||||||
<string name="tap_to_answer">לחץ כדי לענות</string>
|
|
||||||
<string name="right_click">שלח לחיצה ימנית</string>
|
|
||||||
<string name="middle_click">שלח לחיצה אמצעית (גלגלת)</string>
|
|
||||||
<string name="show_keyboard">הראה מקלדת</string>
|
|
||||||
<string name="device_not_paired">ההתקן לא מותאם</string>
|
|
||||||
<string name="request_pairing">בקש התאמה</string>
|
|
||||||
<string name="pairing_accept">אשר</string>
|
|
||||||
<string name="pairing_reject">דחה</string>
|
|
||||||
<string name="mpris_play">נגן</string>
|
|
||||||
<string name="mpris_previous">הקודם</string>
|
|
||||||
<string name="mpris_rew">דילוג אחורה</string>
|
|
||||||
<string name="mpris_ff">דילוג קדימה</string>
|
|
||||||
<string name="mpris_next">הבא</string>
|
|
||||||
<string name="mpris_volume">עוצמה</string>
|
|
||||||
<string name="mpris_time_settings_title">כפתור דילוג קדימה או אחורה</string>
|
|
||||||
<string-array name="mpris_time_entries">
|
|
||||||
<item>10 שניות</item>
|
|
||||||
<item>20 שניות</item>
|
|
||||||
<item>חצי דקה</item>
|
|
||||||
<item>דקה</item>
|
|
||||||
<item>שתי דקות</item>
|
|
||||||
</string-array>
|
|
||||||
<string name="protocol_version_newer">ההתקן משתמש בגרסה חדשה יותר</string>
|
|
||||||
<string name="plugin_settings_with_name">הגדרות %s</string>
|
|
||||||
<string name="invalid_device_name">שם ההתקן לא תקין</string>
|
|
||||||
<string name="shareplugin_text_saved">התקבל טקסט, נשמר ללוח העתקה</string>
|
|
||||||
<string name="custom_devices_settings">רשימת התקנים מותאמת אישית</string>
|
|
||||||
<string name="custom_device_list">הוסף התקן על ידי כתובת IP</string>
|
|
||||||
<string name="share_notification_preference">התראות רועשות</string>
|
|
||||||
<string name="share_notification_preference_summary">רטוט ונגן צליל בעת קבלת קובץ</string>
|
|
||||||
<string name="share_destination_customize">שנה תקיית יעד</string>
|
|
||||||
<string name="share_destination_customize_summary_disabled">קבצים שהתקבלו יהיו בהורדות</string>
|
|
||||||
<string name="share_destination_customize_summary_enabled">קבצים יאוכסנו בתיקיה למטה</string>
|
|
||||||
<string name="share_destination_folder_preference">תיקית יעד</string>
|
|
||||||
<string name="title_activity_notification_filter">סנן התראות</string>
|
|
||||||
<string name="filter_apps_info">התראות יסונכרנו רק לאפליקציות נבחרות</string>
|
|
||||||
<string name="sftp_sdcard_num">כרטיס זיכרון %d</string>
|
|
||||||
<string name="sftp_sdcard">כרטיס זיכרון</string>
|
|
||||||
<string name="sftp_readonly">(לקריאה בלבד)</string>
|
|
||||||
<string name="sftp_camera">תמונות מצלמה</string>
|
|
||||||
<string name="no_players_connected">לא נמצא נגן</string>
|
|
||||||
<string name="send_files">שלח קובץ</string>
|
|
||||||
<string name="pairing_title">מכשירי KDE Connect</string>
|
|
||||||
<string name="pairing_description">התקנים אחרים המריצים KDE Connect ברשת הנוכחית צריכים להופיע פה.</string>
|
|
||||||
<string name="device_rename_title">שנה שם התקן</string>
|
|
||||||
<string name="device_rename_confirm">שנה שם</string>
|
|
||||||
<string name="refresh">רענן</string>
|
|
||||||
<string name="unreachable_description">ההתקן המתואם לא זמין, וודא שהוא מחובר לאותה רשת אליה אתה מחובר.</string>
|
|
||||||
<string name="no_file_browser">לא נמצאו מנהלי קבצים מותקנים במכשיר זה.</string>
|
|
||||||
<string name="pref_plugin_telepathy">שליחת הודעת SMS</string>
|
|
||||||
<string name="pref_plugin_telepathy_desc">שלח הודעות מהמחשב שלך</string>
|
|
||||||
<string name="findmyphone_title">מצא את הפלאפון שלי</string>
|
|
||||||
<string name="findmyphone_title_tablet">מצא את הטבלט שלי</string>
|
|
||||||
<string name="findmyphone_description">מפעיל רעש במכשיר כדי שתוכל למצוא אותו.</string>
|
|
||||||
<string name="open">פתח</string>
|
|
||||||
<string name="close">סגור</string>
|
|
||||||
<string-array name="theme_list">
|
|
||||||
<item>Set by Battery Saver</item>
|
|
||||||
<item/>
|
|
||||||
<item>Dark</item>
|
|
||||||
</string-array>
|
|
||||||
</resources>
|
|
@ -94,7 +94,6 @@
|
|||||||
<item>2 minutas</item>
|
<item>2 minutas</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="share_to">Comparti a…</string>
|
<string name="share_to">Comparti a…</string>
|
||||||
<string name="unreachable_device">%s (non attingibile)</string>
|
|
||||||
<string name="custom_device_fab_hint">Adde un dispositivo</string>
|
<string name="custom_device_fab_hint">Adde un dispositivo</string>
|
||||||
<string name="undo">Annulla</string>
|
<string name="undo">Annulla</string>
|
||||||
<string name="share">Comparti</string>
|
<string name="share">Comparti</string>
|
||||||
|
@ -184,12 +184,14 @@
|
|||||||
<string name="mpris_notification_settings_title">Birta tilkynningar fyrir margmiðlunarstýringar</string>
|
<string name="mpris_notification_settings_title">Birta tilkynningar fyrir margmiðlunarstýringar</string>
|
||||||
<string name="mpris_notification_settings_summary">Gerir kleift að stýra margmiðlunarspilurunum þínum án þess að opna KDE-tengingar</string>
|
<string name="mpris_notification_settings_summary">Gerir kleift að stýra margmiðlunarspilurunum þínum án þess að opna KDE-tengingar</string>
|
||||||
<string name="share_to">Deila með…</string>
|
<string name="share_to">Deila með…</string>
|
||||||
<string name="unreachable_device">%s (ekki aðgengilegt)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
|
<string name="protocol_version">Útgáfa samskiptamáta:</string>
|
||||||
<string name="protocol_version_newer">Þetta tæki notar nýrri útgáfu samskiptastaðals</string>
|
<string name="protocol_version_newer">Þetta tæki notar nýrri útgáfu samskiptastaðals</string>
|
||||||
<string name="plugin_settings_with_name">Stillingar %s</string>
|
<string name="plugin_settings_with_name">Stillingar %s</string>
|
||||||
<string name="invalid_device_name">Ógilt heiti tækis</string>
|
<string name="invalid_device_name">Ógilt heiti tækis</string>
|
||||||
<string name="shareplugin_text_saved">Tók við texta, vistaði á klippispjald</string>
|
<string name="shareplugin_text_saved">Tók við texta, vistaði á klippispjald</string>
|
||||||
<string name="custom_devices_settings">Listi yfir sérsniðin tæki</string>
|
<string name="custom_devices_settings">Listi yfir sérsniðin tæki</string>
|
||||||
|
<string name="custom_devices_settings_summary">%d tækjum bætt við handvirkt</string>
|
||||||
<string name="custom_device_list">Bæta við tækjum eftir auðkennum</string>
|
<string name="custom_device_list">Bæta við tækjum eftir auðkennum</string>
|
||||||
<string name="custom_device_deleted">Sérsniðnu tæki eytt</string>
|
<string name="custom_device_deleted">Sérsniðnu tæki eytt</string>
|
||||||
<string name="custom_device_fab_hint">Bæta við tæki</string>
|
<string name="custom_device_fab_hint">Bæta við tæki</string>
|
||||||
@ -279,6 +281,7 @@
|
|||||||
<string name="devices">Tæki</string>
|
<string name="devices">Tæki</string>
|
||||||
<string name="settings_rename">Heiti tækis</string>
|
<string name="settings_rename">Heiti tækis</string>
|
||||||
<string name="settings_dark_mode">Dökkt þema</string>
|
<string name="settings_dark_mode">Dökkt þema</string>
|
||||||
|
<string name="settings_export_logs">Flytja út atvikaskrár KDE Connect</string>
|
||||||
<string name="settings_more_settings_title">Fleiri stillingar</string>
|
<string name="settings_more_settings_title">Fleiri stillingar</string>
|
||||||
<string name="setting_persistent_notification">Birta viðvarandi tilkynningu</string>
|
<string name="setting_persistent_notification">Birta viðvarandi tilkynningu</string>
|
||||||
<string name="setting_persistent_notification_oreo">Viðvarandi tilkynning</string>
|
<string name="setting_persistent_notification_oreo">Viðvarandi tilkynning</string>
|
||||||
@ -380,4 +383,7 @@
|
|||||||
<string name="mpris_keepwatching">Halda áfram spilun</string>
|
<string name="mpris_keepwatching">Halda áfram spilun</string>
|
||||||
<string name="mpris_keepwatching_settings_title">Halda áfram spilun</string>
|
<string name="mpris_keepwatching_settings_title">Halda áfram spilun</string>
|
||||||
<string name="notification_channel_keepwatching">Halda áfram spilun</string>
|
<string name="notification_channel_keepwatching">Halda áfram spilun</string>
|
||||||
|
<string name="ping_failed">Gat ekki pikkað í tæki</string>
|
||||||
|
<string name="device_host_invalid">Ógilt vélarheiti. Notaðu gilt vélarheiti, IPv4 eða IPv6</string>
|
||||||
|
<string name="device_host_duplicate">Hýsivélin er nú þegar á listanum</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Invia clic tasto centrale</string>
|
<string name="middle_click">Invia clic tasto centrale</string>
|
||||||
<string name="show_keyboard">Mostra tastiera</string>
|
<string name="show_keyboard">Mostra tastiera</string>
|
||||||
<string name="device_not_paired">Dispositivo non associato</string>
|
<string name="device_not_paired">Dispositivo non associato</string>
|
||||||
|
<string name="pairing_duplicate_names">Attenzione: ci sono più dispositivi con lo stesso nome.</string>
|
||||||
<string name="request_pairing">Richiedi associazione</string>
|
<string name="request_pairing">Richiedi associazione</string>
|
||||||
<string name="pairing_accept">Accetta</string>
|
<string name="pairing_accept">Accetta</string>
|
||||||
<string name="pairing_reject">Rifiuta</string>
|
<string name="pairing_reject">Rifiuta</string>
|
||||||
|
<string name="pairing_explanation">L\'associazione di due dispositivi consentirà loro l\'accesso reciproco. Associa solo i tuoi dispositivi.</string>
|
||||||
<string name="settings">Impostazioni</string>
|
<string name="settings">Impostazioni</string>
|
||||||
<string name="mpris_play">Riproduci</string>
|
<string name="mpris_play">Riproduci</string>
|
||||||
<string name="mpris_pause">Pausa</string>
|
<string name="mpris_pause">Pausa</string>
|
||||||
@ -191,7 +193,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Mostra la notifica del controllo multimediale</string>
|
<string name="mpris_notification_settings_title">Mostra la notifica del controllo multimediale</string>
|
||||||
<string name="mpris_notification_settings_summary">Consenti di controllare i lettori multimediali senza aprire KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Consenti di controllare i lettori multimediali senza aprire KDE Connect</string>
|
||||||
<string name="share_to">Condividi con…</string>
|
<string name="share_to">Condividi con…</string>
|
||||||
<string name="unreachable_device">%s (non raggiungibile)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Gli URL condivisi su un dispositivo irraggiungibile saranno recapitati una volta che sarà tornato raggiungibile.\n\n</string>
|
<string name="unreachable_device_url_share_text">Gli URL condivisi su un dispositivo irraggiungibile saranno recapitati una volta che sarà tornato raggiungibile.\n\n</string>
|
||||||
<string name="protocol_version">Versione del protocollo:</string>
|
<string name="protocol_version">Versione del protocollo:</string>
|
||||||
<string name="protocol_version_newer">Questo dispositivo usa una nuova versione del protocollo di rete</string>
|
<string name="protocol_version_newer">Questo dispositivo usa una nuova versione del protocollo di rete</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Dispositivi</string>
|
<string name="devices">Dispositivi</string>
|
||||||
<string name="settings_rename">Nome dispositivo</string>
|
<string name="settings_rename">Nome dispositivo</string>
|
||||||
<string name="settings_dark_mode">Tema scuro</string>
|
<string name="settings_dark_mode">Tema scuro</string>
|
||||||
|
<string name="settings_export_logs">Esporta i registri di KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">Genera un file con informazioni di esecuzione che possono aiutare a risolvere i problemi.</string>
|
||||||
<string name="settings_more_settings_title">Altre impostazioni</string>
|
<string name="settings_more_settings_title">Altre impostazioni</string>
|
||||||
<string name="settings_more_settings_text">Le impostazioni per dispositivo sono disponibili sotto «Impostazioni estensioni» dall\'interno del dispositivo.</string>
|
<string name="settings_more_settings_text">Le impostazioni per dispositivo sono disponibili sotto «Impostazioni estensioni» dall\'interno del dispositivo.</string>
|
||||||
<string name="setting_persistent_notification">Mostra notifica persistente</string>
|
<string name="setting_persistent_notification">Mostra notifica persistente</string>
|
||||||
|
@ -181,9 +181,11 @@
|
|||||||
<string name="middle_click">שליחת לחיצה אמצעית (גלגלת)</string>
|
<string name="middle_click">שליחת לחיצה אמצעית (גלגלת)</string>
|
||||||
<string name="show_keyboard">הצגת מקלדת</string>
|
<string name="show_keyboard">הצגת מקלדת</string>
|
||||||
<string name="device_not_paired">המכשיר לא מצומד</string>
|
<string name="device_not_paired">המכשיר לא מצומד</string>
|
||||||
|
<string name="pairing_duplicate_names">אזהרה: יש כמה מכשירים שונים באותו השם.</string>
|
||||||
<string name="request_pairing">בקשת צימוד</string>
|
<string name="request_pairing">בקשת צימוד</string>
|
||||||
<string name="pairing_accept">אישור</string>
|
<string name="pairing_accept">אישור</string>
|
||||||
<string name="pairing_reject">דחייה</string>
|
<string name="pairing_reject">דחייה</string>
|
||||||
|
<string name="pairing_explanation">צימוד שני מכשירים יעניק להם גישה מאחד לשני ולהפך. יש לצמד רק אם המכשירים הם שלך.</string>
|
||||||
<string name="settings">הגדרות</string>
|
<string name="settings">הגדרות</string>
|
||||||
<string name="mpris_play">נגינה</string>
|
<string name="mpris_play">נגינה</string>
|
||||||
<string name="mpris_pause">השהיה</string>
|
<string name="mpris_pause">השהיה</string>
|
||||||
@ -207,7 +209,7 @@
|
|||||||
<string name="mpris_notification_settings_title">הצגת התראות בקרת מדיה</string>
|
<string name="mpris_notification_settings_title">הצגת התראות בקרת מדיה</string>
|
||||||
<string name="mpris_notification_settings_summary">לאפשר שליטה בנגני המדיה שלך מבלי לפתוח את KDE Connect</string>
|
<string name="mpris_notification_settings_summary">לאפשר שליטה בנגני המדיה שלך מבלי לפתוח את KDE Connect</string>
|
||||||
<string name="share_to">שיתוף אל…</string>
|
<string name="share_to">שיתוף אל…</string>
|
||||||
<string name="unreachable_device">%s (לא נגיש)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">כתובות שותפו להתקן בלתי נגיש והן תועברנה אליו ברגע שישוב להיות נגיש.\n\n</string>
|
<string name="unreachable_device_url_share_text">כתובות שותפו להתקן בלתי נגיש והן תועברנה אליו ברגע שישוב להיות נגיש.\n\n</string>
|
||||||
<string name="protocol_version">גרסת פרוטוקול:</string>
|
<string name="protocol_version">גרסת פרוטוקול:</string>
|
||||||
<string name="protocol_version_newer">המכשיר משתמש בגרסה חדשה יותר</string>
|
<string name="protocol_version_newer">המכשיר משתמש בגרסה חדשה יותר</string>
|
||||||
@ -325,6 +327,8 @@
|
|||||||
<string name="devices">מכשירים</string>
|
<string name="devices">מכשירים</string>
|
||||||
<string name="settings_rename">שם המכשיר</string>
|
<string name="settings_rename">שם המכשיר</string>
|
||||||
<string name="settings_dark_mode">ערכת עיצוב כהה</string>
|
<string name="settings_dark_mode">ערכת עיצוב כהה</string>
|
||||||
|
<string name="settings_export_logs">ייצוא היומנים של KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">ליצור קובץ עם פרטי הפעלה שיכול לסייע בפתרון תקלות.</string>
|
||||||
<string name="settings_more_settings_title">הגדרות נוספות</string>
|
<string name="settings_more_settings_title">הגדרות נוספות</string>
|
||||||
<string name="settings_more_settings_text">אפשר למצוא הגדרות נקודתיות למכשיר תחת ‚הגדרות תוסף’ מתוך המכשיר.</string>
|
<string name="settings_more_settings_text">אפשר למצוא הגדרות נקודתיות למכשיר תחת ‚הגדרות תוסף’ מתוך המכשיר.</string>
|
||||||
<string name="setting_persistent_notification">הצגת התראה קבועה</string>
|
<string name="setting_persistent_notification">הצגת התראה קבועה</string>
|
||||||
|
@ -182,7 +182,6 @@
|
|||||||
<string name="mpris_notification_settings_title">メディア操作の通知を表示</string>
|
<string name="mpris_notification_settings_title">メディア操作の通知を表示</string>
|
||||||
<string name="mpris_notification_settings_summary">KDE Connect を開かずにメディアプレーヤーをコントロール可能にします</string>
|
<string name="mpris_notification_settings_summary">KDE Connect を開かずにメディアプレーヤーをコントロール可能にします</string>
|
||||||
<string name="share_to">共有先...</string>
|
<string name="share_to">共有先...</string>
|
||||||
<string name="unreachable_device">%s (到達不可)</string>
|
|
||||||
<string name="unreachable_device_url_share_text">到達できないデバイスと共有された URL はデバイスが到達可能になったときに送信されます。\n\n</string>
|
<string name="unreachable_device_url_share_text">到達できないデバイスと共有された URL はデバイスが到達可能になったときに送信されます。\n\n</string>
|
||||||
<string name="protocol_version_newer">このデバイスはより新しいプロトコルバージョンを使用しています</string>
|
<string name="protocol_version_newer">このデバイスはより新しいプロトコルバージョンを使用しています</string>
|
||||||
<string name="plugin_settings_with_name">%s 設定</string>
|
<string name="plugin_settings_with_name">%s 設定</string>
|
||||||
|
@ -89,15 +89,12 @@
|
|||||||
<string name="error_not_reachable">მოწყობილობა მიუწვდოელია</string>
|
<string name="error_not_reachable">მოწყობილობა მიუწვდოელია</string>
|
||||||
<string name="error_already_paired">მოწყობილობა უკვე დაწყვილებულია</string>
|
<string name="error_already_paired">მოწყობილობა უკვე დაწყვილებულია</string>
|
||||||
<string name="error_timed_out">ვადა გავიდა</string>
|
<string name="error_timed_out">ვადა გავიდა</string>
|
||||||
|
<string name="error_clocks_not_match">მოწყობილობის საათების სინქრონიზაცია დარღვეულია</string>
|
||||||
<string name="error_canceled_by_user">გაუქმებულია მომხმარებლის მიერ</string>
|
<string name="error_canceled_by_user">გაუქმებულია მომხმარებლის მიერ</string>
|
||||||
<string name="error_canceled_by_other_peer">გაუქმებულია პარტნიორის მიერ</string>
|
<string name="error_canceled_by_other_peer">გაუქმებულია პარტნიორის მიერ</string>
|
||||||
<string name="encryption_info_title">დაშიფვრის ინფორმაცია</string>
|
<string name="encryption_info_title">დაშიფვრის ინფორმაცია</string>
|
||||||
<string name="pair_requested">დაწყვილების მოთხოვნა</string>
|
<string name="pair_requested">დაწყვილების მოთხოვნა</string>
|
||||||
<string name="pair_succeeded">დაწყვილება წარმატებულია</string>
|
<string name="pair_succeeded">დაწყვილება წარმატებულია</string>
|
||||||
<plurals name="incoming_files_text">
|
|
||||||
<item quantity="one">File: %1s</item>
|
|
||||||
<item quantity="other">(File %2$d of %3$d) : %1$s</item>
|
|
||||||
</plurals>
|
|
||||||
<plurals name="outgoing_files_text">
|
<plurals name="outgoing_files_text">
|
||||||
<item quantity="one">ფაილი: %1$s</item>
|
<item quantity="one">ფაილი: %1$s</item>
|
||||||
<item quantity="other">(ფაილი %2$d of %3$d) : %1$s</item>
|
<item quantity="other">(ფაილი %2$d of %3$d) : %1$s</item>
|
||||||
@ -133,7 +130,7 @@
|
|||||||
<item>2 წუთი</item>
|
<item>2 წუთი</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="share_to">გაზიარება…</string>
|
<string name="share_to">გაზიარება…</string>
|
||||||
<string name="unreachable_device">%s (მიუწვდომელია)</string>
|
<string name="protocol_version">პროტოკოლის ვერსია:</string>
|
||||||
<string name="protocol_version_newer">მოწყობილობა პროტოკოლის უფრო ახალ ვერსიას იყენებს</string>
|
<string name="protocol_version_newer">მოწყობილობა პროტოკოლის უფრო ახალ ვერსიას იყენებს</string>
|
||||||
<string name="plugin_settings_with_name">%s-ის მორგება</string>
|
<string name="plugin_settings_with_name">%s-ის მორგება</string>
|
||||||
<string name="invalid_device_name">მოწყობილობის არასწორი სახელი</string>
|
<string name="invalid_device_name">მოწყობილობის არასწორი სახელი</string>
|
||||||
@ -217,6 +214,7 @@
|
|||||||
<string name="devices">მოწყობილობები</string>
|
<string name="devices">მოწყობილობები</string>
|
||||||
<string name="settings_rename">მოწყობილობის სახელი</string>
|
<string name="settings_rename">მოწყობილობის სახელი</string>
|
||||||
<string name="settings_dark_mode">ბნელი თემა</string>
|
<string name="settings_dark_mode">ბნელი თემა</string>
|
||||||
|
<string name="settings_export_logs">KDE Connect-ის ჟურნალის გატანა</string>
|
||||||
<string name="settings_more_settings_title">მეტი პარამეტრი</string>
|
<string name="settings_more_settings_title">მეტი პარამეტრი</string>
|
||||||
<string name="extra_options">დამატებითი პარამეტრები</string>
|
<string name="extra_options">დამატებითი პარამეტრები</string>
|
||||||
<string name="privacy_options">კონფიდენციალობის პარამეტრები</string>
|
<string name="privacy_options">კონფიდენციალობის პარამეტრები</string>
|
||||||
@ -292,4 +290,5 @@
|
|||||||
<string name="send_clipboard">ბუფერის გაგზავნა</string>
|
<string name="send_clipboard">ბუფერის გაგზავნა</string>
|
||||||
<string name="tap_to_execute">ქმედების შესასრულებლად დაატყაპუნეთ</string>
|
<string name="tap_to_execute">ქმედების შესასრულებლად დაატყაპუნეთ</string>
|
||||||
<string name="plugin_stats">მოდულის სტატისტიკა</string>
|
<string name="plugin_stats">მოდულის სტატისტიკა</string>
|
||||||
|
<string name="ping_failed">მოწყობილობა არ იპინგება</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
<string name="error_not_reachable">장치에 접근할 수 없음</string>
|
<string name="error_not_reachable">장치에 접근할 수 없음</string>
|
||||||
<string name="error_already_paired">장치가 이미 페어링됨</string>
|
<string name="error_already_paired">장치가 이미 페어링됨</string>
|
||||||
<string name="error_timed_out">시간 초과됨</string>
|
<string name="error_timed_out">시간 초과됨</string>
|
||||||
|
<string name="error_clocks_not_match">장치 시계가 맞지 않음</string>
|
||||||
<string name="error_canceled_by_user">사용자가 취소함</string>
|
<string name="error_canceled_by_user">사용자가 취소함</string>
|
||||||
<string name="error_canceled_by_other_peer">다른 쪽에서 취소함</string>
|
<string name="error_canceled_by_other_peer">다른 쪽에서 취소함</string>
|
||||||
<string name="encryption_info_title">암호화 정보</string>
|
<string name="encryption_info_title">암호화 정보</string>
|
||||||
@ -156,9 +157,11 @@
|
|||||||
<string name="middle_click">가운데 단추 클릭 신호 보내기</string>
|
<string name="middle_click">가운데 단추 클릭 신호 보내기</string>
|
||||||
<string name="show_keyboard">키보드 표시</string>
|
<string name="show_keyboard">키보드 표시</string>
|
||||||
<string name="device_not_paired">장치가 페어링되지 않음</string>
|
<string name="device_not_paired">장치가 페어링되지 않음</string>
|
||||||
|
<string name="pairing_duplicate_names">경고: 이름이 같은 장치가 여러 대 있습니다.</string>
|
||||||
<string name="request_pairing">페어링 요청</string>
|
<string name="request_pairing">페어링 요청</string>
|
||||||
<string name="pairing_accept">수락</string>
|
<string name="pairing_accept">수락</string>
|
||||||
<string name="pairing_reject">거부</string>
|
<string name="pairing_reject">거부</string>
|
||||||
|
<string name="pairing_explanation">두 장치를 페어링하면 서로간의 접근을 허용합니다. 내 장치끼리만 페어링하십시오.</string>
|
||||||
<string name="settings">설정</string>
|
<string name="settings">설정</string>
|
||||||
<string name="mpris_play">재생</string>
|
<string name="mpris_play">재생</string>
|
||||||
<string name="mpris_pause">일시 정지</string>
|
<string name="mpris_pause">일시 정지</string>
|
||||||
@ -182,13 +185,15 @@
|
|||||||
<string name="mpris_notification_settings_title">미디어 제어 알림 표시</string>
|
<string name="mpris_notification_settings_title">미디어 제어 알림 표시</string>
|
||||||
<string name="mpris_notification_settings_summary">KDE Connect를 열지 않고 미디어 재생기 제어</string>
|
<string name="mpris_notification_settings_summary">KDE Connect를 열지 않고 미디어 재생기 제어</string>
|
||||||
<string name="share_to">다음으로 공유…</string>
|
<string name="share_to">다음으로 공유…</string>
|
||||||
<string name="unreachable_device">%s(접근할 수 없음)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s(✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">접근할 수 없는 장치와 공유한 URL은 장치에 다시 접근할 수 있게 될 때 전달됩니다.\n\n</string>
|
<string name="unreachable_device_url_share_text">접근할 수 없는 장치와 공유한 URL은 장치에 다시 접근할 수 있게 될 때 전달됩니다.\n\n</string>
|
||||||
|
<string name="protocol_version">프로토콜 버전:</string>
|
||||||
<string name="protocol_version_newer">이 장치의 프로토콜 버전이 더 새롭습니다</string>
|
<string name="protocol_version_newer">이 장치의 프로토콜 버전이 더 새롭습니다</string>
|
||||||
<string name="plugin_settings_with_name">%s 설정</string>
|
<string name="plugin_settings_with_name">%s 설정</string>
|
||||||
<string name="invalid_device_name">잘못된 장치 이름</string>
|
<string name="invalid_device_name">잘못된 장치 이름</string>
|
||||||
<string name="shareplugin_text_saved">텍스트 수신, 클립보드에 복사됨</string>
|
<string name="shareplugin_text_saved">텍스트 수신, 클립보드에 복사됨</string>
|
||||||
<string name="custom_devices_settings">사용자 정의 장치 목록</string>
|
<string name="custom_devices_settings">사용자 정의 장치 목록</string>
|
||||||
|
<string name="custom_devices_settings_summary">장치 %d개를 수동으로 추가함</string>
|
||||||
<string name="custom_device_list">IP로 장치 추가</string>
|
<string name="custom_device_list">IP로 장치 추가</string>
|
||||||
<string name="custom_device_deleted">사용자 정의 장치 삭제됨</string>
|
<string name="custom_device_deleted">사용자 정의 장치 삭제됨</string>
|
||||||
<string name="custom_device_list_help">장치가 자동으로 감지되지 않았다면 떠 다니는 동작 단추를 클릭해서 IP 주소나 호스트 이름으로 장치를 수동으로 추가할 수 있습니다</string>
|
<string name="custom_device_list_help">장치가 자동으로 감지되지 않았다면 떠 다니는 동작 단추를 클릭해서 IP 주소나 호스트 이름으로 장치를 수동으로 추가할 수 있습니다</string>
|
||||||
@ -298,6 +303,8 @@
|
|||||||
<string name="devices">장치</string>
|
<string name="devices">장치</string>
|
||||||
<string name="settings_rename">장치 이름</string>
|
<string name="settings_rename">장치 이름</string>
|
||||||
<string name="settings_dark_mode">어두운 테마</string>
|
<string name="settings_dark_mode">어두운 테마</string>
|
||||||
|
<string name="settings_export_logs">KDE Connect 로그 내보내기</string>
|
||||||
|
<string name="settings_export_logs_text">문제 해결을 위해서 실행 정보를 포함하는 파일을 생성합니다.</string>
|
||||||
<string name="settings_more_settings_title">더 많은 설정</string>
|
<string name="settings_more_settings_title">더 많은 설정</string>
|
||||||
<string name="settings_more_settings_text">장치별 설정은 각각 장치의 \'플러그인 설정\'에서 확인할 수 있습니다.</string>
|
<string name="settings_more_settings_text">장치별 설정은 각각 장치의 \'플러그인 설정\'에서 확인할 수 있습니다.</string>
|
||||||
<string name="setting_persistent_notification">항상 표시되는 알림 표시</string>
|
<string name="setting_persistent_notification">항상 표시되는 알림 표시</string>
|
||||||
|
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Verstuur een middelste muisklik</string>
|
<string name="middle_click">Verstuur een middelste muisklik</string>
|
||||||
<string name="show_keyboard">Toetsenbord tonen</string>
|
<string name="show_keyboard">Toetsenbord tonen</string>
|
||||||
<string name="device_not_paired">Apparaat is niet gepaard</string>
|
<string name="device_not_paired">Apparaat is niet gepaard</string>
|
||||||
|
<string name="pairing_duplicate_names">Voorzichtig: er zijn meerdere apparaten met dezelfde naam.</string>
|
||||||
<string name="request_pairing">Verzoek voor maken van paar</string>
|
<string name="request_pairing">Verzoek voor maken van paar</string>
|
||||||
<string name="pairing_accept">Accepteren</string>
|
<string name="pairing_accept">Accepteren</string>
|
||||||
<string name="pairing_reject">Afwijzen</string>
|
<string name="pairing_reject">Afwijzen</string>
|
||||||
|
<string name="pairing_explanation">Twee apparaten paren zal ze toegang geven tot elkaar. Paar alleen uw eigen apparaten.</string>
|
||||||
<string name="settings">Instellingen</string>
|
<string name="settings">Instellingen</string>
|
||||||
<string name="mpris_play">Afspelen</string>
|
<string name="mpris_play">Afspelen</string>
|
||||||
<string name="mpris_pause">Pauzeren</string>
|
<string name="mpris_pause">Pauzeren</string>
|
||||||
@ -191,7 +193,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Mediabesturingsmelding tonen</string>
|
<string name="mpris_notification_settings_title">Mediabesturingsmelding tonen</string>
|
||||||
<string name="mpris_notification_settings_summary">Staat besturing van uw mediaspelers toe zonder KDE Connect te openen</string>
|
<string name="mpris_notification_settings_summary">Staat besturing van uw mediaspelers toe zonder KDE Connect te openen</string>
|
||||||
<string name="share_to">Delen met…</string>
|
<string name="share_to">Delen met…</string>
|
||||||
<string name="unreachable_device">%s (niet bereikbaar)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">URL\'s gedeeld met een niet bereikbaar apparaat zullen er afgeleverd worden wanneer deze bereikbaar wordt.\n\n</string>
|
<string name="unreachable_device_url_share_text">URL\'s gedeeld met een niet bereikbaar apparaat zullen er afgeleverd worden wanneer deze bereikbaar wordt.\n\n</string>
|
||||||
<string name="protocol_version">Protocolversie:</string>
|
<string name="protocol_version">Protocolversie:</string>
|
||||||
<string name="protocol_version_newer">Dit apparaat gebruikt een nieuwere protocolversie</string>
|
<string name="protocol_version_newer">Dit apparaat gebruikt een nieuwere protocolversie</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Apparaten</string>
|
<string name="devices">Apparaten</string>
|
||||||
<string name="settings_rename">Apparaatnaam</string>
|
<string name="settings_rename">Apparaatnaam</string>
|
||||||
<string name="settings_dark_mode">Donker thema</string>
|
<string name="settings_dark_mode">Donker thema</string>
|
||||||
|
<string name="settings_export_logs">Logs van KDE Connect exporteren</string>
|
||||||
|
<string name="settings_export_logs_text">Genereert een bestand met uitvoeringsinformatie die kan helpen problemen op te lossen.</string>
|
||||||
<string name="settings_more_settings_title">Meer instellingen</string>
|
<string name="settings_more_settings_title">Meer instellingen</string>
|
||||||
<string name="settings_more_settings_text">Instellingen per apparaat kunnen gevonden worden onder \'Plug-in-instellingen\' vanuit een apparaat.</string>
|
<string name="settings_more_settings_text">Instellingen per apparaat kunnen gevonden worden onder \'Plug-in-instellingen\' vanuit een apparaat.</string>
|
||||||
<string name="setting_persistent_notification">Blijvende melding tonen</string>
|
<string name="setting_persistent_notification">Blijvende melding tonen</string>
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
<string name="error_not_reachable">Får ikkje kontakt med eininga</string>
|
<string name="error_not_reachable">Får ikkje kontakt med eininga</string>
|
||||||
<string name="error_already_paired">Eininga er alt para</string>
|
<string name="error_already_paired">Eininga er alt para</string>
|
||||||
<string name="error_timed_out">Tidsavbrot</string>
|
<string name="error_timed_out">Tidsavbrot</string>
|
||||||
|
<string name="error_clocks_not_match">Einingsklokkene er ikkje synkroniserte</string>
|
||||||
<string name="error_canceled_by_user">Avbroten av brukar</string>
|
<string name="error_canceled_by_user">Avbroten av brukar</string>
|
||||||
<string name="error_canceled_by_other_peer">Avbroten av den andre eininga</string>
|
<string name="error_canceled_by_other_peer">Avbroten av den andre eininga</string>
|
||||||
<string name="encryption_info_title">Krypteringsinfo</string>
|
<string name="encryption_info_title">Krypteringsinfo</string>
|
||||||
@ -164,9 +165,11 @@
|
|||||||
<string name="middle_click">Send midtklikk</string>
|
<string name="middle_click">Send midtklikk</string>
|
||||||
<string name="show_keyboard">Vis tastatur</string>
|
<string name="show_keyboard">Vis tastatur</string>
|
||||||
<string name="device_not_paired">Eininga er ikkje para</string>
|
<string name="device_not_paired">Eininga er ikkje para</string>
|
||||||
|
<string name="pairing_duplicate_names">Åtvaring: Det finst fleire einingar med same namn.</string>
|
||||||
<string name="request_pairing">Be om paring</string>
|
<string name="request_pairing">Be om paring</string>
|
||||||
<string name="pairing_accept">Godta</string>
|
<string name="pairing_accept">Godta</string>
|
||||||
<string name="pairing_reject">Avvis</string>
|
<string name="pairing_reject">Avvis</string>
|
||||||
|
<string name="pairing_explanation">Ved paring av einingar, gjev du dei tilgang til kvarandre. Berre par saman einingar som du sjølv eig.</string>
|
||||||
<string name="settings">Innstillingar</string>
|
<string name="settings">Innstillingar</string>
|
||||||
<string name="mpris_play">Spel</string>
|
<string name="mpris_play">Spel</string>
|
||||||
<string name="mpris_pause">Pause</string>
|
<string name="mpris_pause">Pause</string>
|
||||||
@ -190,13 +193,15 @@
|
|||||||
<string name="mpris_notification_settings_title">Vis varsling med avspelingskontrollar</string>
|
<string name="mpris_notification_settings_title">Vis varsling med avspelingskontrollar</string>
|
||||||
<string name="mpris_notification_settings_summary">Tillat å kontrollera mediespelarar utan å opna KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Tillat å kontrollera mediespelarar utan å opna KDE Connect</string>
|
||||||
<string name="share_to">Del til …</string>
|
<string name="share_to">Del til …</string>
|
||||||
<string name="unreachable_device">%s (får ikkje kontakt med)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Adresser delte til ei utilgjengeleg eining vert leverte når eininga vert tilgjengeleg att.\n\n</string>
|
<string name="unreachable_device_url_share_text">Adresser delte til ei utilgjengeleg eining vert leverte når eininga vert tilgjengeleg att.\n\n</string>
|
||||||
|
<string name="protocol_version">Protokollversjon:</string>
|
||||||
<string name="protocol_version_newer">Denne eininga brukar ein nyare protokollversjon</string>
|
<string name="protocol_version_newer">Denne eininga brukar ein nyare protokollversjon</string>
|
||||||
<string name="plugin_settings_with_name">%s-innstillingar</string>
|
<string name="plugin_settings_with_name">%s-innstillingar</string>
|
||||||
<string name="invalid_device_name">Ugyldig einingsnamn</string>
|
<string name="invalid_device_name">Ugyldig einingsnamn</string>
|
||||||
<string name="shareplugin_text_saved">Fekk tekst, som vart lagra på utklippstavla</string>
|
<string name="shareplugin_text_saved">Fekk tekst, som vart lagra på utklippstavla</string>
|
||||||
<string name="custom_devices_settings">Tilpassa einingsliste</string>
|
<string name="custom_devices_settings">Tilpassa einingsliste</string>
|
||||||
|
<string name="custom_devices_settings_summary">%d lagde til manuelt</string>
|
||||||
<string name="custom_device_list">Legg til eining basert på IP</string>
|
<string name="custom_device_list">Legg til eining basert på IP</string>
|
||||||
<string name="custom_device_deleted">Tilpassa eining er sletta</string>
|
<string name="custom_device_deleted">Tilpassa eining er sletta</string>
|
||||||
<string name="custom_device_list_help">Viss eininga ikkje vert funnen automatisk, kan du leggja til IP-adressa eller vertsnamnet til eininga ved å trykka på handlingsknappen</string>
|
<string name="custom_device_list_help">Viss eininga ikkje vert funnen automatisk, kan du leggja til IP-adressa eller vertsnamnet til eininga ved å trykka på handlingsknappen</string>
|
||||||
@ -306,6 +311,7 @@
|
|||||||
<string name="devices">Einingar</string>
|
<string name="devices">Einingar</string>
|
||||||
<string name="settings_rename">Einingsnamn</string>
|
<string name="settings_rename">Einingsnamn</string>
|
||||||
<string name="settings_dark_mode">Mørkt tema</string>
|
<string name="settings_dark_mode">Mørkt tema</string>
|
||||||
|
<string name="settings_export_logs">Eksporter KDE Connect-loggar</string>
|
||||||
<string name="settings_more_settings_title">Fleire innstillingar</string>
|
<string name="settings_more_settings_title">Fleire innstillingar</string>
|
||||||
<string name="settings_more_settings_text">Innstillingar for einskildeiningar finn du under «Programtillegg-oppsett» på kvar eining.</string>
|
<string name="settings_more_settings_text">Innstillingar for einskildeiningar finn du under «Programtillegg-oppsett» på kvar eining.</string>
|
||||||
<string name="setting_persistent_notification">Vis evigvarande varsling</string>
|
<string name="setting_persistent_notification">Vis evigvarande varsling</string>
|
||||||
@ -419,4 +425,9 @@
|
|||||||
<string name="mpris_keepwatching_settings_title">Hald fram avspeling</string>
|
<string name="mpris_keepwatching_settings_title">Hald fram avspeling</string>
|
||||||
<string name="mpris_keepwatching_settings_summary">Vis ei stille varsling om framhald av medieavspeling på eininga etter avspelingsstopp</string>
|
<string name="mpris_keepwatching_settings_summary">Vis ei stille varsling om framhald av medieavspeling på eininga etter avspelingsstopp</string>
|
||||||
<string name="notification_channel_keepwatching">Hald fram avspeling</string>
|
<string name="notification_channel_keepwatching">Hald fram avspeling</string>
|
||||||
|
<string name="ping_result">Pinga på %1$d millisekund</string>
|
||||||
|
<string name="ping_failed">Klarte ikkje pinga eininga</string>
|
||||||
|
<string name="ping_in_progress">Pingar …</string>
|
||||||
|
<string name="device_host_invalid">Ugyldig vert. Bruk eit gyldig vertsnamn, IPv4 eller IPv6.</string>
|
||||||
|
<string name="device_host_duplicate">Verten finst i lista frå før</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -181,9 +181,11 @@
|
|||||||
<string name="middle_click">Wyślij kliknięcie środkowym</string>
|
<string name="middle_click">Wyślij kliknięcie środkowym</string>
|
||||||
<string name="show_keyboard">Pokaż klawiaturę</string>
|
<string name="show_keyboard">Pokaż klawiaturę</string>
|
||||||
<string name="device_not_paired">Urządzenie niesparowane</string>
|
<string name="device_not_paired">Urządzenie niesparowane</string>
|
||||||
|
<string name="pairing_duplicate_names">Uwaga: Istnieje wiele urządzeń o tej samej nazwie.</string>
|
||||||
<string name="request_pairing">Prośba o sparowanie</string>
|
<string name="request_pairing">Prośba o sparowanie</string>
|
||||||
<string name="pairing_accept">Przyjmij</string>
|
<string name="pairing_accept">Przyjmij</string>
|
||||||
<string name="pairing_reject">Odrzuć</string>
|
<string name="pairing_reject">Odrzuć</string>
|
||||||
|
<string name="pairing_explanation">Sparowanie dwóch urządzeń da im dostęp do siebie nawzajem. Paruj tylko swoje własne urządzenia.</string>
|
||||||
<string name="settings">Ustawienia</string>
|
<string name="settings">Ustawienia</string>
|
||||||
<string name="mpris_play">Odtwórz</string>
|
<string name="mpris_play">Odtwórz</string>
|
||||||
<string name="mpris_pause">Wstrzymaj</string>
|
<string name="mpris_pause">Wstrzymaj</string>
|
||||||
@ -207,7 +209,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Pokaż powiadomienia sterowania mediami</string>
|
<string name="mpris_notification_settings_title">Pokaż powiadomienia sterowania mediami</string>
|
||||||
<string name="mpris_notification_settings_summary">Steruje odtwarzaczami bez otwierania KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Steruje odtwarzaczami bez otwierania KDE Connect</string>
|
||||||
<string name="share_to">Udostępnij urządzeniu...</string>
|
<string name="share_to">Udostępnij urządzeniu...</string>
|
||||||
<string name="unreachable_device">%s (nieosiągalne)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Adres URL udostępniony nieosiągalnemu urządzeniu zostanie do niego dostarczony zaraz po tym jak stanie się osiągalne.\n\n</string>
|
<string name="unreachable_device_url_share_text">Adres URL udostępniony nieosiągalnemu urządzeniu zostanie do niego dostarczony zaraz po tym jak stanie się osiągalne.\n\n</string>
|
||||||
<string name="protocol_version">Wersja protokołu:</string>
|
<string name="protocol_version">Wersja protokołu:</string>
|
||||||
<string name="protocol_version_newer">Urządzenie to używa nowszej wersji protokołu</string>
|
<string name="protocol_version_newer">Urządzenie to używa nowszej wersji protokołu</string>
|
||||||
@ -325,6 +327,8 @@
|
|||||||
<string name="devices">Urządzenia</string>
|
<string name="devices">Urządzenia</string>
|
||||||
<string name="settings_rename">Nazwa urządzenia</string>
|
<string name="settings_rename">Nazwa urządzenia</string>
|
||||||
<string name="settings_dark_mode">Ciemny wygląd</string>
|
<string name="settings_dark_mode">Ciemny wygląd</string>
|
||||||
|
<string name="settings_export_logs">Wyeksportuj dziennik KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">Utwórz plik zawierający ślad wykonywania, który może pomóc w rozwiązywaniu błędów.</string>
|
||||||
<string name="settings_more_settings_title">Więcej ustawień</string>
|
<string name="settings_more_settings_title">Więcej ustawień</string>
|
||||||
<string name="settings_more_settings_text">Dodatkowe ustawienia, dotyczące danego urządzenia, można znaleźć po wejściu na nie i wybranie „Ustawienia wtyczek”.</string>
|
<string name="settings_more_settings_text">Dodatkowe ustawienia, dotyczące danego urządzenia, można znaleźć po wejściu na nie i wybranie „Ustawienia wtyczek”.</string>
|
||||||
<string name="setting_persistent_notification">Pokaż nieznikające powiadomienia</string>
|
<string name="setting_persistent_notification">Pokaż nieznikające powiadomienia</string>
|
||||||
|
@ -190,7 +190,6 @@
|
|||||||
<string name="mpris_notification_settings_title">Mostrar a notificação do controle multimídia</string>
|
<string name="mpris_notification_settings_title">Mostrar a notificação do controle multimídia</string>
|
||||||
<string name="mpris_notification_settings_summary">Permite controlar os seus reprodutores de mídias sem abrir o KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Permite controlar os seus reprodutores de mídias sem abrir o KDE Connect</string>
|
||||||
<string name="share_to">Compartilhar com...</string>
|
<string name="share_to">Compartilhar com...</string>
|
||||||
<string name="unreachable_device">%s (Inalcançável)</string>
|
|
||||||
<string name="unreachable_device_url_share_text">URLs compartilhadas com um dispositivo inalcançável serão enviadas para ele assim que ele voltar a ficar disponível.\n\n</string>
|
<string name="unreachable_device_url_share_text">URLs compartilhadas com um dispositivo inalcançável serão enviadas para ele assim que ele voltar a ficar disponível.\n\n</string>
|
||||||
<string name="protocol_version_newer">Este dispositivo usa uma versão mais recente do protocolo</string>
|
<string name="protocol_version_newer">Este dispositivo usa uma versão mais recente do protocolo</string>
|
||||||
<string name="plugin_settings_with_name">Configurações de %s</string>
|
<string name="plugin_settings_with_name">Configurações de %s</string>
|
||||||
|
File diff suppressed because one or more lines are too long
@ -181,9 +181,11 @@
|
|||||||
<string name="middle_click">Pošlji sredinski klik</string>
|
<string name="middle_click">Pošlji sredinski klik</string>
|
||||||
<string name="show_keyboard">Pokaži tipkovnico</string>
|
<string name="show_keyboard">Pokaži tipkovnico</string>
|
||||||
<string name="device_not_paired">Naprava ni uparjena</string>
|
<string name="device_not_paired">Naprava ni uparjena</string>
|
||||||
|
<string name="pairing_duplicate_names">POZOR: Obstaja več naprav z istim imenom.</string>
|
||||||
<string name="request_pairing">Zahtevaj uparjanje</string>
|
<string name="request_pairing">Zahtevaj uparjanje</string>
|
||||||
<string name="pairing_accept">Sprejmi</string>
|
<string name="pairing_accept">Sprejmi</string>
|
||||||
<string name="pairing_reject">Zavrni</string>
|
<string name="pairing_reject">Zavrni</string>
|
||||||
|
<string name="pairing_explanation">Uparjanje dveh naprav jim bo omogočilo dostop ene do druge. Uparjajte samo svoje lastne naprave.</string>
|
||||||
<string name="settings">Nastavitve</string>
|
<string name="settings">Nastavitve</string>
|
||||||
<string name="mpris_play">Predvajaj</string>
|
<string name="mpris_play">Predvajaj</string>
|
||||||
<string name="mpris_pause">Premor</string>
|
<string name="mpris_pause">Premor</string>
|
||||||
@ -207,7 +209,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Pokaži obvestilo o nadzoru medija</string>
|
<string name="mpris_notification_settings_title">Pokaži obvestilo o nadzoru medija</string>
|
||||||
<string name="mpris_notification_settings_summary">Dovoli nadzor nad predvajalniki medijev, ne da bi odprli KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Dovoli nadzor nad predvajalniki medijev, ne da bi odprli KDE Connect</string>
|
||||||
<string name="share_to">Deli z…</string>
|
<string name="share_to">Deli z…</string>
|
||||||
<string name="unreachable_device">%s (Nedosegljiva)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">URL-ji, ki so v skupni rabi z nedosegljivo napravo, ji bodo dostavljeni, ko postane dosegljiva.\n\n</string>
|
<string name="unreachable_device_url_share_text">URL-ji, ki so v skupni rabi z nedosegljivo napravo, ji bodo dostavljeni, ko postane dosegljiva.\n\n</string>
|
||||||
<string name="protocol_version">Protokol različice:</string>
|
<string name="protocol_version">Protokol različice:</string>
|
||||||
<string name="protocol_version_newer">Ta naprava uporablja novejšo različico protokola</string>
|
<string name="protocol_version_newer">Ta naprava uporablja novejšo različico protokola</string>
|
||||||
@ -325,6 +327,8 @@
|
|||||||
<string name="devices">Naprave</string>
|
<string name="devices">Naprave</string>
|
||||||
<string name="settings_rename">Ime naprave</string>
|
<string name="settings_rename">Ime naprave</string>
|
||||||
<string name="settings_dark_mode">Temna tema</string>
|
<string name="settings_dark_mode">Temna tema</string>
|
||||||
|
<string name="settings_export_logs">Izvozi dnevnike KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">Ustvari datoteko z informacijami o izvajanju, ki lahko pomagajo pri odpravljanju težav.</string>
|
||||||
<string name="settings_more_settings_title">Več nastavitev</string>
|
<string name="settings_more_settings_title">Več nastavitev</string>
|
||||||
<string name="settings_more_settings_text">Nastavitve posamezne naprave najdete v razdelku \'Nastavitve vtičnikov\' v napravi.</string>
|
<string name="settings_more_settings_text">Nastavitve posamezne naprave najdete v razdelku \'Nastavitve vtičnikov\' v napravi.</string>
|
||||||
<string name="setting_persistent_notification">Prikazuj trajno obvestilo</string>
|
<string name="setting_persistent_notification">Prikazuj trajno obvestilo</string>
|
||||||
|
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Skicka mittenklick</string>
|
<string name="middle_click">Skicka mittenklick</string>
|
||||||
<string name="show_keyboard">Visa tangentbord</string>
|
<string name="show_keyboard">Visa tangentbord</string>
|
||||||
<string name="device_not_paired">Apparat inte parkopplad</string>
|
<string name="device_not_paired">Apparat inte parkopplad</string>
|
||||||
|
<string name="pairing_duplicate_names">Varning: Det finns flera enheter med samma namn.</string>
|
||||||
<string name="request_pairing">Begär parkoppling</string>
|
<string name="request_pairing">Begär parkoppling</string>
|
||||||
<string name="pairing_accept">Acceptera</string>
|
<string name="pairing_accept">Acceptera</string>
|
||||||
<string name="pairing_reject">Avslå</string>
|
<string name="pairing_reject">Avslå</string>
|
||||||
|
<string name="pairing_explanation">Parkoppling av två enheter ger dem tillgång till varandra. Parkoppla bara dina egna enheter.</string>
|
||||||
<string name="settings">Inställningar</string>
|
<string name="settings">Inställningar</string>
|
||||||
<string name="mpris_play">Spela</string>
|
<string name="mpris_play">Spela</string>
|
||||||
<string name="mpris_pause">Paus</string>
|
<string name="mpris_pause">Paus</string>
|
||||||
@ -191,7 +193,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Visa underrättelser om mediastyrning</string>
|
<string name="mpris_notification_settings_title">Visa underrättelser om mediastyrning</string>
|
||||||
<string name="mpris_notification_settings_summary">Tillåt att styra mediaspelare utan att KDE-anslut öppnas</string>
|
<string name="mpris_notification_settings_summary">Tillåt att styra mediaspelare utan att KDE-anslut öppnas</string>
|
||||||
<string name="share_to">Dela med…</string>
|
<string name="share_to">Dela med…</string>
|
||||||
<string name="unreachable_device">%s (kan inte nås)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Webbadress som delas med en apparat som inte kan nås levereras till den när den väl blir möjlig att nå.\n\n</string>
|
<string name="unreachable_device_url_share_text">Webbadress som delas med en apparat som inte kan nås levereras till den när den väl blir möjlig att nå.\n\n</string>
|
||||||
<string name="protocol_version">Protokollversion:</string>
|
<string name="protocol_version">Protokollversion:</string>
|
||||||
<string name="protocol_version_newer">Apparaten använder en nyare protokollversion</string>
|
<string name="protocol_version_newer">Apparaten använder en nyare protokollversion</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Apparater</string>
|
<string name="devices">Apparater</string>
|
||||||
<string name="settings_rename">Apparatnamn</string>
|
<string name="settings_rename">Apparatnamn</string>
|
||||||
<string name="settings_dark_mode">Mörkt tema</string>
|
<string name="settings_dark_mode">Mörkt tema</string>
|
||||||
|
<string name="settings_export_logs">Exportera loggar från KDE anslut</string>
|
||||||
|
<string name="settings_export_logs_text">Generera en fil med körinformation som kan hjälpa till att felsöka problem.</string>
|
||||||
<string name="settings_more_settings_title">Fler inställningar</string>
|
<string name="settings_more_settings_title">Fler inställningar</string>
|
||||||
<string name="settings_more_settings_text">Inställningar per apparat hittas i \'Insticksprograminställningar\' på apparaten.</string>
|
<string name="settings_more_settings_text">Inställningar per apparat hittas i \'Insticksprograminställningar\' på apparaten.</string>
|
||||||
<string name="setting_persistent_notification">Visa permanent underrättelse</string>
|
<string name="setting_persistent_notification">Visa permanent underrättelse</string>
|
||||||
|
@ -130,7 +130,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="incoming_files_text">
|
<plurals name="incoming_files_text">
|
||||||
<item quantity="one">Dosya: %1s</item>
|
<item quantity="one">Dosya: %1s</item>
|
||||||
<item quantity="other">(Dosya %2$d %3$d) : %1$s</item>
|
<item quantity="other">(Dosya %2$d/%3$d) : %1$s</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="outgoing_file_title">
|
<plurals name="outgoing_file_title">
|
||||||
<item quantity="one">%1$d dosya %2$s gönderiliyor</item>
|
<item quantity="one">%1$d dosya %2$s gönderiliyor</item>
|
||||||
@ -165,9 +165,11 @@
|
|||||||
<string name="middle_click">Orta Tık Gönder</string>
|
<string name="middle_click">Orta Tık Gönder</string>
|
||||||
<string name="show_keyboard">Klavyeyi Göster</string>
|
<string name="show_keyboard">Klavyeyi Göster</string>
|
||||||
<string name="device_not_paired">Aygıt eşleşmemiş</string>
|
<string name="device_not_paired">Aygıt eşleşmemiş</string>
|
||||||
|
<string name="pairing_duplicate_names">Dikkat: Aynı adlı birden çok aygıt var.</string>
|
||||||
<string name="request_pairing">Eşleşme isteği</string>
|
<string name="request_pairing">Eşleşme isteği</string>
|
||||||
<string name="pairing_accept">Onayla</string>
|
<string name="pairing_accept">Onayla</string>
|
||||||
<string name="pairing_reject">Reddet</string>
|
<string name="pairing_reject">Reddet</string>
|
||||||
|
<string name="pairing_explanation">İki aygıtı eşleştirmek, onlara birbirlerine erişim hakkını verecektir. Yalnızca kendi aygıtlarınızı eşleştirin.</string>
|
||||||
<string name="settings">Ayarlar</string>
|
<string name="settings">Ayarlar</string>
|
||||||
<string name="mpris_play">Oynat</string>
|
<string name="mpris_play">Oynat</string>
|
||||||
<string name="mpris_pause">Duraklat</string>
|
<string name="mpris_pause">Duraklat</string>
|
||||||
@ -191,7 +193,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Ortam denetim bildirimini göster</string>
|
<string name="mpris_notification_settings_title">Ortam denetim bildirimini göster</string>
|
||||||
<string name="mpris_notification_settings_summary">KDE Bağlan’ı açmadan ortam oynatıcılarınızı denetlemenize izin verin</string>
|
<string name="mpris_notification_settings_summary">KDE Bağlan’ı açmadan ortam oynatıcılarınızı denetlemenize izin verin</string>
|
||||||
<string name="share_to">Şuraya Paylaş…</string>
|
<string name="share_to">Şuraya Paylaş…</string>
|
||||||
<string name="unreachable_device">%s (Erişilebilir değil)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Erişilemeyen bir aygıta gönderilen URL’ler, aygıt erişilebilir olduğunda teslim edilir.\n\n</string>
|
<string name="unreachable_device_url_share_text">Erişilemeyen bir aygıta gönderilen URL’ler, aygıt erişilebilir olduğunda teslim edilir.\n\n</string>
|
||||||
<string name="protocol_version">Protokol sürümü:</string>
|
<string name="protocol_version">Protokol sürümü:</string>
|
||||||
<string name="protocol_version_newer">Bu aygıt, daha yeni bir protokol sürümü kullanıyor</string>
|
<string name="protocol_version_newer">Bu aygıt, daha yeni bir protokol sürümü kullanıyor</string>
|
||||||
@ -309,6 +311,8 @@
|
|||||||
<string name="devices">Aygıtlar</string>
|
<string name="devices">Aygıtlar</string>
|
||||||
<string name="settings_rename">Aygıt adı</string>
|
<string name="settings_rename">Aygıt adı</string>
|
||||||
<string name="settings_dark_mode">Karanlık tema</string>
|
<string name="settings_dark_mode">Karanlık tema</string>
|
||||||
|
<string name="settings_export_logs">KDE Bağlan Günlüklerini Dışa Aktar</string>
|
||||||
|
<string name="settings_export_logs_text">Sorun tanılama konusunda yandımcı olabilecek yürütme bilgisini içeren bir dosya üretin.</string>
|
||||||
<string name="settings_more_settings_title">Daha fazla ayar</string>
|
<string name="settings_more_settings_title">Daha fazla ayar</string>
|
||||||
<string name="settings_more_settings_text">Aygıt başına ayarlar, bir aygıt içinden “Eklenti Ayarları” altında bulunabilir.</string>
|
<string name="settings_more_settings_text">Aygıt başına ayarlar, bir aygıt içinden “Eklenti Ayarları” altında bulunabilir.</string>
|
||||||
<string name="setting_persistent_notification">Kalıcı bildirim göster</string>
|
<string name="setting_persistent_notification">Kalıcı bildirim göster</string>
|
||||||
@ -427,5 +431,5 @@
|
|||||||
<string name="ping_failed">Aygıt pinglenemedi</string>
|
<string name="ping_failed">Aygıt pinglenemedi</string>
|
||||||
<string name="ping_in_progress">Pingleniyor…</string>
|
<string name="ping_in_progress">Pingleniyor…</string>
|
||||||
<string name="device_host_invalid">Makine geçersiz. Geçerli bir makine adı kullanın; IPv4 veya IPv6 gibi</string>
|
<string name="device_host_invalid">Makine geçersiz. Geçerli bir makine adı kullanın; IPv4 veya IPv6 gibi</string>
|
||||||
<string name="device_host_duplicate">Listede makine halihazırda var</string>
|
<string name="device_host_duplicate">Makine listede halihazırda var</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -181,9 +181,11 @@
|
|||||||
<string name="middle_click">Надіслати клацання лівою кнопкою</string>
|
<string name="middle_click">Надіслати клацання лівою кнопкою</string>
|
||||||
<string name="show_keyboard">Показати клавіатуру</string>
|
<string name="show_keyboard">Показати клавіатуру</string>
|
||||||
<string name="device_not_paired">Пристрій не пов’язано</string>
|
<string name="device_not_paired">Пристрій не пов’язано</string>
|
||||||
|
<string name="pairing_duplicate_names">Попередження: маємо декілька пристроїв із однією назвою.</string>
|
||||||
<string name="request_pairing">Надіслати запит щодо пов’язування</string>
|
<string name="request_pairing">Надіслати запит щодо пов’язування</string>
|
||||||
<string name="pairing_accept">Прийняти</string>
|
<string name="pairing_accept">Прийняти</string>
|
||||||
<string name="pairing_reject">Відмовити</string>
|
<string name="pairing_reject">Відмовити</string>
|
||||||
|
<string name="pairing_explanation">Пов\'язування двох пристроїв надасть їм взаємний доступ. Пов\'язуйте між собою лише ваші власні пристрої.</string>
|
||||||
<string name="settings">Параметри</string>
|
<string name="settings">Параметри</string>
|
||||||
<string name="mpris_play">Пуск</string>
|
<string name="mpris_play">Пуск</string>
|
||||||
<string name="mpris_pause">Пауза</string>
|
<string name="mpris_pause">Пауза</string>
|
||||||
@ -207,7 +209,7 @@
|
|||||||
<string name="mpris_notification_settings_title">Показувати сповіщення щодо керування відтворенням</string>
|
<string name="mpris_notification_settings_title">Показувати сповіщення щодо керування відтворенням</string>
|
||||||
<string name="mpris_notification_settings_summary">Уможливлює керування відтворенням мультимедійних даних без відкриття KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Уможливлює керування відтворенням мультимедійних даних без відкриття KDE Connect</string>
|
||||||
<string name="share_to">Оприлюднити на…</string>
|
<string name="share_to">Оприлюднити на…</string>
|
||||||
<string name="unreachable_device">%s (недоступний)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">Адреси, які оприлюднено на недоступному пристрої, буде надіслано, щойно пристрій стане доступним.\n\n</string>
|
<string name="unreachable_device_url_share_text">Адреси, які оприлюднено на недоступному пристрої, буде надіслано, щойно пристрій стане доступним.\n\n</string>
|
||||||
<string name="protocol_version">Версія протоколу:</string>
|
<string name="protocol_version">Версія протоколу:</string>
|
||||||
<string name="protocol_version_newer">На цьому пристрої використовується новіша версія протоколу</string>
|
<string name="protocol_version_newer">На цьому пристрої використовується новіша версія протоколу</string>
|
||||||
@ -325,6 +327,8 @@
|
|||||||
<string name="devices">Пристрої</string>
|
<string name="devices">Пристрої</string>
|
||||||
<string name="settings_rename">Назва пристрою</string>
|
<string name="settings_rename">Назва пристрою</string>
|
||||||
<string name="settings_dark_mode">Темна тема</string>
|
<string name="settings_dark_mode">Темна тема</string>
|
||||||
|
<string name="settings_export_logs">Експортувати журнал KDE Connect</string>
|
||||||
|
<string name="settings_export_logs_text">Створити файл з даними щодо виконання, які можуть допомогти у діагностиці вад.</string>
|
||||||
<string name="settings_more_settings_title">Додаткові параметри</string>
|
<string name="settings_more_settings_title">Додаткові параметри</string>
|
||||||
<string name="settings_more_settings_text">Окремі параметри пристроїв наведено на сторінці «Параметри додатків» сторінки пристрою.</string>
|
<string name="settings_more_settings_text">Окремі параметри пристроїв наведено на сторінці «Параметри додатків» сторінки пристрою.</string>
|
||||||
<string name="setting_persistent_notification">Показувати постійне сповіщення</string>
|
<string name="setting_persistent_notification">Показувати постійне сповіщення</string>
|
||||||
|
@ -157,9 +157,11 @@
|
|||||||
<string name="middle_click">发送中键点击</string>
|
<string name="middle_click">发送中键点击</string>
|
||||||
<string name="show_keyboard">显示键盘</string>
|
<string name="show_keyboard">显示键盘</string>
|
||||||
<string name="device_not_paired">设备未配对</string>
|
<string name="device_not_paired">设备未配对</string>
|
||||||
|
<string name="pairing_duplicate_names">注意:存在多个同名设备。</string>
|
||||||
<string name="request_pairing">请求配对</string>
|
<string name="request_pairing">请求配对</string>
|
||||||
<string name="pairing_accept">接受</string>
|
<string name="pairing_accept">接受</string>
|
||||||
<string name="pairing_reject">拒绝</string>
|
<string name="pairing_reject">拒绝</string>
|
||||||
|
<string name="pairing_explanation">两个设备在配对后即可相互访问。请只配对您自己的设备。</string>
|
||||||
<string name="settings">设置</string>
|
<string name="settings">设置</string>
|
||||||
<string name="mpris_play">播放</string>
|
<string name="mpris_play">播放</string>
|
||||||
<string name="mpris_pause">暂停</string>
|
<string name="mpris_pause">暂停</string>
|
||||||
@ -183,7 +185,7 @@
|
|||||||
<string name="mpris_notification_settings_title">显示媒体控制通知</string>
|
<string name="mpris_notification_settings_title">显示媒体控制通知</string>
|
||||||
<string name="mpris_notification_settings_summary">不打开 KDE Connect 也能在常驻通知中控制媒体播放器</string>
|
<string name="mpris_notification_settings_summary">不打开 KDE Connect 也能在常驻通知中控制媒体播放器</string>
|
||||||
<string name="share_to">分享到…</string>
|
<string name="share_to">分享到…</string>
|
||||||
<string name="unreachable_device">%s (无法访问)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">URL 被分享到了不可访问的设备。它将在设备能够访问时自动传输到该设备。\n</string>
|
<string name="unreachable_device_url_share_text">URL 被分享到了不可访问的设备。它将在设备能够访问时自动传输到该设备。\n</string>
|
||||||
<string name="protocol_version">协议版本:</string>
|
<string name="protocol_version">协议版本:</string>
|
||||||
<string name="protocol_version_newer">此设备使用较新版本的协议</string>
|
<string name="protocol_version_newer">此设备使用较新版本的协议</string>
|
||||||
@ -301,6 +303,8 @@
|
|||||||
<string name="devices">设备</string>
|
<string name="devices">设备</string>
|
||||||
<string name="settings_rename">设备名</string>
|
<string name="settings_rename">设备名</string>
|
||||||
<string name="settings_dark_mode">深色主题</string>
|
<string name="settings_dark_mode">深色主题</string>
|
||||||
|
<string name="settings_export_logs">导出 KDE Connect 日志</string>
|
||||||
|
<string name="settings_export_logs_text">生成一个包含程序执行信息的文件,有助于排查故障。</string>
|
||||||
<string name="settings_more_settings_title">更多设置</string>
|
<string name="settings_more_settings_title">更多设置</string>
|
||||||
<string name="settings_more_settings_text">每个设备的独立设置可以在设备页内的“插件设置”下找到。</string>
|
<string name="settings_more_settings_text">每个设备的独立设置可以在设备页内的“插件设置”下找到。</string>
|
||||||
<string name="setting_persistent_notification">启用常驻通知栏</string>
|
<string name="setting_persistent_notification">启用常驻通知栏</string>
|
||||||
|
@ -157,9 +157,11 @@
|
|||||||
<string name="middle_click">傳送中鍵點擊</string>
|
<string name="middle_click">傳送中鍵點擊</string>
|
||||||
<string name="show_keyboard">顯示鍵盤</string>
|
<string name="show_keyboard">顯示鍵盤</string>
|
||||||
<string name="device_not_paired">裝置未配對</string>
|
<string name="device_not_paired">裝置未配對</string>
|
||||||
|
<string name="pairing_duplicate_names">請小心:有多台裝置有相同的名稱。</string>
|
||||||
<string name="request_pairing">請求配對</string>
|
<string name="request_pairing">請求配對</string>
|
||||||
<string name="pairing_accept">接受</string>
|
<string name="pairing_accept">接受</string>
|
||||||
<string name="pairing_reject">拒絕</string>
|
<string name="pairing_reject">拒絕</string>
|
||||||
|
<string name="pairing_explanation">配對兩台裝置會讓它們能夠互相存取。請只配對您自己的裝置。</string>
|
||||||
<string name="settings">設定</string>
|
<string name="settings">設定</string>
|
||||||
<string name="mpris_play">播放</string>
|
<string name="mpris_play">播放</string>
|
||||||
<string name="mpris_pause">暫停</string>
|
<string name="mpris_pause">暫停</string>
|
||||||
@ -183,7 +185,7 @@
|
|||||||
<string name="mpris_notification_settings_title">顯示媒體控制通知</string>
|
<string name="mpris_notification_settings_title">顯示媒體控制通知</string>
|
||||||
<string name="mpris_notification_settings_summary">無需開啟 KDE Connect 即可控制您的媒體播放器</string>
|
<string name="mpris_notification_settings_summary">無需開啟 KDE Connect 即可控制您的媒體播放器</string>
|
||||||
<string name="share_to">分享給…</string>
|
<string name="share_to">分享給…</string>
|
||||||
<string name="unreachable_device">%s(無法存取)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">若分享網址 (URL) 到無法存取的裝置,將在該裝置變得可存取後再傳送過去。\n\n</string>
|
<string name="unreachable_device_url_share_text">若分享網址 (URL) 到無法存取的裝置,將在該裝置變得可存取後再傳送過去。\n\n</string>
|
||||||
<string name="protocol_version">協定版本:</string>
|
<string name="protocol_version">協定版本:</string>
|
||||||
<string name="protocol_version_newer">此裝置使用較新的通訊協定版本</string>
|
<string name="protocol_version_newer">此裝置使用較新的通訊協定版本</string>
|
||||||
@ -301,6 +303,8 @@
|
|||||||
<string name="devices">裝置</string>
|
<string name="devices">裝置</string>
|
||||||
<string name="settings_rename">裝置名稱</string>
|
<string name="settings_rename">裝置名稱</string>
|
||||||
<string name="settings_dark_mode">暗色主題</string>
|
<string name="settings_dark_mode">暗色主題</string>
|
||||||
|
<string name="settings_export_logs">匯出 KDE Connect 紀錄</string>
|
||||||
|
<string name="settings_export_logs_text">產生包含執行資訊的檔案來幫助發現問題。</string>
|
||||||
<string name="settings_more_settings_title">更多設定</string>
|
<string name="settings_more_settings_title">更多設定</string>
|
||||||
<string name="settings_more_settings_text">各裝置設定可在裝置內的「外掛程式設定」底下找到。</string>
|
<string name="settings_more_settings_text">各裝置設定可在裝置內的「外掛程式設定」底下找到。</string>
|
||||||
<string name="setting_persistent_notification">顯示一致設定</string>
|
<string name="setting_persistent_notification">顯示一致設定</string>
|
||||||
|
@ -227,9 +227,11 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
<string name="middle_click">Send Middle Click</string>
|
<string name="middle_click">Send Middle Click</string>
|
||||||
<string name="show_keyboard">Show Keyboard</string>
|
<string name="show_keyboard">Show Keyboard</string>
|
||||||
<string name="device_not_paired">Device not paired</string>
|
<string name="device_not_paired">Device not paired</string>
|
||||||
|
<string name="pairing_duplicate_names">Caution: There are multiple devices with the same name.</string>
|
||||||
<string name="request_pairing">Request pairing</string>
|
<string name="request_pairing">Request pairing</string>
|
||||||
<string name="pairing_accept">Accept</string>
|
<string name="pairing_accept">Accept</string>
|
||||||
<string name="pairing_reject">Reject</string>
|
<string name="pairing_reject">Reject</string>
|
||||||
|
<string name="pairing_explanation">Pairing two devices will give them access to each other. Only pair together your own devices.</string>
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
<string name="mpris_play">Play</string>
|
<string name="mpris_play">Play</string>
|
||||||
<string name="mpris_pause">Pause</string>
|
<string name="mpris_pause">Pause</string>
|
||||||
@ -263,7 +265,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
<string name="mpris_notification_settings_summary">Allow controlling your media players without opening KDE Connect</string>
|
<string name="mpris_notification_settings_summary">Allow controlling your media players without opening KDE Connect</string>
|
||||||
<string name="mpris_notification_key" translatable="false">mpris_notification_enabled</string>
|
<string name="mpris_notification_key" translatable="false">mpris_notification_enabled</string>
|
||||||
<string name="share_to">Share to…</string>
|
<string name="share_to">Share to…</string>
|
||||||
<string name="unreachable_device">%s (Unreachable)</string>
|
<string name="unreachable_device_dynamic_shortcut">%s (✕)</string>
|
||||||
<string name="unreachable_device_url_share_text">URLs shared to an unreachable device will be delivered to it once it becomes reachable.\n\n</string>
|
<string name="unreachable_device_url_share_text">URLs shared to an unreachable device will be delivered to it once it becomes reachable.\n\n</string>
|
||||||
<string name="protocol_version">Protocol version:</string>
|
<string name="protocol_version">Protocol version:</string>
|
||||||
<string name="protocol_version_newer">This device uses a newer protocol version</string>
|
<string name="protocol_version_newer">This device uses a newer protocol version</string>
|
||||||
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- NoActionBar because we use a Toolbar widget as ActionBar -->
|
<!-- NoActionBar because we use a Toolbar widget as ActionBar -->
|
||||||
<style name="KdeConnectThemeBase" parent="Theme.Material3.DayNight.NoActionBar">
|
<style name="KdeConnectThemeBase" parent="Theme.Material3.DynamicColors.DayNight.NoActionBar">
|
||||||
<!-- The main color attributes -->
|
<!-- The main color attributes -->
|
||||||
<!-- Drawable definitions and overrides -->
|
<!-- Drawable definitions and overrides -->
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
<locale android:name="fi"/>
|
<locale android:name="fi"/>
|
||||||
<locale android:name="fr"/>
|
<locale android:name="fr"/>
|
||||||
<locale android:name="gl"/>
|
<locale android:name="gl"/>
|
||||||
<locale android:name="he"/>
|
|
||||||
<locale android:name="hu"/>
|
<locale android:name="hu"/>
|
||||||
<locale android:name="ia"/>
|
<locale android:name="ia"/>
|
||||||
<locale android:name="id"/>
|
<locale android:name="id"/>
|
||||||
|
@ -8,7 +8,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
|||||||
|
|
||||||
<appwidget-provider
|
<appwidget-provider
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:minWidth="180dp"
|
android:minWidth="120dp"
|
||||||
android:minHeight="80dp"
|
android:minHeight="80dp"
|
||||||
android:initialLayout="@layout/widget_remotecommandplugin"
|
android:initialLayout="@layout/widget_remotecommandplugin"
|
||||||
android:resizeMode="horizontal|vertical"
|
android:resizeMode="horizontal|vertical"
|
||||||
|
@ -16,6 +16,7 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.net.Network
|
import android.net.Network
|
||||||
|
import android.os.Parcelable
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -29,6 +30,8 @@ import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper
|
|||||||
import org.kde.kdeconnect.Helpers.ThreadHelper.execute
|
import org.kde.kdeconnect.Helpers.ThreadHelper.execute
|
||||||
import org.kde.kdeconnect.NetworkPacket
|
import org.kde.kdeconnect.NetworkPacket
|
||||||
import org.kde.kdeconnect.UserInterface.SettingsFragment
|
import org.kde.kdeconnect.UserInterface.SettingsFragment
|
||||||
|
import org.kde.kdeconnect.extensions.getParcelableArrayCompat
|
||||||
|
import org.kde.kdeconnect.extensions.getParcelableCompat
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
@ -74,7 +77,7 @@ class BluetoothLinkProvider(private val context: Context) : BaseLinkProvider() {
|
|||||||
if (!preferences.getBoolean(SettingsFragment.KEY_BLUETOOTH_ENABLED, false)) {
|
if (!preferences.getBoolean(SettingsFragment.KEY_BLUETOOTH_ENABLED, false)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (bluetoothAdapter == null || bluetoothAdapter.isEnabled == false) {
|
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Log.i("BluetoothLinkProvider", "onStart called")
|
Log.i("BluetoothLinkProvider", "onStart called")
|
||||||
@ -297,8 +300,8 @@ class BluetoothLinkProvider(private val context: Context) : BaseLinkProvider() {
|
|||||||
val action = intent.action
|
val action = intent.action
|
||||||
if (BluetoothDevice.ACTION_UUID == action) {
|
if (BluetoothDevice.ACTION_UUID == action) {
|
||||||
Log.i("BluetoothLinkProvider", "Action matches")
|
Log.i("BluetoothLinkProvider", "Action matches")
|
||||||
val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
|
val device = intent.getParcelableCompat<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
|
||||||
val activeUuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID)
|
val activeUuids = intent.getParcelableArrayCompat<Parcelable>(BluetoothDevice.EXTRA_UUID)
|
||||||
if (sockets.containsKey(device)) {
|
if (sockets.containsKey(device)) {
|
||||||
Log.i("BluetoothLinkProvider", "sockets contains device")
|
Log.i("BluetoothLinkProvider", "sockets contains device")
|
||||||
return
|
return
|
||||||
|
@ -10,8 +10,8 @@ import android.content.Context;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.WorkerThread;
|
import androidx.annotation.WorkerThread;
|
||||||
@ -27,7 +27,6 @@ import org.kde.kdeconnect.Helpers.ThreadHelper;
|
|||||||
import org.kde.kdeconnect.Helpers.TrustedNetworkHelper;
|
import org.kde.kdeconnect.Helpers.TrustedNetworkHelper;
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
import org.kde.kdeconnect.UserInterface.CustomDevicesActivity;
|
import org.kde.kdeconnect.UserInterface.CustomDevicesActivity;
|
||||||
import org.kde.kdeconnect.UserInterface.SettingsFragment;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -68,13 +67,15 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
final static int MAX_IDENTITY_PACKET_SIZE = 1024 * 512;
|
final static int MAX_IDENTITY_PACKET_SIZE = 1024 * 512;
|
||||||
final static int MAX_UDP_PACKET_SIZE = 1024 * 512;
|
final static int MAX_UDP_PACKET_SIZE = 1024 * 512;
|
||||||
|
|
||||||
final static long MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE = 500L;
|
final static long MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE = 1000L;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
final HashMap<String, LanLink> visibleDevices = new HashMap<>(); // Links by device id
|
final HashMap<String, LanLink> visibleDevices = new HashMap<>(); // Links by device id
|
||||||
|
|
||||||
final ConcurrentHashMap<String, Long> lastConnectionTime = new ConcurrentHashMap<>();
|
final static int MAX_RATE_LIMIT_ENTRIES = 255;
|
||||||
|
final ConcurrentHashMap<String, Long> lastConnectionTimeByDeviceId = new ConcurrentHashMap<>();
|
||||||
|
final ConcurrentHashMap<InetAddress, Long> lastConnectionTimeByIp = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private ServerSocket tcpServer;
|
private ServerSocket tcpServer;
|
||||||
private DatagramSocket udpServer;
|
private DatagramSocket udpServer;
|
||||||
@ -92,29 +93,70 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
super.onConnectionLost(link);
|
super.onConnectionLost(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pair<NetworkPacket, Boolean> unserializeReceivedIdentityPacket(String message) {
|
||||||
|
NetworkPacket identityPacket;
|
||||||
|
try {
|
||||||
|
identityPacket = NetworkPacket.unserialize(message);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.w("KDE/LanLinkProvider", "Invalid identity packet received: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DeviceInfo.isValidIdentityPacket(identityPacket)) {
|
||||||
|
Log.w("KDE/LanLinkProvider", "Invalid identity packet received.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String deviceId = identityPacket.getString("deviceId");
|
||||||
|
String myId = DeviceHelper.getDeviceId(context);
|
||||||
|
if (deviceId.equals(myId)) {
|
||||||
|
//Ignore my own broadcast
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rateLimitByDeviceId(deviceId)) {
|
||||||
|
Log.i("LanLinkProvider", "Discarding second packet from the same device " + deviceId + " received too quickly");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean deviceTrusted = isDeviceTrusted(deviceId);
|
||||||
|
if (!deviceTrusted && !TrustedNetworkHelper.isTrustedNetwork(context)) {
|
||||||
|
Log.i("KDE/LanLinkProvider", "Ignoring identity packet because the device is not trusted and I'm not on a trusted network.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Pair<>(identityPacket, deviceTrusted);
|
||||||
|
}
|
||||||
|
|
||||||
//They received my UDP broadcast and are connecting to me. The first thing they send should be their identity packet.
|
//They received my UDP broadcast and are connecting to me. The first thing they send should be their identity packet.
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
private void tcpPacketReceived(Socket socket) throws IOException {
|
private void tcpPacketReceived(Socket socket) throws IOException {
|
||||||
|
|
||||||
NetworkPacket networkPacket;
|
InetAddress address = socket.getInetAddress();
|
||||||
|
if (rateLimitByIp(address)) {
|
||||||
|
Log.i("LanLinkProvider", "Discarding second TCP packet from the same ip " + address + " received too quickly");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String message;
|
||||||
try {
|
try {
|
||||||
String message = readSingleLine(socket);
|
message = readSingleLine(socket);
|
||||||
networkPacket = NetworkPacket.unserialize(message);
|
//Log.e("TcpListener", "Received TCP packet: " + identityPacket.serialize());
|
||||||
//Log.e("TcpListener", "Received TCP packet: " + networkPacket.serialize());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("KDE/LanLinkProvider", "Exception while receiving TCP packet", e);
|
Log.e("KDE/LanLinkProvider", "Exception while receiving TCP packet", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i("KDE/LanLinkProvider", "identity packet received from a TCP connection from " + networkPacket.getString("deviceName"));
|
final Pair<NetworkPacket, Boolean> pair = unserializeReceivedIdentityPacket(message);
|
||||||
|
if (pair == null) {
|
||||||
boolean deviceTrusted = isDeviceTrusted(networkPacket.getString("deviceId"));
|
|
||||||
if (!deviceTrusted && !TrustedNetworkHelper.isTrustedNetwork(context)) {
|
|
||||||
Log.i("KDE/LanLinkProvider", "Ignoring identity packet because the device is not trusted and I'm not on a trusted network.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final NetworkPacket identityPacket = pair.first;
|
||||||
|
final boolean deviceTrusted = pair.second;
|
||||||
|
|
||||||
identityPacketReceived(networkPacket, socket, LanLink.ConnectionStarted.Locally, deviceTrusted);
|
Log.i("KDE/LanLinkProvider", "identity packet received from a TCP connection from " + identityPacket.getString("deviceName"));
|
||||||
|
|
||||||
|
identityPacketReceived(identityPacket, socket, LanLink.ConnectionStarted.Locally, deviceTrusted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,40 +178,53 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
throw new IOException("Couldn't read a line from the socket");
|
throw new IOException("Couldn't read a line from the socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean rateLimitByIp(InetAddress address) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
Long last = lastConnectionTimeByIp.get(address);
|
||||||
|
if (last != null && (last + MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE > now)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
lastConnectionTimeByIp.put(address, now);
|
||||||
|
if (lastConnectionTimeByIp.size() > MAX_RATE_LIMIT_ENTRIES) {
|
||||||
|
lastConnectionTimeByIp.entrySet().removeIf(e -> e.getValue() + MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE < now);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean rateLimitByDeviceId(String deviceId) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
Long last = lastConnectionTimeByDeviceId.get(deviceId);
|
||||||
|
if (last != null && (last + MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE > now)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
lastConnectionTimeByDeviceId.put(deviceId, now);
|
||||||
|
if (lastConnectionTimeByDeviceId.size() > MAX_RATE_LIMIT_ENTRIES) {
|
||||||
|
lastConnectionTimeByDeviceId.entrySet().removeIf(e -> e.getValue() + MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE < now);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//I've received their broadcast and should connect to their TCP socket and send my identity.
|
//I've received their broadcast and should connect to their TCP socket and send my identity.
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
private void udpPacketReceived(DatagramPacket packet) throws JSONException, IOException {
|
private void udpPacketReceived(DatagramPacket packet) throws JSONException, IOException {
|
||||||
|
|
||||||
final InetAddress address = packet.getAddress();
|
final InetAddress address = packet.getAddress();
|
||||||
|
|
||||||
|
if (rateLimitByIp(address)) {
|
||||||
|
Log.i("LanLinkProvider", "Discarding second UDP packet from the same ip " + address + " received too quickly");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String message = new String(packet.getData(), Charsets.UTF_8);
|
String message = new String(packet.getData(), Charsets.UTF_8);
|
||||||
final NetworkPacket identityPacket;
|
|
||||||
try {
|
|
||||||
identityPacket = NetworkPacket.unserialize(message);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.w("KDE/LanLinkProvider", "Invalid identity packet received: " + e.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DeviceInfo.isValidIdentityPacket(identityPacket)) {
|
final Pair<NetworkPacket, Boolean> pair = unserializeReceivedIdentityPacket(message);
|
||||||
Log.w("KDE/LanLinkProvider", "Invalid identity packet received.");
|
if (pair == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final NetworkPacket identityPacket = pair.first;
|
||||||
|
final boolean deviceTrusted = pair.second;
|
||||||
|
|
||||||
final String deviceId = identityPacket.getString("deviceId");
|
Log.i("KDE/LanLinkProvider", "Broadcast identity packet received from " + identityPacket.getString("deviceName"));
|
||||||
String myId = DeviceHelper.getDeviceId(context);
|
|
||||||
if (deviceId.equals(myId)) {
|
|
||||||
//Ignore my own broadcast
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
Long last = lastConnectionTime.get(deviceId);
|
|
||||||
if (last != null && (last + MILLIS_DELAY_BETWEEN_CONNECTIONS_TO_SAME_DEVICE > now)) {
|
|
||||||
Log.i("LanLinkProvider", "Discarding second UDP packet from the same device " + deviceId + " received too quickly");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastConnectionTime.put(deviceId, now);
|
|
||||||
|
|
||||||
int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT);
|
int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT);
|
||||||
if (tcpPort < MIN_PORT || tcpPort > MAX_PORT) {
|
if (tcpPort < MIN_PORT || tcpPort > MAX_PORT) {
|
||||||
@ -177,14 +232,6 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i("KDE/LanLinkProvider", "Broadcast identity packet received from " + identityPacket.getString("deviceName"));
|
|
||||||
|
|
||||||
boolean deviceTrusted = isDeviceTrusted(identityPacket.getString("deviceId"));
|
|
||||||
if (!deviceTrusted && !TrustedNetworkHelper.isTrustedNetwork(context)) {
|
|
||||||
Log.i("KDE/LanLinkProvider", "Ignoring identity packet because the device is not trusted and I'm not on a trusted network.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SocketFactory socketFactory = SocketFactory.getDefault();
|
SocketFactory socketFactory = SocketFactory.getDefault();
|
||||||
Socket socket = socketFactory.createSocket(address, tcpPort);
|
Socket socket = socketFactory.createSocket(address, tcpPort);
|
||||||
configureSocket(socket);
|
configureSocket(socket);
|
||||||
@ -224,18 +271,7 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
*/
|
*/
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
private void identityPacketReceived(final NetworkPacket identityPacket, final Socket socket, final LanLink.ConnectionStarted connectionStarted, final boolean deviceTrusted) throws IOException {
|
private void identityPacketReceived(final NetworkPacket identityPacket, final Socket socket, final LanLink.ConnectionStarted connectionStarted, final boolean deviceTrusted) throws IOException {
|
||||||
|
|
||||||
if (!DeviceInfo.isValidIdentityPacket(identityPacket)) {
|
|
||||||
Log.w("KDE/LanLinkProvider", "Invalid identity packet received.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String myId = DeviceHelper.getDeviceId(context);
|
|
||||||
final String deviceId = identityPacket.getString("deviceId");
|
final String deviceId = identityPacket.getString("deviceId");
|
||||||
if (deviceId.equals(myId)) {
|
|
||||||
Log.e("KDE/LanLinkProvider", "Somehow I'm connected to myself, ignoring. This should not happen.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int protocolVersion = identityPacket.getInt("protocolVersion");
|
int protocolVersion = identityPacket.getInt("protocolVersion");
|
||||||
if (deviceTrusted && isProtocolDowngrade(deviceId, protocolVersion)) {
|
if (deviceTrusted && isProtocolDowngrade(deviceId, protocolVersion)) {
|
||||||
@ -420,12 +456,6 @@ public class LanLinkProvider extends BaseLinkProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void broadcastUdpIdentityPacket(@Nullable Network network) {
|
private void broadcastUdpIdentityPacket(@Nullable Network network) {
|
||||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
if (!preferences.getBoolean(SettingsFragment.KEY_UDP_BROADCAST_ENABLED, true)) {
|
|
||||||
Log.i("LanLinkProvider", "UDP broadcast is disabled in settings. Skipping.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadHelper.execute(() -> {
|
ThreadHelper.execute(() -> {
|
||||||
List<DeviceHost> hostList = CustomDevicesActivity
|
List<DeviceHost> hostList = CustomDevicesActivity
|
||||||
.getCustomDeviceList(context);
|
.getCustomDeviceList(context);
|
||||||
|
@ -234,7 +234,12 @@ class BackgroundService : Service() {
|
|||||||
Log.d(LOG_TAG, "onStartCommand")
|
Log.d(LOG_TAG, "onStartCommand")
|
||||||
if (NotificationHelper.isPersistentNotificationEnabled(this)) {
|
if (NotificationHelper.isPersistentNotificationEnabled(this)) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
try {
|
||||||
startForeground(FOREGROUND_NOTIFICATION_ID, createForegroundNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE)
|
startForeground(FOREGROUND_NOTIFICATION_ID, createForegroundNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE)
|
||||||
|
} catch (e: IllegalStateException) { // To catch ForegroundServiceStartNotAllowedException
|
||||||
|
Log.w("BackgroundService", "Couldn't startForeground", e);
|
||||||
|
return START_STICKY
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
startForeground(FOREGROUND_NOTIFICATION_ID, createForegroundNotification())
|
startForeground(FOREGROUND_NOTIFICATION_ID, createForegroundNotification())
|
||||||
|
@ -43,7 +43,7 @@ class DeviceHost private constructor(private val host: String) {
|
|||||||
companion object {
|
companion object {
|
||||||
/** Ping timeout */
|
/** Ping timeout */
|
||||||
private const val PING_TIMEOUT = 3_000
|
private const val PING_TIMEOUT = 3_000
|
||||||
private val hostnameValidityPattern = Regex("^[0-9A-Za-z._-]+$")
|
private val hostnameValidityPattern = Regex("^[0-9A-Za-z.:_-]+$")
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isValidDeviceHost(host: String): Boolean {
|
fun isValidDeviceHost(host: String): Boolean {
|
||||||
|
@ -94,7 +94,7 @@ class DeviceInfo(
|
|||||||
with(identityPacket) {
|
with(identityPacket) {
|
||||||
DeviceInfo(
|
DeviceInfo(
|
||||||
id = getString("deviceId"), // Redundant: We could read this from the certificate instead
|
id = getString("deviceId"), // Redundant: We could read this from the certificate instead
|
||||||
name = DeviceHelper.filterName(getString("deviceName", "unknown")),
|
name = DeviceHelper.filterInvalidCharactersFromDeviceNameAndLimitLength(getString("deviceName", "unknown")),
|
||||||
type = DeviceType.fromString(getString("deviceType", "desktop")),
|
type = DeviceType.fromString(getString("deviceType", "desktop")),
|
||||||
certificate = certificate,
|
certificate = certificate,
|
||||||
protocolVersion = getInt("protocolVersion"),
|
protocolVersion = getInt("protocolVersion"),
|
||||||
@ -106,7 +106,7 @@ class DeviceInfo(
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isValidIdentityPacket(identityPacket: NetworkPacket): Boolean = with(identityPacket) {
|
fun isValidIdentityPacket(identityPacket: NetworkPacket): Boolean = with(identityPacket) {
|
||||||
type == NetworkPacket.PACKET_TYPE_IDENTITY &&
|
type == NetworkPacket.PACKET_TYPE_IDENTITY &&
|
||||||
DeviceHelper.filterName(getString("deviceName", "")).isNotBlank() &&
|
DeviceHelper.filterInvalidCharactersFromDeviceNameAndLimitLength(getString("deviceName", "")).isNotBlank() &&
|
||||||
isValidDeviceId(getString("deviceId", ""))
|
isValidDeviceId(getString("deviceId", ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ object DeviceHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setDeviceName(context: Context, name: String) {
|
fun setDeviceName(context: Context, name: String) {
|
||||||
val filteredName = filterName(name)
|
val filteredName = filterInvalidCharactersFromDeviceNameAndLimitLength(name)
|
||||||
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
preferences.edit { putString(KEY_DEVICE_NAME_PREFERENCE, filteredName) }
|
preferences.edit { putString(KEY_DEVICE_NAME_PREFERENCE, filteredName) }
|
||||||
}
|
}
|
||||||
@ -157,5 +157,9 @@ object DeviceHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun filterName(input: String): String = input.replace(NAME_INVALID_CHARACTERS_REGEX, "").take(MAX_DEVICE_NAME_LENGTH)
|
fun filterInvalidCharactersFromDeviceNameAndLimitLength(input: String): String = filterInvalidCharactersFromDeviceName(input).trim().take(MAX_DEVICE_NAME_LENGTH)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun filterInvalidCharactersFromDeviceName(input: String): String = input.replace(NAME_INVALID_CHARACTERS_REGEX, "")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,13 @@ public class ClipboardListener {
|
|||||||
try {
|
try {
|
||||||
String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US).format(new Date());
|
String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US).format(new Date());
|
||||||
// Listen only ClipboardService errors after now
|
// Listen only ClipboardService errors after now
|
||||||
Process process = Runtime.getRuntime().exec(new String[]{"logcat", "-T", timeStamp, "ClipboardService:E", "*:S"});
|
String logcatFilter;
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||||
|
logcatFilter = "E ClipboardService";
|
||||||
|
} else {
|
||||||
|
logcatFilter = "ClipboardService:E";
|
||||||
|
}
|
||||||
|
Process process = Runtime.getRuntime().exec(new String[]{"logcat", "-T", timeStamp, logcatFilter, "*:S"});
|
||||||
BufferedReader bufferedReader = new BufferedReader(
|
BufferedReader bufferedReader = new BufferedReader(
|
||||||
new InputStreamReader(
|
new InputStreamReader(
|
||||||
process.getInputStream()
|
process.getInputStream()
|
||||||
|
@ -15,6 +15,7 @@ import android.os.Bundle;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.content.IntentCompat;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ public class FindMyPhoneSettingsFragment extends PluginSettingsFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
if (requestCode == REQUEST_CODE_SELECT_RINGTONE && resultCode == Activity.RESULT_OK) {
|
if (requestCode == REQUEST_CODE_SELECT_RINGTONE && resultCode == Activity.RESULT_OK) {
|
||||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
Uri uri = IntentCompat.getParcelableExtra(data, RingtoneManager.EXTRA_RINGTONE_PICKED_URI, Uri.class);
|
||||||
|
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
sharedPreferences.edit()
|
sharedPreferences.edit()
|
||||||
|
@ -21,7 +21,7 @@ import org.kde.kdeconnect.Helpers.SafeTextChecker;
|
|||||||
import org.kde.kdeconnect.Helpers.WindowHelper;
|
import org.kde.kdeconnect.Helpers.WindowHelper;
|
||||||
import org.kde.kdeconnect.KdeConnect;
|
import org.kde.kdeconnect.KdeConnect;
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
import org.kde.kdeconnect.NetworkPacket;
|
||||||
import org.kde.kdeconnect.UserInterface.List.EntryItemWithIcon;
|
import org.kde.kdeconnect.UserInterface.List.DeviceItem;
|
||||||
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
|
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
|
||||||
import org.kde.kdeconnect.UserInterface.List.SectionItem;
|
import org.kde.kdeconnect.UserInterface.List.SectionItem;
|
||||||
import org.kde.kdeconnect.base.BaseActivity;
|
import org.kde.kdeconnect.base.BaseActivity;
|
||||||
@ -36,6 +36,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import kotlin.Lazy;
|
import kotlin.Lazy;
|
||||||
import kotlin.LazyKt;
|
import kotlin.LazyKt;
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
public class SendKeystrokesToHostActivity extends BaseActivity<ActivitySendkeystrokesBinding> {
|
public class SendKeystrokesToHostActivity extends BaseActivity<ActivitySendkeystrokesBinding> {
|
||||||
|
|
||||||
@ -166,17 +167,16 @@ public class SendKeystrokesToHostActivity extends BaseActivity<ActivitySendkeyst
|
|||||||
for (Device d : devices) {
|
for (Device d : devices) {
|
||||||
if (d.isReachable() && d.isPaired()) {
|
if (d.isReachable() && d.isPaired()) {
|
||||||
devicesList.add(d);
|
devicesList.add(d);
|
||||||
items.add(new EntryItemWithIcon(d.getName(), d.getIcon()));
|
items.add(new DeviceItem(d, this::deviceClicked));
|
||||||
section.isEmpty = false;
|
section.isEmpty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getBinding().devicesList.setAdapter(new ListAdapter(SendKeystrokesToHostActivity.this, items));
|
getBinding().devicesList.setAdapter(new ListAdapter(SendKeystrokesToHostActivity.this, items));
|
||||||
getBinding().devicesList.setOnItemClickListener((adapterView, view, i, l) -> {
|
|
||||||
Device device = devicesList.get(i - 1); // NOTE: -1 because of the title!
|
// Configure focus order for Accessibility, for touchpads, and for TV remotes
|
||||||
sendKeys(device);
|
// (allow focus of items in the device list)
|
||||||
this.finish(); // close the activity
|
getBinding().devicesList.setItemsCanFocus(true);
|
||||||
});
|
|
||||||
|
|
||||||
// only one device is connected and we trust the text to send -> send it and close the activity.
|
// only one device is connected and we trust the text to send -> send it and close the activity.
|
||||||
// Usually we already check it in `onStart` - but if the BackgroundService was not started/connected to the host
|
// Usually we already check it in `onStart` - but if the BackgroundService was not started/connected to the host
|
||||||
@ -185,8 +185,15 @@ public class SendKeystrokesToHostActivity extends BaseActivity<ActivitySendkeyst
|
|||||||
if (devicesList.size() == 1 && contentIsOkay) {
|
if (devicesList.size() == 1 && contentIsOkay) {
|
||||||
Device device = devicesList.get(0);
|
Device device = devicesList.get(0);
|
||||||
sendKeys(device);
|
sendKeys(device);
|
||||||
this.finish(); // close the activity
|
finish(); // close the activity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Unit deviceClicked(Device device) {
|
||||||
|
sendKeys(device);
|
||||||
|
finish(); // close the activity
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import org.kde.kdeconnect.KdeConnect
|
import org.kde.kdeconnect.KdeConnect
|
||||||
|
import org.kde.kdeconnect.extensions.getParcelableCompat
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the mpris media notification's buttons are pressed
|
* Called when the mpris media notification's buttons are pressed
|
||||||
@ -20,7 +21,7 @@ class MprisMediaNotificationReceiver : BroadcastReceiver() {
|
|||||||
if (Intent.ACTION_MEDIA_BUTTON == intent.action) {
|
if (Intent.ACTION_MEDIA_BUTTON == intent.action) {
|
||||||
// Route these buttons to the media session, which will handle them
|
// Route these buttons to the media session, which will handle them
|
||||||
val mediaSession = MprisMediaSession.getMediaSession() ?: return
|
val mediaSession = MprisMediaSession.getMediaSession() ?: return
|
||||||
mediaSession.controller.dispatchMediaButtonEvent(intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT))
|
mediaSession.controller.dispatchMediaButtonEvent(intent.getParcelableCompat(Intent.EXTRA_KEY_EVENT))
|
||||||
} else {
|
} else {
|
||||||
// Second case: buttons on the notification, which we created ourselves
|
// Second case: buttons on the notification, which we created ourselves
|
||||||
// Get the correct device, the mpris plugin and the mpris player
|
// Get the correct device, the mpris plugin and the mpris player
|
||||||
|
@ -99,7 +99,7 @@ class MprisMediaSession : OnSharedPreferenceChangeListener, NotificationReceiver
|
|||||||
* @param device The device id
|
* @param device The device id
|
||||||
*/
|
*/
|
||||||
fun onCreate(context: Context?, plugin: MprisPlugin, device: String) {
|
fun onCreate(context: Context?, plugin: MprisPlugin, device: String) {
|
||||||
if (mprisDevices.isEmpty) {
|
if (mprisDevices.isEmpty()) {
|
||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
prefs.registerOnSharedPreferenceChangeListener(this)
|
prefs.registerOnSharedPreferenceChangeListener(this)
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ class MprisMediaSession : OnSharedPreferenceChangeListener, NotificationReceiver
|
|||||||
plugin.removePlayerListUpdatedHandler("media_notification")
|
plugin.removePlayerListUpdatedHandler("media_notification")
|
||||||
updateMediaNotification()
|
updateMediaNotification()
|
||||||
|
|
||||||
if (mprisDevices.isEmpty) {
|
if (mprisDevices.isEmpty()) {
|
||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
prefs.unregisterOnSharedPreferenceChangeListener(this)
|
prefs.unregisterOnSharedPreferenceChangeListener(this)
|
||||||
}
|
}
|
||||||
|
@ -103,14 +103,14 @@ class MprisNowPlayingFragment : Fragment(), VolumeKeyListener {
|
|||||||
performActionOnClick(mprisControlBinding.stopButton, MprisPlayer::sendStop)
|
performActionOnClick(mprisControlBinding.stopButton, MprisPlayer::sendStop)
|
||||||
|
|
||||||
mprisControlBinding.volumeSeek.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
|
mprisControlBinding.volumeSeek.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
|
||||||
override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {}
|
override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {
|
||||||
|
|
||||||
override fun onStartTrackingTouch(seekBar: SeekBar) {}
|
|
||||||
|
|
||||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
|
||||||
val targetPlayer = targetPlayer ?: return
|
val targetPlayer = targetPlayer ?: return
|
||||||
targetPlayer.sendSetVolume(seekBar.progress)
|
targetPlayer.sendSetVolume(seekBar.progress)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStartTrackingTouch(seekBar: SeekBar) {}
|
||||||
|
|
||||||
|
override fun onStopTrackingTouch(seekBar: SeekBar) {}
|
||||||
})
|
})
|
||||||
|
|
||||||
positionSeekUpdateRunnable = Runnable {
|
positionSeekUpdateRunnable = Runnable {
|
||||||
|
@ -200,6 +200,7 @@ class MprisReceiverCallback extends MediaController.Callback {
|
|||||||
* @return null if no art is available, otherwise a PNG image serialized into a bytearray
|
* @return null if no art is available, otherwise a PNG image serialized into a bytearray
|
||||||
*/
|
*/
|
||||||
public byte[] getArtAsArray() {
|
public byte[] getArtAsArray() {
|
||||||
|
Bitmap displayArt = this.displayArt;
|
||||||
if (displayArt == null) {
|
if (displayArt == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
|
import androidx.core.os.BundleCompat;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
import org.apache.commons.collections4.MultiValuedMap;
|
import org.apache.commons.collections4.MultiValuedMap;
|
||||||
@ -358,7 +359,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
|
|||||||
if (!notification.extras.containsKey(Notification.EXTRA_MESSAGES))
|
if (!notification.extras.containsKey(Notification.EXTRA_MESSAGES))
|
||||||
return new Pair<>(null, null);
|
return new Pair<>(null, null);
|
||||||
|
|
||||||
Parcelable[] ms = notification.extras.getParcelableArray(Notification.EXTRA_MESSAGES);
|
Parcelable[] ms = BundleCompat.getParcelableArray(notification.extras, Notification.EXTRA_MESSAGES, Parcelable.class);
|
||||||
|
|
||||||
if (ms == null)
|
if (ms == null)
|
||||||
return new Pair<>(null, null);
|
return new Pair<>(null, null);
|
||||||
|
@ -11,19 +11,14 @@ import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import android.widget.ArrayAdapter
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import org.kde.kdeconnect.Device
|
import org.kde.kdeconnect.Device
|
||||||
import org.kde.kdeconnect.KdeConnect
|
import org.kde.kdeconnect.KdeConnect
|
||||||
import org.kde.kdeconnect_tp.R
|
import org.kde.kdeconnect.UserInterface.List.DeviceItem
|
||||||
|
import org.kde.kdeconnect.UserInterface.List.ListAdapter
|
||||||
import org.kde.kdeconnect_tp.databinding.WidgetRemoteCommandPluginDialogBinding
|
import org.kde.kdeconnect_tp.databinding.WidgetRemoteCommandPluginDialogBinding
|
||||||
import java.util.stream.Collectors
|
|
||||||
|
|
||||||
class RunCommandWidgetConfigActivity : AppCompatActivity() {
|
class RunCommandWidgetConfigActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@ -45,19 +40,15 @@ class RunCommandWidgetConfigActivity : AppCompatActivity() {
|
|||||||
val binding = WidgetRemoteCommandPluginDialogBinding.inflate(layoutInflater)
|
val binding = WidgetRemoteCommandPluginDialogBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
val pairedDevices = KdeConnect.getInstance().devices.values.stream().filter(Device::isPaired).collect(Collectors.toList())
|
val pairedDevices = KdeConnect.getInstance().devices.values.asSequence().filter(Device::isPaired).toList()
|
||||||
|
|
||||||
binding.runCommandsDeviceList.adapter = object : ArrayAdapter<Device>(this, 0, pairedDevices) {
|
val list = ListAdapter(this, pairedDevices.map { DeviceItem(it, ::deviceClicked) })
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
binding.runCommandsDeviceList.adapter = list
|
||||||
val view : View = convertView ?: layoutInflater.inflate(R.layout.list_item_with_icon_entry, parent, false)
|
binding.runCommandsDeviceList.emptyView = binding.noDevices
|
||||||
val device = pairedDevices[position]
|
|
||||||
view.findViewById<TextView>(R.id.list_item_entry_title).text = device.name
|
|
||||||
view.findViewById<ImageView>(R.id.list_item_entry_icon).setImageDrawable(device.icon)
|
|
||||||
return view
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
binding.runCommandsDeviceList.setOnItemClickListener { _, _, position, _ ->
|
fun deviceClicked(device: Device) {
|
||||||
val deviceId = pairedDevices[position].deviceId
|
val deviceId = device.deviceId
|
||||||
saveWidgetDeviceIdPref(this, appWidgetId, deviceId)
|
saveWidgetDeviceIdPref(this, appWidgetId, deviceId)
|
||||||
|
|
||||||
val appWidgetManager = AppWidgetManager.getInstance(this)
|
val appWidgetManager = AppWidgetManager.getInstance(this)
|
||||||
@ -68,8 +59,6 @@ class RunCommandWidgetConfigActivity : AppCompatActivity() {
|
|||||||
setResult(RESULT_OK, resultValue)
|
setResult(RESULT_OK, resultValue)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
binding.runCommandsDeviceList.emptyView = binding.noDevices
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val PREFS_NAME = "org.kde.kdeconnect_tp.WidgetProvider"
|
private const val PREFS_NAME = "org.kde.kdeconnect_tp.WidgetProvider"
|
||||||
|
@ -23,9 +23,10 @@ import org.kde.kdeconnect.BackgroundService;
|
|||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
import org.kde.kdeconnect.Helpers.WindowHelper;
|
import org.kde.kdeconnect.Helpers.WindowHelper;
|
||||||
import org.kde.kdeconnect.KdeConnect;
|
import org.kde.kdeconnect.KdeConnect;
|
||||||
import org.kde.kdeconnect.UserInterface.List.EntryItemWithIcon;
|
import org.kde.kdeconnect.UserInterface.List.DeviceItem;
|
||||||
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
|
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
|
||||||
import org.kde.kdeconnect.UserInterface.List.SectionItem;
|
import org.kde.kdeconnect.UserInterface.List.SectionItem;
|
||||||
|
import org.kde.kdeconnect.UserInterface.List.UnreachableDeviceItem;
|
||||||
import org.kde.kdeconnect.base.BaseActivity;
|
import org.kde.kdeconnect.base.BaseActivity;
|
||||||
import org.kde.kdeconnect_tp.R;
|
import org.kde.kdeconnect_tp.R;
|
||||||
import org.kde.kdeconnect_tp.databinding.ActivityShareBinding;
|
import org.kde.kdeconnect_tp.databinding.ActivityShareBinding;
|
||||||
@ -38,6 +39,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import kotlin.Lazy;
|
import kotlin.Lazy;
|
||||||
import kotlin.LazyKt;
|
import kotlin.LazyKt;
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
public class ShareActivity extends BaseActivity<ActivityShareBinding> {
|
public class ShareActivity extends BaseActivity<ActivityShareBinding> {
|
||||||
private static final String KEY_UNREACHABLE_URL_LIST = "key_unreachable_url_list";
|
private static final String KEY_UNREACHABLE_URL_LIST = "key_unreachable_url_list";
|
||||||
@ -109,27 +111,32 @@ public class ShareActivity extends BaseActivity<ActivityShareBinding> {
|
|||||||
// Show the paired devices only if they are unreachable and the shared intent has a URL
|
// Show the paired devices only if they are unreachable and the shared intent has a URL
|
||||||
if (d.isPaired() && (intentHasUrl || d.isReachable())) {
|
if (d.isPaired() && (intentHasUrl || d.isReachable())) {
|
||||||
devicesList.add(d);
|
devicesList.add(d);
|
||||||
String deviceName = d.getName();
|
|
||||||
if (!d.isReachable()) {
|
if (!d.isReachable()) {
|
||||||
deviceName = getString(R.string.unreachable_device, deviceName);
|
items.add(new UnreachableDeviceItem(d, device -> deviceClicked(device, intentHasUrl, intent)));
|
||||||
|
} else {
|
||||||
|
items.add(new DeviceItem(d, device -> deviceClicked(device, intentHasUrl, intent)));
|
||||||
}
|
}
|
||||||
items.add(new EntryItemWithIcon(deviceName, d.getIcon()));
|
|
||||||
section.isEmpty = false;
|
section.isEmpty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getBinding().devicesListLayout.devicesList.setAdapter(new ListAdapter(ShareActivity.this, items));
|
getBinding().devicesListLayout.devicesList.setAdapter(new ListAdapter(ShareActivity.this, items));
|
||||||
getBinding().devicesListLayout.devicesList.setOnItemClickListener((adapterView, view, i, l) -> {
|
|
||||||
Device device = devicesList.get(i - 1); //NOTE: -1 because of the title!
|
// Configure focus order for Accessibility, for touchpads, and for TV remotes
|
||||||
|
// (allow focus of items in the device list)
|
||||||
|
getBinding().devicesListLayout.devicesList.setItemsCanFocus(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Unit deviceClicked(Device device, boolean intentHasUrl, Intent intent) {
|
||||||
SharePlugin plugin = KdeConnect.getInstance().getDevicePlugin(device.getDeviceId(), SharePlugin.class);
|
SharePlugin plugin = KdeConnect.getInstance().getDevicePlugin(device.getDeviceId(), SharePlugin.class);
|
||||||
if (intentHasUrl && !device.isReachable()) {
|
if (intentHasUrl && !device.isReachable()) {
|
||||||
// Store the URL to be delivered once device becomes online
|
// Store the URL to be delivered once device becomes online
|
||||||
storeUrlForFutureDelivery(device, intent.toUri(0));
|
storeUrlForFutureDelivery(device, intent.getStringExtra(Intent.EXTRA_TEXT));
|
||||||
} else if (plugin != null) {
|
} else if (plugin != null) {
|
||||||
plugin.share(intent);
|
plugin.share(intent);
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
});
|
return Unit.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doesIntentContainUrl(Intent intent) {
|
private boolean doesIntentContainUrl(Intent intent) {
|
||||||
@ -187,6 +194,15 @@ public class ShareActivity extends BaseActivity<ActivityShareBinding> {
|
|||||||
SharePlugin plugin = KdeConnect.getInstance().getDevicePlugin(deviceId, SharePlugin.class);
|
SharePlugin plugin = KdeConnect.getInstance().getDevicePlugin(deviceId, SharePlugin.class);
|
||||||
if (plugin != null) {
|
if (plugin != null) {
|
||||||
plugin.share(intent);
|
plugin.share(intent);
|
||||||
|
} else {
|
||||||
|
Bundle extras = intent.getExtras();
|
||||||
|
if (extras != null && extras.containsKey(Intent.EXTRA_TEXT)) {
|
||||||
|
final Device device = KdeConnect.getInstance().getDevice(deviceId);
|
||||||
|
if (doesIntentContainUrl(intent) && device != null && !device.isReachable()) {
|
||||||
|
final String text = extras.getString(Intent.EXTRA_TEXT);
|
||||||
|
storeUrlForFutureDelivery(device, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
} else {
|
} else {
|
||||||
|
@ -22,12 +22,15 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.WorkerThread;
|
import androidx.annotation.WorkerThread;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.content.IntentCompat;
|
||||||
import androidx.core.content.LocusIdCompat;
|
import androidx.core.content.LocusIdCompat;
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat;
|
import androidx.core.content.pm.ShortcutInfoCompat;
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat;
|
import androidx.core.content.pm.ShortcutManagerCompat;
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
|
import androidx.core.os.BundleCompat;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
@ -90,23 +93,7 @@ public class SharePlugin extends Plugin {
|
|||||||
public boolean onCreate() {
|
public boolean onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
createOrUpdateDynamicShortcut(null);
|
||||||
Intent shortcutIntent = new Intent(context, MainActivity.class);
|
|
||||||
shortcutIntent.setAction(Intent.ACTION_VIEW);
|
|
||||||
shortcutIntent.putExtra(MainActivity.EXTRA_DEVICE_ID, device.getDeviceId());
|
|
||||||
|
|
||||||
IconCompat icon = IconCompat.createWithResource(context, device.getDeviceType().toShortcutDrawableId());
|
|
||||||
|
|
||||||
ShortcutInfoCompat shortcut = new ShortcutInfoCompat
|
|
||||||
.Builder(context, device.getDeviceId())
|
|
||||||
.setIntent(shortcutIntent)
|
|
||||||
.setIcon(icon)
|
|
||||||
.setShortLabel(device.getName())
|
|
||||||
.setCategories(Set.of("org.kde.kdeconnect.category.SHARE_TARGET"))
|
|
||||||
.setLocusId(new LocusIdCompat(device.getDeviceId()))
|
|
||||||
.build();
|
|
||||||
ShortcutManagerCompat.pushDynamicShortcut(context, shortcut);
|
|
||||||
|
|
||||||
// Deliver URLs previously shared to this device now that it's connected
|
// Deliver URLs previously shared to this device now that it's connected
|
||||||
deliverPreviouslySentIntents();
|
deliverPreviouslySentIntents();
|
||||||
return true;
|
return true;
|
||||||
@ -114,10 +101,49 @@ public class SharePlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
ShortcutManagerCompat.removeLongLivedShortcuts(context, List.of(device.getDeviceId()));
|
for (ShortcutInfoCompat shortcut : ShortcutManagerCompat.getDynamicShortcuts(context)) {
|
||||||
|
if (!shortcut.getId().equals(device.getDeviceId())) continue;
|
||||||
|
if (!device.isReachable() && shortcut.isPinned()) {
|
||||||
|
// Create an updated shortcut with the same ID
|
||||||
|
createOrUpdateDynamicShortcut(shortcut);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
ShortcutManagerCompat.removeLongLivedShortcuts(context, List.of(shortcut.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createOrUpdateDynamicShortcut(@Nullable ShortcutInfoCompat shortcutToUpdate) {
|
||||||
|
final boolean isNewShortcut = shortcutToUpdate == null;
|
||||||
|
IconCompat icon = IconCompat.createWithResource(
|
||||||
|
context, device.getDeviceType().toShortcutDrawableId());
|
||||||
|
Intent shortcutIntent = null;
|
||||||
|
if (isNewShortcut) {
|
||||||
|
shortcutIntent = new Intent(context, MainActivity.class);
|
||||||
|
shortcutIntent.setAction(Intent.ACTION_VIEW);
|
||||||
|
shortcutIntent.putExtra(MainActivity.EXTRA_DEVICE_ID, device.getDeviceId());
|
||||||
|
}
|
||||||
|
ShortcutInfoCompat shortcut = new ShortcutInfoCompat
|
||||||
|
.Builder(context, device.getDeviceId())
|
||||||
|
.setIntent(isNewShortcut ? shortcutIntent : shortcutToUpdate.getIntent())
|
||||||
|
.setIcon(icon)
|
||||||
|
.setShortLabel(isNewShortcut ? device.getName()
|
||||||
|
: context.getString(
|
||||||
|
R.string.unreachable_device_dynamic_shortcut,
|
||||||
|
shortcutToUpdate.getShortLabel()))
|
||||||
|
.setCategories(isNewShortcut ? Set.of("org.kde.kdeconnect.category.SHARE_TARGET")
|
||||||
|
: shortcutToUpdate.getCategories())
|
||||||
|
.setLocusId(isNewShortcut ? new LocusIdCompat(device.getDeviceId())
|
||||||
|
: shortcutToUpdate.getLocusId())
|
||||||
|
.build();
|
||||||
|
if (isNewShortcut) {
|
||||||
|
ShortcutManagerCompat.pushDynamicShortcut(context, shortcut);
|
||||||
|
} else {
|
||||||
|
ShortcutManagerCompat.updateShortcuts(context, List.of(shortcut));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void deliverPreviouslySentIntents() {
|
private void deliverPreviouslySentIntents() {
|
||||||
Set<String> currentUrlSet = mSharedPrefs.getStringSet(KEY_UNREACHABLE_URL_LIST + device.getDeviceId(), null);
|
Set<String> currentUrlSet = mSharedPrefs.getStringSet(KEY_UNREACHABLE_URL_LIST + device.getDeviceId(), null);
|
||||||
if (currentUrlSet != null) {
|
if (currentUrlSet != null) {
|
||||||
@ -125,6 +151,7 @@ public class SharePlugin extends Plugin {
|
|||||||
Intent intent;
|
Intent intent;
|
||||||
try {
|
try {
|
||||||
intent = Intent.parseUri(url, 0);
|
intent = Intent.parseUri(url, 0);
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT, url);
|
||||||
} catch (URISyntaxException ex) {
|
} catch (URISyntaxException ex) {
|
||||||
Log.e("SharePlugin", "Malformed URI");
|
Log.e("SharePlugin", "Malformed URI");
|
||||||
continue;
|
continue;
|
||||||
@ -316,12 +343,8 @@ public class SharePlugin extends Plugin {
|
|||||||
isUrl = false;
|
isUrl = false;
|
||||||
}
|
}
|
||||||
NetworkPacket np = new NetworkPacket(SharePlugin.PACKET_TYPE_SHARE_REQUEST);
|
NetworkPacket np = new NetworkPacket(SharePlugin.PACKET_TYPE_SHARE_REQUEST);
|
||||||
if (isUrl) {
|
np.set(isUrl ? "url" : "text", text);
|
||||||
np.set("url", text);
|
device.sendPacket(np);
|
||||||
} else {
|
|
||||||
np.set("text", text);
|
|
||||||
}
|
|
||||||
getDevice().sendPacket(np);
|
|
||||||
} else {
|
} else {
|
||||||
Log.e("SharePlugin", "There's nothing we know how to share");
|
Log.e("SharePlugin", "There's nothing we know how to share");
|
||||||
}
|
}
|
||||||
@ -334,10 +357,10 @@ public class SharePlugin extends Plugin {
|
|||||||
Log.i("SharePlugin", "Intent contains streams to share");
|
Log.i("SharePlugin", "Intent contains streams to share");
|
||||||
ArrayList<Uri> uriList;
|
ArrayList<Uri> uriList;
|
||||||
if (Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) {
|
if (Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) {
|
||||||
uriList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
uriList = IntentCompat.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM, Uri.class);
|
||||||
} else {
|
} else {
|
||||||
uriList = new ArrayList<>();
|
uriList = new ArrayList<>();
|
||||||
uriList.add(extras.getParcelable(Intent.EXTRA_STREAM));
|
uriList.add(BundleCompat.getParcelable(extras, Intent.EXTRA_STREAM, Uri.class));
|
||||||
}
|
}
|
||||||
uriList.removeAll(Collections.singleton(null));
|
uriList.removeAll(Collections.singleton(null));
|
||||||
if (uriList.isEmpty()) {
|
if (uriList.isEmpty()) {
|
||||||
|
@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.kde.kdeconnect.Plugins.SystemVolumePlugin;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.core.util.Consumer;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.ListAdapter;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import org.kde.kdeconnect.Helpers.VolumeHelperKt;
|
|
||||||
import org.kde.kdeconnect.KdeConnect;
|
|
||||||
import org.kde.kdeconnect.Plugins.MprisPlugin.MprisPlugin;
|
|
||||||
import org.kde.kdeconnect.Plugins.MprisPlugin.VolumeKeyListener;
|
|
||||||
import org.kde.kdeconnect_tp.R;
|
|
||||||
import org.kde.kdeconnect_tp.databinding.ListItemSystemvolumeBinding;
|
|
||||||
import org.kde.kdeconnect_tp.databinding.SystemVolumeFragmentBinding;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SystemVolumeFragment
|
|
||||||
extends Fragment
|
|
||||||
implements Sink.UpdateListener, SystemVolumePlugin.SinkListener, VolumeKeyListener {
|
|
||||||
|
|
||||||
private SystemVolumePlugin plugin;
|
|
||||||
private RecyclerSinkAdapter recyclerAdapter;
|
|
||||||
private boolean tracking;
|
|
||||||
private final Consumer<Boolean> trackingConsumer = aBoolean -> tracking = aBoolean;
|
|
||||||
private SystemVolumeFragmentBinding systemVolumeFragmentBinding;
|
|
||||||
|
|
||||||
public static SystemVolumeFragment newInstance(String deviceId) {
|
|
||||||
SystemVolumeFragment systemvolumeFragment = new SystemVolumeFragment();
|
|
||||||
|
|
||||||
Bundle arguments = new Bundle();
|
|
||||||
arguments.putString(MprisPlugin.DEVICE_ID_KEY, deviceId);
|
|
||||||
|
|
||||||
systemvolumeFragment.setArguments(arguments);
|
|
||||||
|
|
||||||
return systemvolumeFragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public View onCreateView(
|
|
||||||
@NonNull LayoutInflater inflater,
|
|
||||||
@Nullable ViewGroup container,
|
|
||||||
@Nullable Bundle savedInstanceState
|
|
||||||
) {
|
|
||||||
|
|
||||||
if (systemVolumeFragmentBinding == null) {
|
|
||||||
systemVolumeFragmentBinding = SystemVolumeFragmentBinding.inflate(inflater);
|
|
||||||
|
|
||||||
RecyclerView recyclerView = systemVolumeFragmentBinding.audioDevicesRecycler;
|
|
||||||
|
|
||||||
int gap = requireContext().getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin);
|
|
||||||
recyclerView.addItemDecoration(new ItemGapDecoration(gap));
|
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
|
||||||
|
|
||||||
recyclerAdapter = new RecyclerSinkAdapter();
|
|
||||||
recyclerView.setAdapter(recyclerAdapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
connectToPlugin(getDeviceId());
|
|
||||||
|
|
||||||
return systemVolumeFragmentBinding.getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyView() {
|
|
||||||
disconnectFromPlugin(getDeviceId());
|
|
||||||
super.onDestroyView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateSink(@NonNull final Sink sink) {
|
|
||||||
|
|
||||||
// Don't set progress while the slider is moved
|
|
||||||
if (!tracking) {
|
|
||||||
|
|
||||||
requireActivity().runOnUiThread(() -> recyclerAdapter.notifyDataSetChanged());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void connectToPlugin(final String deviceId) {
|
|
||||||
SystemVolumePlugin plugin = KdeConnect.getInstance().getDevicePlugin(deviceId, SystemVolumePlugin.class);
|
|
||||||
if (plugin == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.plugin = plugin;
|
|
||||||
plugin.addSinkListener(SystemVolumeFragment.this);
|
|
||||||
plugin.requestSinkList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disconnectFromPlugin(final String deviceId) {
|
|
||||||
SystemVolumePlugin plugin = KdeConnect.getInstance().getDevicePlugin(deviceId, SystemVolumePlugin.class);
|
|
||||||
if (plugin == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
plugin.removeSinkListener(SystemVolumeFragment.this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sinksChanged() {
|
|
||||||
|
|
||||||
for (Sink sink : plugin.getSinks()) {
|
|
||||||
sink.addListener(SystemVolumeFragment.this);
|
|
||||||
}
|
|
||||||
|
|
||||||
requireActivity().runOnUiThread(() -> {
|
|
||||||
List<Sink> newSinks = new ArrayList<>(plugin.getSinks());
|
|
||||||
recyclerAdapter.submitList(newSinks);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onVolumeUp() {
|
|
||||||
updateDefaultSinkVolume(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onVolumeDown() {
|
|
||||||
updateDefaultSinkVolume(-5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateDefaultSinkVolume(int percent) {
|
|
||||||
if (plugin == null) return;
|
|
||||||
|
|
||||||
Sink defaultSink = SystemVolumeUtilsKt.getDefaultSink(plugin);
|
|
||||||
if (defaultSink == null) return;
|
|
||||||
|
|
||||||
int newVolume = VolumeHelperKt.calculateNewVolume(
|
|
||||||
defaultSink.getVolume(),
|
|
||||||
defaultSink.getMaxVolume(),
|
|
||||||
percent
|
|
||||||
);
|
|
||||||
|
|
||||||
if (defaultSink.getVolume() == newVolume) return;
|
|
||||||
|
|
||||||
plugin.sendVolume(defaultSink.getName(), newVolume);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getDeviceId() {
|
|
||||||
return requireArguments().getString(MprisPlugin.DEVICE_ID_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RecyclerSinkAdapter extends ListAdapter<Sink, SinkItemHolder> {
|
|
||||||
|
|
||||||
public RecyclerSinkAdapter() {
|
|
||||||
super(new SinkItemCallback());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public SinkItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
|
||||||
|
|
||||||
LayoutInflater inflater = getLayoutInflater();
|
|
||||||
ListItemSystemvolumeBinding viewBinding = ListItemSystemvolumeBinding.inflate(inflater, parent, false);
|
|
||||||
|
|
||||||
return new SinkItemHolder(viewBinding, plugin, trackingConsumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull SinkItemHolder holder, int position) {
|
|
||||||
holder.bind(getItem(position));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
package org.kde.kdeconnect.Plugins.SystemVolumePlugin
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.util.Consumer
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import org.kde.kdeconnect.Helpers.calculateNewVolume
|
||||||
|
import org.kde.kdeconnect.KdeConnect
|
||||||
|
import org.kde.kdeconnect.Plugins.MprisPlugin.MprisPlugin
|
||||||
|
import org.kde.kdeconnect.Plugins.MprisPlugin.VolumeKeyListener
|
||||||
|
import org.kde.kdeconnect.Plugins.SystemVolumePlugin.SystemVolumePlugin.SinkListener
|
||||||
|
import org.kde.kdeconnect.base.BaseFragment
|
||||||
|
import org.kde.kdeconnect.extensions.setupBottomPadding
|
||||||
|
import org.kde.kdeconnect_tp.R
|
||||||
|
import org.kde.kdeconnect_tp.databinding.ListItemSystemvolumeBinding
|
||||||
|
import org.kde.kdeconnect_tp.databinding.SystemVolumeFragmentBinding
|
||||||
|
|
||||||
|
class SystemVolumeFragment : BaseFragment<SystemVolumeFragmentBinding>(),
|
||||||
|
Sink.UpdateListener, SinkListener, VolumeKeyListener {
|
||||||
|
|
||||||
|
private lateinit var plugin: SystemVolumePlugin
|
||||||
|
private lateinit var recyclerAdapter: RecyclerSinkAdapter
|
||||||
|
private var tracking = false
|
||||||
|
private val trackingConsumer = Consumer { aBoolean: Boolean -> tracking = aBoolean }
|
||||||
|
|
||||||
|
override fun onInflateBinding(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): SystemVolumeFragmentBinding {
|
||||||
|
return SystemVolumeFragmentBinding.inflate(inflater, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
recyclerAdapter = RecyclerSinkAdapter()
|
||||||
|
binding.audioDevicesRecycler.apply {
|
||||||
|
layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
addItemDecoration(ItemGapDecoration(resources.getDimensionPixelSize(R.dimen.activity_vertical_margin)))
|
||||||
|
adapter = recyclerAdapter
|
||||||
|
setupBottomPadding()
|
||||||
|
}
|
||||||
|
connectToPlugin(deviceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
disconnectFromPlugin(deviceId)
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
override fun updateSink(sink: Sink) {
|
||||||
|
// Don't set progress while the slider is moved
|
||||||
|
if (!tracking) {
|
||||||
|
requireActivity().runOnUiThread {
|
||||||
|
if (::recyclerAdapter.isInitialized) {
|
||||||
|
recyclerAdapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun connectToPlugin(deviceId: String?) {
|
||||||
|
val plugin = KdeConnect.getInstance().getDevicePlugin(
|
||||||
|
deviceId,
|
||||||
|
SystemVolumePlugin::class.java
|
||||||
|
)
|
||||||
|
if (plugin == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.plugin = plugin
|
||||||
|
plugin.addSinkListener(this@SystemVolumeFragment)
|
||||||
|
plugin.requestSinkList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun disconnectFromPlugin(deviceId: String?) {
|
||||||
|
val plugin = KdeConnect.getInstance().getDevicePlugin(
|
||||||
|
deviceId,
|
||||||
|
SystemVolumePlugin::class.java
|
||||||
|
)
|
||||||
|
if (plugin == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
plugin.removeSinkListener(this@SystemVolumeFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sinksChanged() {
|
||||||
|
if (!::plugin.isInitialized || !::recyclerAdapter.isInitialized) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (sink in plugin.sinks) {
|
||||||
|
sink.addListener(this@SystemVolumeFragment)
|
||||||
|
}
|
||||||
|
requireActivity().runOnUiThread {
|
||||||
|
val newSinks: List<Sink> = ArrayList(plugin.sinks)
|
||||||
|
recyclerAdapter.submitList(newSinks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onVolumeUp() {
|
||||||
|
updateDefaultSinkVolume(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onVolumeDown() {
|
||||||
|
updateDefaultSinkVolume(-5)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDefaultSinkVolume(percent: Int) {
|
||||||
|
if (!::plugin.isInitialized) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val defaultSink = getDefaultSink(plugin) ?: return
|
||||||
|
|
||||||
|
val newVolume = calculateNewVolume(
|
||||||
|
defaultSink.volume,
|
||||||
|
defaultSink.maxVolume,
|
||||||
|
percent
|
||||||
|
)
|
||||||
|
|
||||||
|
if (defaultSink.volume == newVolume) return
|
||||||
|
|
||||||
|
plugin.sendVolume(defaultSink.name, newVolume)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val deviceId: String?
|
||||||
|
get() = arguments?.getString(MprisPlugin.DEVICE_ID_KEY)
|
||||||
|
|
||||||
|
private inner class RecyclerSinkAdapter : ListAdapter<Sink?, SinkItemHolder>(SinkItemCallback()) {
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SinkItemHolder {
|
||||||
|
val viewBinding = ListItemSystemvolumeBinding.inflate(layoutInflater, parent, false)
|
||||||
|
return SinkItemHolder(viewBinding, plugin, trackingConsumer)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: SinkItemHolder, position: Int) {
|
||||||
|
holder.bind(getItem(position))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance(deviceId: String?): SystemVolumeFragment {
|
||||||
|
val systemVolumeFragment = SystemVolumeFragment()
|
||||||
|
|
||||||
|
val arguments = Bundle()
|
||||||
|
arguments.putString(MprisPlugin.DEVICE_ID_KEY, deviceId)
|
||||||
|
|
||||||
|
systemVolumeFragment.arguments = arguments
|
||||||
|
|
||||||
|
return systemVolumeFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,50 +14,56 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import org.kde.kdeconnect.UserInterface.List.ListAdapter
|
import org.kde.kdeconnect.UserInterface.List.ListAdapter
|
||||||
import org.kde.kdeconnect.UserInterface.MainActivity
|
import org.kde.kdeconnect.base.BaseFragment
|
||||||
|
import org.kde.kdeconnect.extensions.getParcelableCompat
|
||||||
import org.kde.kdeconnect.extensions.setupBottomPadding
|
import org.kde.kdeconnect.extensions.setupBottomPadding
|
||||||
import org.kde.kdeconnect_tp.R
|
import org.kde.kdeconnect_tp.R
|
||||||
import org.kde.kdeconnect_tp.databinding.FragmentAboutBinding
|
import org.kde.kdeconnect_tp.databinding.FragmentAboutBinding
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
|
||||||
class AboutFragment : Fragment() {
|
class AboutFragment : BaseFragment<FragmentAboutBinding>() {
|
||||||
private var _binding: FragmentAboutBinding? = null
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
private lateinit var aboutData: AboutData
|
|
||||||
private var tapCount = 0
|
|
||||||
private var firstTapMillis: Long? = null
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val KEY_ABOUT_DATA = "about_data"
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun newInstance(aboutData: AboutData): Fragment {
|
fun newInstance(aboutData: AboutData): Fragment {
|
||||||
val fragment = AboutFragment()
|
val fragment = AboutFragment()
|
||||||
|
|
||||||
val args = Bundle(1)
|
val args = Bundle(1)
|
||||||
args.putParcelable("ABOUT_DATA", aboutData)
|
args.putParcelable(KEY_ABOUT_DATA, aboutData)
|
||||||
fragment.arguments = args
|
fragment.arguments = args
|
||||||
|
|
||||||
return fragment
|
return fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
private lateinit var aboutData: AboutData
|
||||||
if (activity != null) {
|
private var tapCount = 0
|
||||||
(requireActivity() as MainActivity).supportActionBar?.setTitle(R.string.about)
|
private var firstTapMillis: Long? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
aboutData = arguments?.getParcelableCompat(KEY_ABOUT_DATA) ?: throw IllegalArgumentException("AboutData is null")
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutData = requireArguments().getParcelable("ABOUT_DATA")!!
|
override fun onInflateBinding(
|
||||||
_binding = FragmentAboutBinding.inflate(inflater, container, false)
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
updateData()
|
savedInstanceState: Bundle?
|
||||||
return binding.root
|
): FragmentAboutBinding {
|
||||||
|
return FragmentAboutBinding.inflate(inflater, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
(activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.about)
|
||||||
binding.scrollView.setupBottomPadding()
|
binding.scrollView.setupBottomPadding()
|
||||||
|
updateData()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
@ -65,8 +71,8 @@ class AboutFragment : Fragment() {
|
|||||||
// Update general info
|
// Update general info
|
||||||
|
|
||||||
binding.appName.text = aboutData.name
|
binding.appName.text = aboutData.name
|
||||||
binding.appIcon.setImageDrawable(this.context?.let { ContextCompat.getDrawable(it, aboutData.icon) })
|
binding.appIcon.setImageDrawable(context?.let { ContextCompat.getDrawable(it, aboutData.icon) })
|
||||||
binding.appVersion.text = this.context?.getString(R.string.version, aboutData.versionName)
|
binding.appVersion.text = context?.getString(R.string.version, aboutData.versionName)
|
||||||
|
|
||||||
// Setup Easter Egg onClickListener
|
// Setup Easter Egg onClickListener
|
||||||
|
|
||||||
@ -103,7 +109,7 @@ class AboutFragment : Fragment() {
|
|||||||
setupInfoButton(aboutData.websiteURL, binding.websiteButton)
|
setupInfoButton(aboutData.websiteURL, binding.websiteButton)
|
||||||
|
|
||||||
// Update authors
|
// Update authors
|
||||||
binding.authorsList.adapter = ListAdapter(this.requireContext(), aboutData.authors.map { AboutPersonEntryItem(it) }, false)
|
binding.authorsList.adapter = ListAdapter(requireContext(), aboutData.authors.map { AboutPersonEntryItem(it) }, false)
|
||||||
if (aboutData.authorsFooterText != null) {
|
if (aboutData.authorsFooterText != null) {
|
||||||
binding.authorsFooterText.text = context?.getString(aboutData.authorsFooterText!!)
|
binding.authorsFooterText.text = context?.getString(aboutData.authorsFooterText!!)
|
||||||
}
|
}
|
||||||
@ -119,8 +125,4 @@ class AboutFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -11,6 +11,8 @@ import android.util.Log
|
|||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
@ -30,7 +32,8 @@ import androidx.compose.ui.semantics.semantics
|
|||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.*
|
import androidx.compose.ui.unit.*
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.core.view.MenuProvider
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import org.kde.kdeconnect.BackgroundService
|
import org.kde.kdeconnect.BackgroundService
|
||||||
import org.kde.kdeconnect.Device
|
import org.kde.kdeconnect.Device
|
||||||
@ -44,44 +47,15 @@ import org.kde.kdeconnect.Plugins.Plugin
|
|||||||
import org.kde.kdeconnect.Plugins.PresenterPlugin.PresenterPlugin
|
import org.kde.kdeconnect.Plugins.PresenterPlugin.PresenterPlugin
|
||||||
import org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandPlugin
|
import org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandPlugin
|
||||||
import org.kde.kdeconnect.UserInterface.compose.KdeTheme
|
import org.kde.kdeconnect.UserInterface.compose.KdeTheme
|
||||||
|
import org.kde.kdeconnect.base.BaseFragment
|
||||||
import org.kde.kdeconnect.extensions.setupBottomPadding
|
import org.kde.kdeconnect.extensions.setupBottomPadding
|
||||||
import org.kde.kdeconnect_tp.R
|
import org.kde.kdeconnect_tp.R
|
||||||
import org.kde.kdeconnect_tp.databinding.ActivityDeviceBinding
|
import org.kde.kdeconnect_tp.databinding.ActivityDeviceBinding
|
||||||
import org.kde.kdeconnect_tp.databinding.ViewPairErrorBinding
|
|
||||||
import org.kde.kdeconnect_tp.databinding.ViewPairRequestBinding
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main view. Displays the current device and its plugins
|
* Main view. Displays the current device and its plugins
|
||||||
*/
|
*/
|
||||||
class DeviceFragment : Fragment() {
|
class DeviceFragment : BaseFragment<ActivityDeviceBinding>() {
|
||||||
val deviceId: String by lazy {
|
|
||||||
arguments?.getString(ARG_DEVICE_ID)
|
|
||||||
?: throw RuntimeException("You must instantiate a new DeviceFragment using DeviceFragment.newInstance()")
|
|
||||||
}
|
|
||||||
private var device: Device? = null
|
|
||||||
private val mActivity: MainActivity? by lazy { activity as MainActivity? }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Top-level ViewBinding for this fragment.
|
|
||||||
*/
|
|
||||||
private var deviceBinding: ActivityDeviceBinding? = null
|
|
||||||
private fun requireDeviceBinding() = deviceBinding ?: throw IllegalStateException("deviceBinding is not set")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not-yet-paired ViewBinding.
|
|
||||||
*
|
|
||||||
* Used to start and retry pairing.
|
|
||||||
*/
|
|
||||||
private var pairingBinding: ViewPairRequestBinding? = null
|
|
||||||
private fun requirePairingBinding() = pairingBinding ?: throw IllegalStateException("binding is not set")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cannot-communicate ViewBinding.
|
|
||||||
*
|
|
||||||
* Used when the remote device is unreachable.
|
|
||||||
*/
|
|
||||||
private var errorBinding: ViewPairErrorBinding? = null
|
|
||||||
private fun requireErrorBinding() = errorBinding ?: throw IllegalStateException("errorBinding is not set")
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ARG_DEVICE_ID = "deviceId"
|
private const val ARG_DEVICE_ID = "deviceId"
|
||||||
@ -97,87 +71,40 @@ class DeviceFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
val deviceId: String by lazy {
|
||||||
|
arguments?.getString(ARG_DEVICE_ID)
|
||||||
|
?: throw RuntimeException("You must instantiate a new DeviceFragment using DeviceFragment.newInstance()")
|
||||||
|
}
|
||||||
|
|
||||||
|
private var device: Device? = null
|
||||||
|
|
||||||
|
private val mActivity: MainActivity? by lazy { activity as MainActivity? }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not-yet-paired ViewBinding.
|
||||||
|
*
|
||||||
|
* Used to start and retry pairing.
|
||||||
|
*/
|
||||||
|
private val pairingBinding get() = binding.pairRequest
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cannot-communicate ViewBinding.
|
||||||
|
*
|
||||||
|
* Used when the remote device is unreachable.
|
||||||
|
*/
|
||||||
|
private val errorBinding get() = binding.pairError
|
||||||
|
|
||||||
|
override fun onInflateBinding(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): ActivityDeviceBinding {
|
||||||
deviceBinding = ActivityDeviceBinding.inflate(inflater, container, false)
|
return ActivityDeviceBinding.inflate(inflater, container, false)
|
||||||
val deviceBinding = deviceBinding ?: return null
|
|
||||||
|
|
||||||
// Inner binding for the layout shown when we're not paired yet...
|
|
||||||
pairingBinding = deviceBinding.pairRequest
|
|
||||||
// ...and for when pairing doesn't (or can't) work
|
|
||||||
errorBinding = deviceBinding.pairError
|
|
||||||
|
|
||||||
device = KdeConnect.getInstance().getDevice(deviceId)
|
|
||||||
|
|
||||||
requireErrorBinding().errorMessageContainer.setOnRefreshListener {
|
|
||||||
this.refreshDevicesAction()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
requirePairingBinding().pairButton.setOnClickListener {
|
private val menuProvider = object : MenuProvider {
|
||||||
device?.requestPairing()
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
refreshUI()
|
|
||||||
}
|
|
||||||
requirePairingBinding().acceptButton.setOnClickListener {
|
|
||||||
device?.apply {
|
|
||||||
acceptPairing()
|
|
||||||
requirePairingBinding().pairingButtons.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requirePairingBinding().rejectButton.setOnClickListener {
|
|
||||||
device?.apply {
|
|
||||||
// Remove listener so buttons don't show for an instant before changing the view
|
|
||||||
removePluginsChangedListener(pluginsChangedListener)
|
|
||||||
removePairingCallback(pairingCallback)
|
|
||||||
cancelPairing()
|
|
||||||
}
|
|
||||||
mActivity?.onDeviceSelected(null)
|
|
||||||
}
|
|
||||||
setHasOptionsMenu(true)
|
|
||||||
|
|
||||||
device?.apply {
|
|
||||||
mActivity?.supportActionBar?.title = name
|
|
||||||
addPairingCallback(pairingCallback)
|
|
||||||
addPluginsChangedListener(pluginsChangedListener)
|
|
||||||
} ?: run { // device is null
|
|
||||||
Log.e(TAG, "Trying to display a device fragment but the device is not present")
|
|
||||||
mActivity?.onDeviceSelected(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshUI()
|
|
||||||
|
|
||||||
return deviceBinding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
deviceBinding?.deviceView?.setupBottomPadding()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun refreshDevicesAction() {
|
|
||||||
BackgroundService.ForceRefreshConnections(requireContext())
|
|
||||||
requireErrorBinding().errorMessageContainer.isRefreshing = true
|
|
||||||
requireErrorBinding().errorMessageContainer.postDelayed({
|
|
||||||
errorBinding?.errorMessageContainer?.isRefreshing = false // check for null since the view might be destroyed by now
|
|
||||||
}, 1500)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val pluginsChangedListener = PluginsChangedListener { mActivity?.runOnUiThread { refreshUI() } }
|
|
||||||
override fun onDestroyView() {
|
|
||||||
device?.apply {
|
|
||||||
removePluginsChangedListener(pluginsChangedListener)
|
|
||||||
removePairingCallback(pairingCallback)
|
|
||||||
}
|
|
||||||
device = null
|
|
||||||
pairingBinding = null
|
|
||||||
errorBinding = null
|
|
||||||
deviceBinding = null
|
|
||||||
super.onDestroyView()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
|
||||||
super.onPrepareOptionsMenu(menu)
|
|
||||||
menu.clear()
|
menu.clear()
|
||||||
val device = device ?: return
|
val device = device ?: return
|
||||||
|
|
||||||
@ -243,6 +170,71 @@ class DeviceFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
binding.deviceView.setupBottomPadding()
|
||||||
|
errorBinding.errorMessageContainer.setOnRefreshListener {
|
||||||
|
this.refreshDevicesAction()
|
||||||
|
}
|
||||||
|
pairingBinding.pairButton.setOnClickListener {
|
||||||
|
device?.requestPairing()
|
||||||
|
refreshUI()
|
||||||
|
}
|
||||||
|
pairingBinding.acceptButton.setOnClickListener {
|
||||||
|
device?.apply {
|
||||||
|
acceptPairing()
|
||||||
|
pairingBinding.pairingButtons.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pairingBinding.rejectButton.setOnClickListener {
|
||||||
|
device?.apply {
|
||||||
|
// Remove listener so buttons don't show for an instant before changing the view
|
||||||
|
removePluginsChangedListener(pluginsChangedListener)
|
||||||
|
removePairingCallback(pairingCallback)
|
||||||
|
cancelPairing()
|
||||||
|
}
|
||||||
|
mActivity?.onDeviceSelected(null)
|
||||||
|
}
|
||||||
|
device = KdeConnect.getInstance().getDevice(deviceId)
|
||||||
|
device?.apply {
|
||||||
|
mActivity?.supportActionBar?.title = name
|
||||||
|
addPairingCallback(pairingCallback)
|
||||||
|
addPluginsChangedListener(pluginsChangedListener)
|
||||||
|
} ?: run { // device is null
|
||||||
|
Log.e(TAG, "Trying to display a device fragment but the device is not present")
|
||||||
|
mActivity?.onDeviceSelected(null)
|
||||||
|
}
|
||||||
|
mActivity?.addMenuProvider(menuProvider, viewLifecycleOwner)
|
||||||
|
refreshUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshDevicesAction() {
|
||||||
|
BackgroundService.ForceRefreshConnections(requireContext())
|
||||||
|
errorBinding.errorMessageContainer.isRefreshing = true
|
||||||
|
errorBinding.errorMessageContainer.postDelayed({
|
||||||
|
if (viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)) {
|
||||||
|
errorBinding.errorMessageContainer.isRefreshing = false // check for null since the view might be destroyed by now
|
||||||
|
}
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val pluginsChangedListener = PluginsChangedListener { mActivity?.runOnUiThread { refreshUI() } }
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
device?.apply {
|
||||||
|
removePluginsChangedListener(pluginsChangedListener)
|
||||||
|
removePairingCallback(pairingCallback)
|
||||||
|
}
|
||||||
|
device = null
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
with(requireView()) {
|
with(requireView()) {
|
||||||
@ -270,13 +262,13 @@ class DeviceFragment : Fragment() {
|
|||||||
|
|
||||||
when (device.pairStatus) {
|
when (device.pairStatus) {
|
||||||
PairingHandler.PairState.NotPaired -> {
|
PairingHandler.PairState.NotPaired -> {
|
||||||
requireErrorBinding().errorMessageContainer.visibility = View.GONE
|
errorBinding.errorMessageContainer.visibility = View.GONE
|
||||||
requireDeviceBinding().deviceView.visibility = View.GONE
|
binding.deviceView.visibility = View.GONE
|
||||||
requirePairingBinding().pairingButtons.visibility = View.VISIBLE
|
pairingBinding.pairingButtons.visibility = View.VISIBLE
|
||||||
requirePairingBinding().pairVerification.visibility = View.GONE
|
pairingBinding.pairVerification.visibility = View.GONE
|
||||||
}
|
}
|
||||||
PairingHandler.PairState.Requested -> {
|
PairingHandler.PairState.Requested -> {
|
||||||
with(requirePairingBinding()) {
|
with(pairingBinding) {
|
||||||
pairButton.visibility = View.GONE
|
pairButton.visibility = View.GONE
|
||||||
pairMessage.text = getString(R.string.pair_requested)
|
pairMessage.text = getString(R.string.pair_requested)
|
||||||
pairProgress.visibility = View.VISIBLE
|
pairProgress.visibility = View.VISIBLE
|
||||||
@ -285,7 +277,7 @@ class DeviceFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PairingHandler.PairState.RequestedByPeer -> {
|
PairingHandler.PairState.RequestedByPeer -> {
|
||||||
with (requirePairingBinding()) {
|
with (pairingBinding) {
|
||||||
pairMessage.setText(R.string.pair_requested)
|
pairMessage.setText(R.string.pair_requested)
|
||||||
pairVerification.visibility = View.VISIBLE
|
pairVerification.visibility = View.VISIBLE
|
||||||
pairingButtons.visibility = View.VISIBLE
|
pairingButtons.visibility = View.VISIBLE
|
||||||
@ -295,25 +287,25 @@ class DeviceFragment : Fragment() {
|
|||||||
pairVerification.text = device.verificationKey
|
pairVerification.text = device.verificationKey
|
||||||
pairVerification.visibility = View.VISIBLE
|
pairVerification.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
requireDeviceBinding().deviceView.visibility = View.GONE
|
binding.deviceView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
PairingHandler.PairState.Paired -> {
|
PairingHandler.PairState.Paired -> {
|
||||||
requirePairingBinding().pairingButtons.visibility = View.GONE
|
pairingBinding.pairingButtons.visibility = View.GONE
|
||||||
if (device.isReachable) {
|
if (device.isReachable) {
|
||||||
val context = requireContext()
|
val context = requireContext()
|
||||||
val pluginsWithButtons = device.loadedPlugins.values.filter { it.displayAsButton(context) }
|
val pluginsWithButtons = device.loadedPlugins.values.filter { it.displayAsButton(context) }
|
||||||
val pluginsNeedPermissions = device.pluginsWithoutPermissions.values.filter { device.isPluginEnabled(it.pluginKey) }
|
val pluginsNeedPermissions = device.pluginsWithoutPermissions.values.filter { device.isPluginEnabled(it.pluginKey) }
|
||||||
val pluginsNeedOptionalPermissions = device.pluginsWithoutOptionalPermissions.values.filter { device.isPluginEnabled(it.pluginKey) }
|
val pluginsNeedOptionalPermissions = device.pluginsWithoutOptionalPermissions.values.filter { device.isPluginEnabled(it.pluginKey) }
|
||||||
requireErrorBinding().errorMessageContainer.visibility = View.GONE
|
errorBinding.errorMessageContainer.visibility = View.GONE
|
||||||
requireDeviceBinding().deviceView.visibility = View.VISIBLE
|
binding.deviceView.visibility = View.VISIBLE
|
||||||
requireDeviceBinding().deviceViewCompose.apply {
|
binding.deviceViewCompose.apply {
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||||
setContent { KdeTheme(context) { PluginList(pluginsWithButtons, pluginsNeedPermissions, pluginsNeedOptionalPermissions) } }
|
setContent { KdeTheme(context) { PluginList(pluginsWithButtons, pluginsNeedPermissions, pluginsNeedOptionalPermissions) } }
|
||||||
}
|
}
|
||||||
displayBatteryInfoIfPossible()
|
displayBatteryInfoIfPossible()
|
||||||
} else {
|
} else {
|
||||||
requireErrorBinding().errorMessageContainer.visibility = View.VISIBLE
|
errorBinding.errorMessageContainer.visibility = View.VISIBLE
|
||||||
requireDeviceBinding().deviceView.visibility = View.GONE
|
binding.deviceView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,13 +318,13 @@ class DeviceFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun pairingSuccessful() {
|
override fun pairingSuccessful() {
|
||||||
requirePairingBinding().pairMessage.announceForAccessibility(getString(R.string.pair_succeeded))
|
pairingBinding.pairMessage.announceForAccessibility(getString(R.string.pair_succeeded))
|
||||||
mActivity?.runOnUiThread { refreshUI() }
|
mActivity?.runOnUiThread { refreshUI() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pairingFailed(error: String) {
|
override fun pairingFailed(error: String) {
|
||||||
mActivity?.runOnUiThread {
|
mActivity?.runOnUiThread {
|
||||||
with(requirePairingBinding()) {
|
with(pairingBinding) {
|
||||||
pairMessage.text = error
|
pairMessage.text = error
|
||||||
pairProgress.visibility = View.GONE
|
pairProgress.visibility = View.GONE
|
||||||
pairButton.visibility = View.VISIBLE
|
pairButton.visibility = View.VISIBLE
|
||||||
@ -344,7 +336,7 @@ class DeviceFragment : Fragment() {
|
|||||||
|
|
||||||
override fun unpaired() {
|
override fun unpaired() {
|
||||||
mActivity?.runOnUiThread {
|
mActivity?.runOnUiThread {
|
||||||
with(requirePairingBinding()) {
|
with(pairingBinding) {
|
||||||
pairMessage.setText(R.string.device_not_paired)
|
pairMessage.setText(R.string.device_not_paired)
|
||||||
pairProgress.visibility = View.GONE
|
pairProgress.visibility = View.GONE
|
||||||
pairButton.visibility = View.VISIBLE
|
pairButton.visibility = View.VISIBLE
|
||||||
@ -501,5 +493,4 @@ class DeviceFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
32
src/org/kde/kdeconnect/UserInterface/List/DeviceItem.kt
Normal file
32
src/org/kde/kdeconnect/UserInterface/List/DeviceItem.kt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Albert Vaca Cintora <albertvaka@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
package org.kde.kdeconnect.UserInterface.List
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import org.kde.kdeconnect.Device
|
||||||
|
import org.kde.kdeconnect_tp.databinding.ListItemDeviceEntryBinding
|
||||||
|
|
||||||
|
open class DeviceItem(
|
||||||
|
val device: Device,
|
||||||
|
private val callback: ((d: Device) -> Unit)
|
||||||
|
) : ListAdapter.Item
|
||||||
|
{
|
||||||
|
protected lateinit var binding: ListItemDeviceEntryBinding
|
||||||
|
|
||||||
|
override fun inflateView(layoutInflater: LayoutInflater): View {
|
||||||
|
binding = ListItemDeviceEntryBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
binding.listItemEntryIcon.setImageDrawable(device.icon)
|
||||||
|
binding.listItemEntryTitle.text = device.name
|
||||||
|
|
||||||
|
binding.getRoot().setOnClickListener(View.OnClickListener { v1: View? ->
|
||||||
|
callback(device)
|
||||||
|
})
|
||||||
|
|
||||||
|
return binding.getRoot()
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Albert Vaca Cintora <albertvaka@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
package org.kde.kdeconnect.UserInterface.List
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import org.kde.kdeconnect_tp.databinding.ListCardEntryBinding
|
|
||||||
|
|
||||||
open class EntryItemWithIcon : ListAdapter.Item {
|
|
||||||
protected val title: String
|
|
||||||
protected val icon: Drawable
|
|
||||||
|
|
||||||
constructor(title: String, icon: Drawable) {
|
|
||||||
this.title = title
|
|
||||||
this.icon = icon
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun inflateView(layoutInflater: LayoutInflater): View {
|
|
||||||
val binding = ListCardEntryBinding.inflate(layoutInflater)
|
|
||||||
|
|
||||||
binding.listItemEntryTitle.text = title
|
|
||||||
binding.listItemEntryIcon.setImageDrawable(icon)
|
|
||||||
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Albert Vaca Cintora <albertvaka@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.kde.kdeconnect.UserInterface.List;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.kde.kdeconnect.Device;
|
|
||||||
import org.kde.kdeconnect_tp.R;
|
|
||||||
import org.kde.kdeconnect_tp.databinding.ListItemWithIconEntryBinding;
|
|
||||||
|
|
||||||
public class PairingDeviceItem implements ListAdapter.Item {
|
|
||||||
|
|
||||||
public interface Callback {
|
|
||||||
void pairingClicked(Device d);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Callback callback;
|
|
||||||
private final Device device;
|
|
||||||
|
|
||||||
public PairingDeviceItem(Device device, Callback callback) {
|
|
||||||
this.device = device;
|
|
||||||
this.callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Device getDevice() {
|
|
||||||
return this.device;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public View inflateView(@NonNull LayoutInflater layoutInflater) {
|
|
||||||
final ListItemWithIconEntryBinding binding = ListItemWithIconEntryBinding.inflate(layoutInflater);
|
|
||||||
|
|
||||||
binding.listItemEntryIcon.setImageDrawable(device.getIcon());
|
|
||||||
// binding.listItemEntryTitle.setText(device.getName() + " " + device.getConnectivityType());
|
|
||||||
binding.listItemEntryTitle.setText(device.getName());
|
|
||||||
|
|
||||||
if (device.compareProtocolVersion() != 0) {
|
|
||||||
if (device.compareProtocolVersion() > 0) {
|
|
||||||
binding.listItemEntrySummary.setText(R.string.protocol_version_newer);
|
|
||||||
binding.listItemEntrySummary.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
//FIXME: Uncoment when we decide old versions are old enough to notify the user.
|
|
||||||
binding.listItemEntrySummary.setVisibility(View.GONE);
|
|
||||||
/*
|
|
||||||
summaryView.setText(R.string.protocol_version_older);
|
|
||||||
summaryView.setVisibility(View.VISIBLE);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
binding.listItemEntrySummary.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.getRoot().setOnClickListener(v1 -> callback.pairingClicked(device));
|
|
||||||
|
|
||||||
return binding.getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Albert Vaca Cintora <albertvaka@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
package org.kde.kdeconnect.UserInterface.List
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import org.kde.kdeconnect.Device
|
||||||
|
import org.kde.kdeconnect_tp.R
|
||||||
|
|
||||||
|
class PairingDeviceItem(
|
||||||
|
device: Device,
|
||||||
|
callback: ((d: Device) -> Unit)
|
||||||
|
) : DeviceItem(device, callback) {
|
||||||
|
override fun inflateView(layoutInflater: LayoutInflater): View {
|
||||||
|
return super.inflateView(layoutInflater).also {
|
||||||
|
if (device.compareProtocolVersion() > 0) {
|
||||||
|
binding.listItemEntrySummary.setText(R.string.protocol_version_newer)
|
||||||
|
binding.listItemEntrySummary.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Albert Vaca Cintora <albertvaka@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
package org.kde.kdeconnect.UserInterface.List
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import org.kde.kdeconnect.Device
|
||||||
|
import org.kde.kdeconnect_tp.R
|
||||||
|
|
||||||
|
class UnreachableDeviceItem(
|
||||||
|
device: Device,
|
||||||
|
callback: ((d: Device) -> Unit),
|
||||||
|
) : DeviceItem(device, callback) {
|
||||||
|
override fun inflateView(layoutInflater: LayoutInflater): View {
|
||||||
|
return super.inflateView(layoutInflater).also {
|
||||||
|
binding.listItemEntrySummary.setText(R.string.runcommand_notreachable)
|
||||||
|
binding.listItemEntrySummary.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,317 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Albert Vaca Cintora <albertvaka@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.kde.kdeconnect.UserInterface;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import org.kde.kdeconnect.BackgroundService;
|
|
||||||
import org.kde.kdeconnect.Device;
|
|
||||||
import org.kde.kdeconnect.Helpers.TrustedNetworkHelper;
|
|
||||||
import org.kde.kdeconnect.Helpers.WindowHelper;
|
|
||||||
import org.kde.kdeconnect.KdeConnect;
|
|
||||||
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
|
|
||||||
import org.kde.kdeconnect.UserInterface.List.PairingDeviceItem;
|
|
||||||
import org.kde.kdeconnect.UserInterface.List.SectionItem;
|
|
||||||
import org.kde.kdeconnect_tp.R;
|
|
||||||
import org.kde.kdeconnect_tp.databinding.DevicesListBinding;
|
|
||||||
import org.kde.kdeconnect_tp.databinding.PairingExplanationNotTrustedBinding;
|
|
||||||
import org.kde.kdeconnect_tp.databinding.PairingExplanationTextBinding;
|
|
||||||
import org.kde.kdeconnect_tp.databinding.PairingExplanationTextNoNotificationsBinding;
|
|
||||||
import org.kde.kdeconnect_tp.databinding.PairingExplanationTextNoWifiBinding;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The view that the user will see when there are no devices paired, or when you choose "add a new device" from the sidebar.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class PairingFragment extends Fragment implements PairingDeviceItem.Callback {
|
|
||||||
|
|
||||||
private static final int RESULT_PAIRING_SUCCESFUL = Activity.RESULT_FIRST_USER;
|
|
||||||
|
|
||||||
private DevicesListBinding devicesListBinding;
|
|
||||||
private PairingExplanationNotTrustedBinding pairingExplanationNotTrustedBinding;
|
|
||||||
private PairingExplanationTextBinding pairingExplanationTextBinding;
|
|
||||||
private PairingExplanationTextNoWifiBinding pairingExplanationTextNoWifiBinding;
|
|
||||||
private PairingExplanationTextNoNotificationsBinding pairingExplanationTextNoNotificationsBinding;
|
|
||||||
|
|
||||||
private MainActivity mActivity;
|
|
||||||
|
|
||||||
private boolean listRefreshCalledThisFrame = false;
|
|
||||||
|
|
||||||
private TextView headerText;
|
|
||||||
private TextView noWifiHeader;
|
|
||||||
private TextView noNotificationsHeader;
|
|
||||||
private TextView notTrustedText;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
mActivity.getSupportActionBar().setTitle(R.string.pairing_title);
|
|
||||||
|
|
||||||
setHasOptionsMenu(true);
|
|
||||||
|
|
||||||
devicesListBinding = DevicesListBinding.inflate(inflater, container, false);
|
|
||||||
|
|
||||||
pairingExplanationNotTrustedBinding = PairingExplanationNotTrustedBinding.inflate(inflater);
|
|
||||||
notTrustedText = pairingExplanationNotTrustedBinding.getRoot();
|
|
||||||
notTrustedText.setOnClickListener(null);
|
|
||||||
notTrustedText.setOnLongClickListener(null);
|
|
||||||
|
|
||||||
pairingExplanationTextBinding = PairingExplanationTextBinding.inflate(inflater);
|
|
||||||
headerText = pairingExplanationTextBinding.getRoot();
|
|
||||||
headerText.setOnClickListener(null);
|
|
||||||
headerText.setOnLongClickListener(null);
|
|
||||||
|
|
||||||
pairingExplanationTextNoWifiBinding = PairingExplanationTextNoWifiBinding.inflate(inflater);
|
|
||||||
noWifiHeader = pairingExplanationTextNoWifiBinding.getRoot();
|
|
||||||
noWifiHeader.setOnClickListener(view -> startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)));
|
|
||||||
|
|
||||||
pairingExplanationTextNoNotificationsBinding = PairingExplanationTextNoNotificationsBinding.inflate(inflater);
|
|
||||||
noNotificationsHeader = pairingExplanationTextNoNotificationsBinding.getRoot();
|
|
||||||
noNotificationsHeader.setOnClickListener(view -> ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.POST_NOTIFICATIONS}, MainActivity.RESULT_NOTIFICATIONS_ENABLED));
|
|
||||||
noNotificationsHeader.setOnLongClickListener(view -> {
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
|
||||||
Uri uri = Uri.fromParts("package", requireContext().getPackageName(), null);
|
|
||||||
intent.setData(uri);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
devicesListBinding.devicesList.addHeaderView(headerText);
|
|
||||||
devicesListBinding.refreshListLayout.setOnRefreshListener(this::refreshDevicesAction);
|
|
||||||
|
|
||||||
return devicesListBinding.getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
|
|
||||||
// Configure focus order for Accessibility, for touchpads, and for TV remotes
|
|
||||||
// (allow focus of items in the device list)
|
|
||||||
devicesListBinding.devicesList.setItemsCanFocus(true);
|
|
||||||
WindowHelper.setupBottomPadding(devicesListBinding.devicesList);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyView() {
|
|
||||||
super.onDestroyView();
|
|
||||||
devicesListBinding = null;
|
|
||||||
pairingExplanationNotTrustedBinding = null;
|
|
||||||
pairingExplanationTextBinding = null;
|
|
||||||
pairingExplanationTextNoWifiBinding = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(@NonNull Context context) {
|
|
||||||
super.onAttach(context);
|
|
||||||
mActivity = ((MainActivity) getActivity());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshDevicesAction() {
|
|
||||||
BackgroundService.ForceRefreshConnections(requireContext());
|
|
||||||
|
|
||||||
devicesListBinding.refreshListLayout.setRefreshing(true);
|
|
||||||
devicesListBinding.refreshListLayout.postDelayed(() -> {
|
|
||||||
if (devicesListBinding != null) { // the view might be destroyed by now
|
|
||||||
devicesListBinding.refreshListLayout.setRefreshing(false);
|
|
||||||
}
|
|
||||||
}, 1500);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateDeviceList() {
|
|
||||||
if (!isAdded()) {
|
|
||||||
//Fragment is not attached to an activity. We will crash if we try to do anything here.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listRefreshCalledThisFrame) {
|
|
||||||
// This makes sure we don't try to call list.getFirstVisiblePosition()
|
|
||||||
// twice per frame, because the second time the list hasn't been drawn
|
|
||||||
// yet and it would always return 0.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
listRefreshCalledThisFrame = true;
|
|
||||||
|
|
||||||
//Check if we're on Wi-Fi/Local network. If we still see a device, don't do anything special
|
|
||||||
BackgroundService service = BackgroundService.getInstance();
|
|
||||||
if (service == null) {
|
|
||||||
updateConnectivityInfoHeader(true);
|
|
||||||
} else {
|
|
||||||
service.isConnectedToNonCellularNetwork().observe(this, this::updateConnectivityInfoHeader);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final ArrayList<ListAdapter.Item> items = new ArrayList<>();
|
|
||||||
|
|
||||||
SectionItem connectedSection;
|
|
||||||
Resources res = getResources();
|
|
||||||
|
|
||||||
connectedSection = new SectionItem(res.getString(R.string.category_connected_devices));
|
|
||||||
items.add(connectedSection);
|
|
||||||
|
|
||||||
Collection<Device> devices = KdeConnect.getInstance().getDevices().values();
|
|
||||||
for (Device device : devices) {
|
|
||||||
if (device.isReachable() && device.isPaired()) {
|
|
||||||
items.add(new PairingDeviceItem(device, PairingFragment.this));
|
|
||||||
connectedSection.isEmpty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (connectedSection.isEmpty) {
|
|
||||||
items.remove(items.size() - 1); //Remove connected devices section if empty
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionItem availableSection = new SectionItem(res.getString(R.string.category_not_paired_devices));
|
|
||||||
items.add(availableSection);
|
|
||||||
for (Device device : devices) {
|
|
||||||
if (device.isReachable() && !device.isPaired()) {
|
|
||||||
items.add(new PairingDeviceItem(device, PairingFragment.this));
|
|
||||||
availableSection.isEmpty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (availableSection.isEmpty && !connectedSection.isEmpty) {
|
|
||||||
items.remove(items.size() - 1); //Remove remembered devices section if empty
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionItem rememberedSection = new SectionItem(res.getString(R.string.category_remembered_devices));
|
|
||||||
items.add(rememberedSection);
|
|
||||||
for (Device device : devices) {
|
|
||||||
if (!device.isReachable() && device.isPaired()) {
|
|
||||||
items.add(new PairingDeviceItem(device, PairingFragment.this));
|
|
||||||
rememberedSection.isEmpty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rememberedSection.isEmpty) {
|
|
||||||
items.remove(items.size() - 1); //Remove remembered devices section if empty
|
|
||||||
}
|
|
||||||
|
|
||||||
//Store current scroll
|
|
||||||
int index = devicesListBinding.devicesList.getFirstVisiblePosition();
|
|
||||||
View v = devicesListBinding.devicesList.getChildAt(0);
|
|
||||||
int top = (v == null) ? 0 : (v.getTop() - devicesListBinding.devicesList.getPaddingTop());
|
|
||||||
|
|
||||||
devicesListBinding.devicesList.setAdapter(new ListAdapter(mActivity, items));
|
|
||||||
|
|
||||||
//Restore scroll
|
|
||||||
devicesListBinding.devicesList.setSelectionFromTop(index, top);
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
//Ignore: The activity was closed while we were trying to update it
|
|
||||||
} finally {
|
|
||||||
listRefreshCalledThisFrame = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateConnectivityInfoHeader(boolean isConnectedToNonCellularNetwork) {
|
|
||||||
Collection<Device> devices = KdeConnect.getInstance().getDevices().values();
|
|
||||||
boolean someDevicesReachable = false;
|
|
||||||
for (Device device : devices) {
|
|
||||||
if (device.isReachable()) {
|
|
||||||
someDevicesReachable = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasNotificationsPermission = ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED;
|
|
||||||
|
|
||||||
devicesListBinding.devicesList.removeHeaderView(headerText);
|
|
||||||
devicesListBinding.devicesList.removeHeaderView(noWifiHeader);
|
|
||||||
devicesListBinding.devicesList.removeHeaderView(notTrustedText);
|
|
||||||
devicesListBinding.devicesList.removeHeaderView(noNotificationsHeader);
|
|
||||||
|
|
||||||
if (someDevicesReachable || isConnectedToNonCellularNetwork) {
|
|
||||||
if (!hasNotificationsPermission) {
|
|
||||||
devicesListBinding.devicesList.addHeaderView(noNotificationsHeader);
|
|
||||||
} else if (TrustedNetworkHelper.isTrustedNetwork(getContext())) {
|
|
||||||
devicesListBinding.devicesList.addHeaderView(headerText);
|
|
||||||
} else {
|
|
||||||
devicesListBinding.devicesList.addHeaderView(notTrustedText);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
devicesListBinding.devicesList.addHeaderView(noWifiHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
KdeConnect.getInstance().addDeviceListChangedCallback("PairingFragment", () -> mActivity.runOnUiThread(this::updateDeviceList));
|
|
||||||
BackgroundService.ForceRefreshConnections(requireContext()); // force a network re-discover
|
|
||||||
updateDeviceList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
KdeConnect.getInstance().removeDeviceListChangedCallback("PairingFragment");
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pairingClicked(Device device) {
|
|
||||||
mActivity.onDeviceSelected(device.getDeviceId(), !device.isPaired() || !device.isReachable());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
switch (requestCode) {
|
|
||||||
case RESULT_PAIRING_SUCCESFUL:
|
|
||||||
if (resultCode == 1) {
|
|
||||||
String deviceId = data.getStringExtra("deviceId");
|
|
||||||
mActivity.onDeviceSelected(deviceId);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
|
|
||||||
inflater.inflate(R.menu.pairing, menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
|
||||||
int id = item.getItemId();
|
|
||||||
if (id == R.id.menu_refresh) {
|
|
||||||
refreshDevicesAction();
|
|
||||||
return true;
|
|
||||||
} else if (id == R.id.menu_custom_device_list) {
|
|
||||||
startActivity(new Intent(mActivity, CustomDevicesActivity.class));
|
|
||||||
return true;
|
|
||||||
} else if (id == R.id.menu_trusted_networks) {
|
|
||||||
startActivity(new Intent(mActivity, TrustedNetworksActivity.class));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
331
src/org/kde/kdeconnect/UserInterface/PairingFragment.kt
Normal file
331
src/org/kde/kdeconnect/UserInterface/PairingFragment.kt
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2014 Albert Vaca Cintora <albertvaka@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
package org.kde.kdeconnect.UserInterface
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.MenuProvider
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import org.kde.kdeconnect.BackgroundService.Companion.ForceRefreshConnections
|
||||||
|
import org.kde.kdeconnect.BackgroundService.Companion.instance
|
||||||
|
import org.kde.kdeconnect.Device
|
||||||
|
import org.kde.kdeconnect.Helpers.TrustedNetworkHelper.Companion.isTrustedNetwork
|
||||||
|
import org.kde.kdeconnect.KdeConnect
|
||||||
|
import org.kde.kdeconnect.UserInterface.List.ListAdapter
|
||||||
|
import org.kde.kdeconnect.UserInterface.List.PairingDeviceItem
|
||||||
|
import org.kde.kdeconnect.UserInterface.List.SectionItem
|
||||||
|
import org.kde.kdeconnect.base.BaseFragment
|
||||||
|
import org.kde.kdeconnect.extensions.setupBottomPadding
|
||||||
|
import org.kde.kdeconnect_tp.R
|
||||||
|
import org.kde.kdeconnect_tp.databinding.DevicesListBinding
|
||||||
|
import org.kde.kdeconnect_tp.databinding.PairingExplanationDuplicateNamesBinding
|
||||||
|
import org.kde.kdeconnect_tp.databinding.PairingExplanationNotTrustedBinding
|
||||||
|
import org.kde.kdeconnect_tp.databinding.PairingExplanationTextBinding
|
||||||
|
import org.kde.kdeconnect_tp.databinding.PairingExplanationTextNoNotificationsBinding
|
||||||
|
import org.kde.kdeconnect_tp.databinding.PairingExplanationTextNoWifiBinding
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The view that the user will see when there are no devices paired, or when you choose "add a new device" from the sidebar.
|
||||||
|
*/
|
||||||
|
class PairingFragment : BaseFragment<DevicesListBinding>() {
|
||||||
|
|
||||||
|
private var _textBinding: PairingExplanationTextBinding? = null
|
||||||
|
private var _duplicateNamesBinding: PairingExplanationDuplicateNamesBinding? = null
|
||||||
|
private var _textNoWifiBinding: PairingExplanationTextNoWifiBinding? = null
|
||||||
|
private var _textNoNotificationsBinding: PairingExplanationTextNoNotificationsBinding? = null
|
||||||
|
private var _textNotTrustedBinding: PairingExplanationNotTrustedBinding? = null
|
||||||
|
|
||||||
|
private val headerText: TextView get() = _textBinding!!.root
|
||||||
|
private val noWifiHeader: TextView get() = _textNoWifiBinding!!.root
|
||||||
|
private val duplicateNamesHeader: TextView get() = _duplicateNamesBinding!!.root
|
||||||
|
private val noNotificationsHeader: TextView get() = _textNoNotificationsBinding!!.root
|
||||||
|
private val notTrustedText: TextView get() = _textNotTrustedBinding!!.root
|
||||||
|
|
||||||
|
private var listRefreshCalledThisFrame = false
|
||||||
|
|
||||||
|
private val mainActivity by lazy { activity as MainActivity }
|
||||||
|
|
||||||
|
private val menuProvider = object : MenuProvider {
|
||||||
|
|
||||||
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
menuInflater.inflate(R.menu.pairing, menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
|
return when (menuItem.itemId) {
|
||||||
|
R.id.menu_refresh -> {
|
||||||
|
refreshDevicesAction()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.menu_custom_device_list -> {
|
||||||
|
startActivity(Intent(mainActivity, CustomDevicesActivity::class.java))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.menu_trusted_networks -> {
|
||||||
|
startActivity(Intent(mainActivity, TrustedNetworksActivity::class.java))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onInflateBinding(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): DevicesListBinding {
|
||||||
|
_textBinding = PairingExplanationTextBinding.inflate(inflater)
|
||||||
|
_duplicateNamesBinding = PairingExplanationDuplicateNamesBinding.inflate(inflater)
|
||||||
|
_textNoWifiBinding = PairingExplanationTextNoWifiBinding.inflate(inflater)
|
||||||
|
_textNoNotificationsBinding = PairingExplanationTextNoNotificationsBinding.inflate(inflater)
|
||||||
|
_textNotTrustedBinding = PairingExplanationNotTrustedBinding.inflate(inflater)
|
||||||
|
return DevicesListBinding.inflate(inflater, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
// Configure focus order for Accessibility, for touchpads, and for TV remotes
|
||||||
|
// (allow focus of items in the device list)
|
||||||
|
binding.devicesList.itemsCanFocus = true
|
||||||
|
binding.devicesList.setupBottomPadding()
|
||||||
|
|
||||||
|
mainActivity.supportActionBar?.setTitle(R.string.pairing_title)
|
||||||
|
mainActivity.addMenuProvider(menuProvider, viewLifecycleOwner, Lifecycle.State.RESUMED)
|
||||||
|
|
||||||
|
notTrustedText.setOnClickListener(null)
|
||||||
|
notTrustedText.setOnLongClickListener(null)
|
||||||
|
|
||||||
|
headerText.setOnClickListener(null)
|
||||||
|
headerText.setOnLongClickListener(null)
|
||||||
|
|
||||||
|
|
||||||
|
noWifiHeader.setOnClickListener {
|
||||||
|
startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
|
||||||
|
}
|
||||||
|
|
||||||
|
noNotificationsHeader.setOnClickListener {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
requireActivity(),
|
||||||
|
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
|
||||||
|
MainActivity.RESULT_NOTIFICATIONS_ENABLED
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
noNotificationsHeader.setOnLongClickListener {
|
||||||
|
val intent = Intent()
|
||||||
|
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||||
|
val uri = Uri.fromParts("package", requireContext().packageName, null)
|
||||||
|
intent.setData(uri)
|
||||||
|
startActivity(intent)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.devicesList.addHeaderView(headerText)
|
||||||
|
binding.refreshListLayout.setOnRefreshListener { this.refreshDevicesAction() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_textBinding = null
|
||||||
|
_textNoWifiBinding = null
|
||||||
|
_textNoNotificationsBinding = null
|
||||||
|
_textNotTrustedBinding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun refreshDevicesAction() {
|
||||||
|
ForceRefreshConnections(requireContext())
|
||||||
|
|
||||||
|
binding.refreshListLayout.isRefreshing = true
|
||||||
|
binding.refreshListLayout.postDelayed({
|
||||||
|
if (isResumed && !isDetached) { // the view might be destroyed by now
|
||||||
|
binding.refreshListLayout.isRefreshing = false
|
||||||
|
}
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDeviceList() {
|
||||||
|
if (!isAdded) {
|
||||||
|
//Fragment is not attached to an activity. We will crash if we try to do anything here.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listRefreshCalledThisFrame) {
|
||||||
|
// This makes sure we don't try to call list.getFirstVisiblePosition()
|
||||||
|
// twice per frame, because the second time the list hasn't been drawn
|
||||||
|
// yet and it would always return 0.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
listRefreshCalledThisFrame = true
|
||||||
|
|
||||||
|
binding.devicesList.removeHeaderView(duplicateNamesHeader)
|
||||||
|
|
||||||
|
//Check if we're on Wi-Fi/Local network. If we still see a device, don't do anything special
|
||||||
|
val service = instance
|
||||||
|
if (service == null) {
|
||||||
|
updateConnectivityInfoHeader(true)
|
||||||
|
} else {
|
||||||
|
service.isConnectedToNonCellularNetwork.observe(this, ::updateConnectivityInfoHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val items = ArrayList<ListAdapter.Item>()
|
||||||
|
|
||||||
|
val connectedSection: SectionItem
|
||||||
|
val res = resources
|
||||||
|
|
||||||
|
val moreDevices = KdeConnect.getInstance().devices.values
|
||||||
|
|
||||||
|
val seenNames = hashSetOf<String>()
|
||||||
|
for (device in moreDevices) {
|
||||||
|
if (seenNames.contains(device.name)) {
|
||||||
|
binding.devicesList.addHeaderView(duplicateNamesHeader)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
seenNames.add(device.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedSection = SectionItem(res.getString(R.string.category_connected_devices))
|
||||||
|
items.add(connectedSection)
|
||||||
|
|
||||||
|
val devices: Collection<Device> = KdeConnect.getInstance().devices.values
|
||||||
|
for (device in devices) {
|
||||||
|
if (device.isReachable && device.isPaired) {
|
||||||
|
items.add(PairingDeviceItem(device, ::deviceClicked))
|
||||||
|
connectedSection.isEmpty = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (connectedSection.isEmpty) {
|
||||||
|
items.removeAt(items.size - 1) //Remove connected devices section if empty
|
||||||
|
}
|
||||||
|
|
||||||
|
val availableSection = SectionItem(res.getString(R.string.category_not_paired_devices))
|
||||||
|
items.add(availableSection)
|
||||||
|
for (device in devices) {
|
||||||
|
if (device.isReachable && !device.isPaired) {
|
||||||
|
items.add(PairingDeviceItem(device, ::deviceClicked))
|
||||||
|
availableSection.isEmpty = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (availableSection.isEmpty && !connectedSection.isEmpty) {
|
||||||
|
items.removeAt(items.size - 1) //Remove remembered devices section if empty
|
||||||
|
}
|
||||||
|
|
||||||
|
val rememberedSection = SectionItem(res.getString(R.string.category_remembered_devices))
|
||||||
|
items.add(rememberedSection)
|
||||||
|
for (device in devices) {
|
||||||
|
if (!device.isReachable && device.isPaired) {
|
||||||
|
items.add(PairingDeviceItem(device, ::deviceClicked))
|
||||||
|
rememberedSection.isEmpty = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rememberedSection.isEmpty) {
|
||||||
|
items.removeAt(items.size - 1) //Remove remembered devices section if empty
|
||||||
|
}
|
||||||
|
|
||||||
|
//Store current scroll
|
||||||
|
val index = binding.devicesList.firstVisiblePosition
|
||||||
|
val v = binding.devicesList.getChildAt(0)
|
||||||
|
val top = if ((v == null)) 0 else (v.top - binding.devicesList.paddingTop)
|
||||||
|
|
||||||
|
binding.devicesList.adapter = ListAdapter(mainActivity, items)
|
||||||
|
|
||||||
|
//Restore scroll
|
||||||
|
binding.devicesList.setSelectionFromTop(index, top)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
//Ignore: The activity was closed while we were trying to update it
|
||||||
|
} finally {
|
||||||
|
listRefreshCalledThisFrame = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateConnectivityInfoHeader(isConnectedToNonCellularNetwork: Boolean) {
|
||||||
|
val devices: Collection<Device> = KdeConnect.getInstance().devices.values
|
||||||
|
var someDevicesReachable = false
|
||||||
|
for (device in devices) {
|
||||||
|
if (device.isReachable) {
|
||||||
|
someDevicesReachable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val hasNotificationsPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
ContextCompat.checkSelfPermission(
|
||||||
|
requireContext(),
|
||||||
|
Manifest.permission.POST_NOTIFICATIONS
|
||||||
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.devicesList.removeHeaderView(headerText)
|
||||||
|
binding.devicesList.removeHeaderView(noWifiHeader)
|
||||||
|
binding.devicesList.removeHeaderView(notTrustedText)
|
||||||
|
binding.devicesList.removeHeaderView(noNotificationsHeader)
|
||||||
|
|
||||||
|
if (someDevicesReachable || isConnectedToNonCellularNetwork) {
|
||||||
|
if (!hasNotificationsPermission) {
|
||||||
|
binding.devicesList.addHeaderView(noNotificationsHeader)
|
||||||
|
} else if (isTrustedNetwork(requireContext())) {
|
||||||
|
binding.devicesList.addHeaderView(headerText)
|
||||||
|
} else {
|
||||||
|
binding.devicesList.addHeaderView(notTrustedText)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.devicesList.addHeaderView(noWifiHeader)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
KdeConnect.getInstance().addDeviceListChangedCallback("PairingFragment") {
|
||||||
|
mainActivity.runOnUiThread { this.updateDeviceList() }
|
||||||
|
}
|
||||||
|
ForceRefreshConnections(mainActivity) // force a network re-discover
|
||||||
|
updateDeviceList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
KdeConnect.getInstance().removeDeviceListChangedCallback("PairingFragment")
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deviceClicked(device: Device) {
|
||||||
|
mainActivity.onDeviceSelected(device.deviceId, !device.isPaired || !device.isReachable)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
when (requestCode) {
|
||||||
|
RESULT_PAIRING_SUCCESFUL -> if (resultCode == 1) {
|
||||||
|
val deviceId = data?.getStringExtra("deviceId")
|
||||||
|
mainActivity.onDeviceSelected(deviceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val RESULT_PAIRING_SUCCESFUL = Activity.RESULT_FIRST_USER
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,7 @@ import org.kde.kdeconnect.BackgroundService
|
|||||||
import org.kde.kdeconnect.Helpers.CreateFileParams
|
import org.kde.kdeconnect.Helpers.CreateFileParams
|
||||||
import org.kde.kdeconnect.Helpers.CreateFileResultContract
|
import org.kde.kdeconnect.Helpers.CreateFileResultContract
|
||||||
import org.kde.kdeconnect.Helpers.DeviceHelper
|
import org.kde.kdeconnect.Helpers.DeviceHelper
|
||||||
import org.kde.kdeconnect.Helpers.DeviceHelper.filterName
|
import org.kde.kdeconnect.Helpers.DeviceHelper.filterInvalidCharactersFromDeviceName
|
||||||
import org.kde.kdeconnect.Helpers.DeviceHelper.getDeviceName
|
import org.kde.kdeconnect.Helpers.DeviceHelper.getDeviceName
|
||||||
import org.kde.kdeconnect.Helpers.NotificationHelper
|
import org.kde.kdeconnect.Helpers.NotificationHelper
|
||||||
import org.kde.kdeconnect.UserInterface.ThemeUtil.applyTheme
|
import org.kde.kdeconnect.UserInterface.ThemeUtil.applyTheme
|
||||||
@ -64,7 +64,6 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
persistentNotificationPref(context),
|
persistentNotificationPref(context),
|
||||||
trustedNetworkPref(context),
|
trustedNetworkPref(context),
|
||||||
devicesByIpPref(context),
|
devicesByIpPref(context),
|
||||||
udpBroadcastPref(context),
|
|
||||||
bluetoothSupportPref(context),
|
bluetoothSupportPref(context),
|
||||||
exportLogsPref(context),
|
exportLogsPref(context),
|
||||||
moreSettingsPref(context),
|
moreSettingsPref(context),
|
||||||
@ -84,7 +83,9 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
setOnBindEditTextListener(EditText::setSingleLine)
|
setOnBindEditTextListener(EditText::setSingleLine)
|
||||||
setOnBindEditTextListener { editText: EditText ->
|
setOnBindEditTextListener { editText: EditText ->
|
||||||
editText.filters = arrayOf(
|
editText.filters = arrayOf(
|
||||||
InputFilter { source: CharSequence, start: Int, end: Int, _: Spanned?, _: Int, _: Int -> filterName(source.subSequence(start, end).toString()) },
|
InputFilter { source: CharSequence, start: Int, end: Int, _: Spanned?, _: Int, _: Int ->
|
||||||
|
filterInvalidCharactersFromDeviceName(source.subSequence(start, end).toString())
|
||||||
|
},
|
||||||
LengthFilter(DeviceHelper.MAX_DEVICE_NAME_LENGTH),
|
LengthFilter(DeviceHelper.MAX_DEVICE_NAME_LENGTH),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -200,12 +201,6 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun udpBroadcastPref(context: Context) = SwitchPreference(context).apply {
|
|
||||||
setDefaultValue(true)
|
|
||||||
key = KEY_UDP_BROADCAST_ENABLED
|
|
||||||
setTitle(R.string.enable_udp_broadcast)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bluetoothSupportPref(context: Context) = SwitchPreference(context).apply {
|
private fun bluetoothSupportPref(context: Context) = SwitchPreference(context).apply {
|
||||||
setDefaultValue(false)
|
setDefaultValue(false)
|
||||||
key = KEY_BLUETOOTH_ENABLED
|
key = KEY_BLUETOOTH_ENABLED
|
||||||
@ -243,8 +238,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
) { uri: Uri? ->
|
) { uri: Uri? ->
|
||||||
val output = uri?.let { context?.contentResolver?.openOutputStream(uri) } ?: return@registerForActivityResult
|
val output = uri?.let { context?.contentResolver?.openOutputStream(uri) } ?: return@registerForActivityResult
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val pid = android.os.Process.myPid()
|
val process = Runtime.getRuntime().exec(arrayOf("logcat", "-d"))
|
||||||
val process = Runtime.getRuntime().exec(arrayOf("logcat", "-d", "--pid=$pid"))
|
|
||||||
val reader = InputStreamReader(process.inputStream)
|
val reader = InputStreamReader(process.inputStream)
|
||||||
output.use {
|
output.use {
|
||||||
it.write("KDE Connect ${BuildConfig.VERSION_NAME}\n".toByteArray(Charsets.UTF_8))
|
it.write("KDE Connect ${BuildConfig.VERSION_NAME}\n".toByteArray(Charsets.UTF_8))
|
||||||
@ -262,7 +256,6 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val KEY_UDP_BROADCAST_ENABLED: String = "udp_broadcast_enabled"
|
|
||||||
const val KEY_BLUETOOTH_ENABLED: String = "bluetooth_enabled"
|
const val KEY_BLUETOOTH_ENABLED: String = "bluetooth_enabled"
|
||||||
const val KEY_APP_THEME: String = "theme_pref"
|
const val KEY_APP_THEME: String = "theme_pref"
|
||||||
}
|
}
|
||||||
|
36
src/org/kde/kdeconnect/base/BaseFragment.kt
Normal file
36
src/org/kde/kdeconnect/base/BaseFragment.kt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Mash Kyrielight <fiepi@live.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
package org.kde.kdeconnect.base
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
|
||||||
|
abstract class BaseFragment<VB: ViewBinding> : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: VB? = null
|
||||||
|
|
||||||
|
protected val binding get() = _binding!!
|
||||||
|
|
||||||
|
abstract fun onInflateBinding(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): VB
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
_binding = onInflateBinding(inflater, container, savedInstanceState)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
}
|
23
src/org/kde/kdeconnect/extensions/Bundle.kt
Normal file
23
src/org/kde/kdeconnect/extensions/Bundle.kt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Mash Kyrielight <fiepi@live.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
package org.kde.kdeconnect.extensions
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Parcelable
|
||||||
|
import androidx.core.os.BundleCompat
|
||||||
|
|
||||||
|
|
||||||
|
inline fun <reified T> Bundle.getParcelableCompat(key: String): T? {
|
||||||
|
return BundleCompat.getParcelable(this, key, T::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T> Bundle.getParcelableArrayListCompat(key: String): ArrayList<T>? {
|
||||||
|
return BundleCompat.getParcelableArrayList(this, key, T::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T: Parcelable> Bundle.getParcelableArrayCompat(key: String): Array<Parcelable>? {
|
||||||
|
return BundleCompat.getParcelableArray(this, key, T::class.java)
|
||||||
|
}
|
23
src/org/kde/kdeconnect/extensions/Intent.kt
Normal file
23
src/org/kde/kdeconnect/extensions/Intent.kt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Mash Kyrielight <fiepi@live.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
package org.kde.kdeconnect.extensions
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Parcelable
|
||||||
|
import androidx.core.content.IntentCompat
|
||||||
|
|
||||||
|
|
||||||
|
inline fun <reified T> Intent.getParcelableCompat(key: String): T? {
|
||||||
|
return IntentCompat.getParcelableExtra(this, key, T::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T> Intent.getParcelableArrayListCompat(key: String): ArrayList<T>? {
|
||||||
|
return IntentCompat.getParcelableArrayListExtra(this, key, T::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T: Parcelable> Intent.getParcelableArrayCompat(key: String): Array<Parcelable>? {
|
||||||
|
return IntentCompat.getParcelableArrayExtra(this, key, T::class.java)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user