2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-09-01 22:55:10 +00:00

Compare commits

...

57 Commits

Author SHA1 Message Date
Albert Vaca Cintora
36636406b0 Require Android 6 (API 32) 2024-05-12 16:25:11 +02:00
Albert Vaca Cintora
862bd43c63 Fix warning 2024-05-12 16:06:38 +02:00
Albert Vaca Cintora
a82b6bbae0 Remove some depreacated calls in EasterEggActivity 2024-05-12 16:03:27 +02:00
Albert Vaca Cintora
2803024046 Bump Gradle version 2024-05-12 15:50:19 +02:00
l10n daemon script
01bc5490f2 GIT_SILENT Sync po/docbooks with svn 2024-05-12 02:38:29 +00:00
l10n daemon script
994a71f7cd GIT_SILENT made messages (after extraction) 2024-05-12 01:56:34 +00:00
l10n daemon script
0eb79e0053 GIT_SILENT made messages (after extraction) 2024-05-09 01:51:50 +00:00
l10n daemon script
00387ca01d GIT_SILENT made messages (after extraction) 2024-05-08 01:52:04 +00:00
l10n daemon script
7dba06cbb6 GIT_SILENT made messages (after extraction) 2024-05-07 01:44:25 +00:00
l10n daemon script
ae60cbbf74 GIT_SILENT Sync po/docbooks with svn 2024-05-06 02:30:22 +00:00
l10n daemon script
0d4951f152 GIT_SILENT made messages (after extraction) 2024-05-05 01:44:14 +00:00
l10n daemon script
5fb87d598e GIT_SILENT Sync po/docbooks with svn 2024-05-04 02:38:12 +00:00
l10n daemon script
b65c1aae8f GIT_SILENT made messages (after extraction) 2024-05-04 01:56:54 +00:00
Albert Vaca Cintora
3d166e6d4b Offer to "continue playing" media on this device after pausing
Based on the MR !249

Co-authored-by: Alex Gravenor <blazingkin@gmail.com>
2024-05-02 16:18:33 +02:00
Albert Vaca Cintora
411bcc3960 Added a comment 2024-05-02 12:19:08 +02:00
Albert Vaca Cintora
eb5719d9a2 Improve security of SFTP server against timing attacks
Use a constant time string comparison for password auth.
2024-05-02 10:13:19 +00:00
Albert Vaca Cintora
37246f8575 Fix not loading any plugins when pairing with MacOS 2024-05-02 10:12:13 +00:00
l10n daemon script
6728ca472c GIT_SILENT made messages (after extraction) 2024-05-01 01:41:30 +00:00
l10n daemon script
d19595fc3b GIT_SILENT made messages (after extraction) 2024-04-24 01:55:57 +00:00
l10n daemon script
f3c23c5b8e GIT_SILENT Sync po/docbooks with svn 2024-04-22 02:41:36 +00:00
l10n daemon script
ce4f6ca9ef GIT_SILENT made messages (after extraction) 2024-04-22 01:54:24 +00:00
Rob Emery
f21fe2eb1b Removing accidental newline
Signed-off-by: Rob Emery <git@mintsoft.net>
2024-04-21 21:18:00 +00:00
Rob Emery
105a733028 When we are denied bluetooth, we can switch it off as well so it doesn't try again
Signed-off-by: Rob Emery <git@mintsoft.net>
2024-04-21 21:18:00 +00:00
Rob Emery
9df15bf9ca If the user revokes the "nearby devices" permission from KDEConnect, previously this
would throw a SecurityException and cause the app to crash. It will now ignore this
condition and keep using the other connection methods (i.e. LANProvider). Toggling the
Enable Bluetooth option in the settings will fix the permissions

Signed-off-by: Rob Emery <git@mintsoft.net>
2024-04-21 21:18:00 +00:00
l10n daemon script
d53fcdd546 GIT_SILENT Sync po/docbooks with svn 2024-04-21 02:27:21 +00:00
l10n daemon script
fa125ed0ac GIT_SILENT made messages (after extraction) 2024-04-21 01:43:30 +00:00
l10n daemon script
28ebd94517 GIT_SILENT Sync po/docbooks with svn 2024-04-20 02:29:18 +00:00
l10n daemon script
d0efb70bcf GIT_SILENT made messages (after extraction) 2024-04-20 01:44:45 +00:00
l10n daemon script
5441b0b5d6 GIT_SILENT made messages (after extraction) 2024-04-19 01:46:55 +00:00
l10n daemon script
0a354695cc GIT_SILENT made messages (after extraction) 2024-04-18 01:36:27 +00:00
l10n daemon script
4bbe6c2e55 GIT_SILENT Sync po/docbooks with svn 2024-04-17 02:30:54 +00:00
Vala Zadeh
80106ccb81 Add option to cache URLs shared to unreachable devices 2024-04-16 07:10:42 +00:00
Albert Vaca Cintora
fb327ae35e Fixes from code review 2024-04-15 18:22:26 +02:00
Albert Vaca Cintora
ffa0049c09 Remove colors from theme
We had a mix of specific colors and theme-based Material You colors.
This aims to remove any hardcoded color so the app only uses the colors
from the current theme.
2024-04-15 18:01:54 +02:00
l10n daemon script
afb45416b1 GIT_SILENT Sync po/docbooks with svn 2024-04-15 02:21:17 +00:00
ShellWen Chen
295dc7b42a refactor: migrate DevicePacketQueue to Kotlin Coroutine 2024-04-14 23:04:55 +00:00
l10n daemon script
0de545773d GIT_SILENT Sync po/docbooks with svn 2024-04-14 02:22:27 +00:00
l10n daemon script
7a0e38445b GIT_SILENT Sync po/docbooks with svn 2024-04-13 02:28:20 +00:00
Albert Vaca Cintora
40b1cdabc8 Safer gitignore 2024-04-12 09:25:44 +02:00
Albert Vaca Cintora
28b1e7d96a Gitignore release dir 2024-04-12 09:25:44 +02:00
Albert Vaca Cintora
2f922f282a Bump deps 2024-04-12 09:25:44 +02:00
Albert Vaca Cintora
6d431c5797 Add packet type information when an OOM happens 2024-04-12 09:25:44 +02:00
l10n daemon script
175ee9b011 GIT_SILENT Sync po/docbooks with svn 2024-04-12 02:26:43 +00:00
l10n daemon script
8a9ac32882 GIT_SILENT made messages (after extraction) 2024-04-12 01:42:12 +00:00
Albert Vaca Cintora
9065867c4a Release 1.30.1 2024-04-11 23:45:56 +02:00
Albert Vaca Cintora
47e0cca3c6 Migrate SMSHelper to Kotlin 2024-04-11 21:17:02 +00:00
Albert Vaca Cintora
db33b13343 Fix crash due to passing null as a non-null arg 2024-04-11 22:55:37 +02:00
Albert Vaca Cintora
45dfbae63f Do not make unnecessary stuff public in NetworkPacket 2024-04-11 22:48:23 +02:00
l10n daemon script
8268358b5a GIT_SILENT Sync po/docbooks with svn 2024-04-11 02:27:34 +00:00
l10n daemon script
3aa7d249b3 GIT_SILENT Sync po/docbooks with svn 2024-04-10 02:29:45 +00:00
l10n daemon script
b3f96b136c GIT_SILENT Sync po/docbooks with svn 2024-04-09 02:28:48 +00:00
Albert Vaca Cintora
e2196b35fe Fix remote mouse: you can drag but not drop in Plasma Wayland 2024-04-08 21:00:06 +00:00
l10n daemon script
6c7700f6c8 GIT_SILENT Sync po/docbooks with svn 2024-04-08 02:28:11 +00:00
ShellWen Chen
7f67a80bda refactor: migrate PairingHandler to Kotlin 2024-04-07 18:16:39 +00:00
ShellWen Chen
5ce0c1ccf8 refactor: migrate AppsHelper to Kotlin
Remove `appIconLookup()` as not used
2024-04-07 13:52:03 +00:00
l10n daemon script
c2e1a93f68 GIT_SILENT Sync po/docbooks with svn 2024-04-07 02:28:33 +00:00
ShellWen Chen
3e6329c64e refactor: migrate ThemeUtil to Kotlin
Migrate `ThemeUtil` into Kotlin. It was already tested.
2024-04-06 22:17:54 +00:00
116 changed files with 2177 additions and 2192 deletions

17
.gitignore vendored
View File

@@ -1,14 +1,15 @@
local.properties
.gradle/
.idea/
out/
gen/
bin/
build/
target/
classes/
/.gradle/
/.idea/
/out/
/gen/
/bin/
/build/
/target/
/classes/
*.iml
*.keystore
!debug.keystore
.directory
GPUCache/
/release/

View File

@@ -8,8 +8,8 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="13000"
android:versionName="1.30.0">
android:versionCode="13001"
android:versionName="1.30.1">
<uses-feature
android:name="android.hardware.telephony"

View File

@@ -43,7 +43,7 @@ android {
namespace = "org.kde.kdeconnect_tp"
compileSdk = 34
defaultConfig {
minSdk = 21
minSdk = 23
targetSdk = 33
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}

View File

@@ -0,0 +1,16 @@
1.30.1
* Fixes recently introduced crashes
1.30
* Added Bluetooth support (beta)
* Improved device controls
* Added scroll sensitivity option to remote input
* Accessibility improvements
1.29
* Added MDNS device discovery
* Fixed crash opening the Run Command widget settings
* Added more fine-grained notification channels
* Added a confirmation before copying contacts
* Long-tapping the "Send clipboard" quick settings tile now opens the app
* Removed the photo plugin

View File

@@ -1 +1 @@
KDE Connect intègre votre téléphone et votre ordinateur.
KDEConnect intègre votre téléphone et votre ordinateur.

View File

@@ -1,20 +1,20 @@
[versions]
activityCompose = "1.8.2"
androidDesugarJdkLibs = "2.0.4"
androidGradlePlugin = "8.3.1"
androidGradlePlugin = "8.4.0"
androidSmsmms = "kdeconnect-1-21-0"
appcompat = "1.6.1"
bcpkixJdk15on = "1.70"
classindex = "3.13"
commonsCollections4 = "4.4"
commonsIo = "2.16.0"
commonsIo = "2.16.1"
commonsLang3 = "3.14.0"
constraintlayoutCompose = "1.0.1"
compose-compiler = "1.5.11"
coreKtx = "1.12.0"
disklrucache = "2.0.2"
documentfile = "1.0.1"
gradle = "8.3.1"
gradle = "8.4.0"
gridlayout = "1.0.0"
jsonassert = "1.5.1"
junit = "4.13.2"

View File

@@ -63,7 +63,7 @@ msgstr ""
"- Obteniu les notificacions de tocades entrants i missatges a l'ordinador.\n"
"- Ratolí tàctil virtual: utilitzeu la pantalla del telèfon com a ratolí "
"tàctil de l'ordinador.\n"
"- Sincronització de notificacions: accediu a les notificacions del telèfon "
"- Sincronitzeu les notificacions: accediu a les notificacions del telèfon "
"des de l'ordinador i contesteu els missatges.\n"
"- Control remot multimèdia: utilitzeu el telèfon com a control remot dels "
"reproductors multimèdia Linux.\n"

View File

@@ -1,19 +1,19 @@
# Xavier Besnard <xavier.besnard@kde.org>, 2023.
# SPDX-FileCopyrightText: 2023, 2024 Xavier Besnard <xavier.besnard@kde.org>
#. extracted from ./metadata/android/en-US/short_description.txt
msgid ""
msgstr ""
"Project-Id-Version: kdeconnect-android-store-short\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
"PO-Revision-Date: 2023-06-27 08:54+0200\n"
"Last-Translator: Xavier BESNARD <xavier.besnard@neuf.fr>\n"
"Language-Team: French <kde-francophone@kde.org>\n"
"PO-Revision-Date: 2024-04-25 14:41+0200\n"
"Last-Translator: Xavier Besnard <xavier.besnard@kde.org>\n"
"Language-Team: French <French <kde-francophone@kde.org>>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Lokalize 23.04.2\n"
"X-Generator: Lokalize 23.08.5\n"
msgid "KDE Connect integrates your smartphone and computer"
msgstr "KDE Connect intègre votre téléphone et votre ordinateur."
msgstr "KDEConnect intègre votre téléphone et votre ordinateur."

View File

@@ -1,4 +1,4 @@
# Stefan Asserhäll <stefan.asserhall@bredband.net>, 2023.
# Stefan Asserhäll <stefan.asserhall@gmail.com>, 2023.
#. extracted from ./metadata/android/en-US/full_description.txt
msgid ""
msgstr ""
@@ -6,7 +6,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
"PO-Revision-Date: 2023-09-29 22:08+0200\n"
"Last-Translator: Stefan Asserhäll <stefan.asserhall@bredband.net>\n"
"Last-Translator: Stefan Asserhäll <stefan.asserhall@gmail.com>\n"
"Language-Team: Swedish <kde-i18n-doc@kde.org>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"

View File

@@ -1,4 +1,4 @@
# Stefan Asserhäll <stefan.asserhall@bredband.net>, 2023.
# Stefan Asserhäll <stefan.asserhall@gmail.com>, 2023.
#. extracted from ./metadata/android/en-US/short_description.txt
msgid ""
msgstr ""
@@ -6,7 +6,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
"PO-Revision-Date: 2023-07-31 08:17+0200\n"
"Last-Translator: Stefan Asserhäll <stefan.asserhall@bredband.net>\n"
"Last-Translator: Stefan Asserhäll <stefan.asserhall@gmail.com>\n"
"Language-Team: Swedish <kde-i18n-doc@kde.org>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"

View File

@@ -4,7 +4,7 @@ msgstr ""
"Project-Id-Version: kdeorg\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
"PO-Revision-Date: 2024-04-04 19:52\n"
"PO-Revision-Date: 2024-04-21 04:51\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"

View File

@@ -4,7 +4,7 @@ msgstr ""
"Project-Id-Version: kdeorg\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-05 12:31+0000\n"
"PO-Revision-Date: 2024-04-04 19:52\n"
"PO-Revision-Date: 2024-04-21 04:51\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primary" android:state_checked="true" />
<item android:drawable="@color/darkStatusBarBackground" android:state_checked="false" />
</selector>

View File

@@ -6,7 +6,7 @@
android:viewportHeight="108">
<path
android:pathData="m0,0h108v108h-108z"
android:fillColor="@color/accent"/>
android:fillColor="@color/launcher_background"/>
<path
android:pathData="m0,0h108v108h-108z"
android:strokeAlpha="0.2"

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/accent" />
<solid android:color="?colorAccent" />
<corners android:bottomRightRadius="2dip"
android:bottomLeftRadius="2dip"
android:topRightRadius="2dip"
android:topLeftRadius="2dip"/>
</shape>
</shape>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:color="@color/primary" />
<item android:state_enabled="false" android:color="@color/disabled_grey" />
</selector>

View File

@@ -1,4 +1,8 @@
<vector android:height="24dp" android:viewportHeight="48"
android:viewportWidth="48" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#fcfcfc" android:pathData="m26.8172,6.058 l-5.9774,0.5722v24.6133l5.9142,-0.8904v-10.494l7.9499,11.6392 6.2324,-1.972 -8.1405,-11.1935 8.2042,-10.5576 -6.3594,-1.4621 -7.8865,10.5572zM13.2678,12.0558c-0.0675,0.0071 -0.1327,0.0369 -0.1834,0.0877l-2.346,2.3456c-0.0986,0.0989 -0.1172,0.2523 -0.0445,0.3721l2.7467,4.5238c-0.4872,0.819 -0.8776,1.7021 -1.1567,2.6336l-5.0426,1.0489c-0.1403,0.0291 -0.2414,0.1534 -0.2414,0.2973v3.3173c0,0.1403 0.096,0.2618 0.2312,0.2945l4.8943,1.1963c0.261,1.0789 0.6654,2.1016 1.2,3.0416l-2.833,4.32c-0.079,0.1208 -0.0625,0.2798 0.0396,0.3815l2.3452,2.3456c0.0986,0.0984 0.2526,0.1176 0.3729,0.0454l4.4393,-2.6961c0.872,0.5032 1.8124,0.8992 2.8063,1.1677l1.0358,4.98c0.0291,0.1412 0.1539,0.2414 0.2969,0.2414h3.3177c0.1395,0 0.2612,-0.0952 0.2945,-0.232l1.22,-4.9903c1.0246,-0.2765 1.9935,-0.6886 2.8869,-1.2147l4.3747,2.8684c0.1203,0.0792 0.2794,0.0633 0.3815,-0.0387l2.346,-2.3456c0.0992,-0.0992 0.117,-0.2526 0.0441,-0.3721l-1.597,-2.632 -0.5167,0.1634c-0.0753,0.0238 -0.1575,-0.0043 -0.2018,-0.0699 0,0 -1.0186,-1.4912 -2.3342,-3.4167 -1.5727,3.0779 -4.7723,5.1864 -8.4672,5.1864 -5.2496,0 -9.5055,-4.2561 -9.5055,-9.5059 0,-3.8619 2.3035,-7.1832 5.6102,-8.6711v-2.4523c-0.6018,0.2105 -1.1836,0.4644 -1.7362,0.7654 -0.0004,-0.0004 -0.0008,-0.0014 -0.0024,-0.0028l-4.4777,-2.9368c-0.0603,-0.0394 -0.1302,-0.0551 -0.1977,-0.0482z"/>
android:viewportWidth="48" android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="m26.8172,6.058 l-5.9774,0.5722v24.6133l5.9142,-0.8904v-10.494l7.9499,11.6392 6.2324,-1.972 -8.1405,-11.1935 8.2042,-10.5576 -6.3594,-1.4621 -7.8865,10.5572zM13.2678,12.0558c-0.0675,0.0071 -0.1327,0.0369 -0.1834,0.0877l-2.346,2.3456c-0.0986,0.0989 -0.1172,0.2523 -0.0445,0.3721l2.7467,4.5238c-0.4872,0.819 -0.8776,1.7021 -1.1567,2.6336l-5.0426,1.0489c-0.1403,0.0291 -0.2414,0.1534 -0.2414,0.2973v3.3173c0,0.1403 0.096,0.2618 0.2312,0.2945l4.8943,1.1963c0.261,1.0789 0.6654,2.1016 1.2,3.0416l-2.833,4.32c-0.079,0.1208 -0.0625,0.2798 0.0396,0.3815l2.3452,2.3456c0.0986,0.0984 0.2526,0.1176 0.3729,0.0454l4.4393,-2.6961c0.872,0.5032 1.8124,0.8992 2.8063,1.1677l1.0358,4.98c0.0291,0.1412 0.1539,0.2414 0.2969,0.2414h3.3177c0.1395,0 0.2612,-0.0952 0.2945,-0.232l1.22,-4.9903c1.0246,-0.2765 1.9935,-0.6886 2.8869,-1.2147l4.3747,2.8684c0.1203,0.0792 0.2794,0.0633 0.3815,-0.0387l2.346,-2.3456c0.0992,-0.0992 0.117,-0.2526 0.0441,-0.3721l-1.597,-2.632 -0.5167,0.1634c-0.0753,0.0238 -0.1575,-0.0043 -0.2018,-0.0699 0,0 -1.0186,-1.4912 -2.3342,-3.4167 -1.5727,3.0779 -4.7723,5.1864 -8.4672,5.1864 -5.2496,0 -9.5055,-4.2561 -9.5055,-9.5059 0,-3.8619 2.3035,-7.1832 5.6102,-8.6711v-2.4523c-0.6018,0.2105 -1.1836,0.4644 -1.7362,0.7654 -0.0004,-0.0004 -0.0008,-0.0014 -0.0024,-0.0028l-4.4777,-2.9368c-0.0603,-0.0394 -0.1302,-0.0551 -0.1977,-0.0482z"/>
</vector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primary" android:state_checked="true" />
<item android:drawable="@color/background_floating_material_light" android:state_checked="false" />
</selector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primary" android:state_checked="true" />
<item android:drawable="@color/darkStatusBarBackground" android:state_checked="false" />
</selector>

View File

@@ -56,7 +56,6 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:contentDescription="@string/visit_contributors_homepage"
android:src="@drawable/ic_baseline_web_24"
android:visibility="gone"
app:tint="@color/text_color"
tools:visibility="visible" />
</LinearLayout>

View File

@@ -38,8 +38,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:text="@string/kde_be_free"
android:textAppearance="?attr/textAppearanceHeadline6"
app:drawableLeftCompat="@drawable/ic_kde_48dp"
app:drawableStartCompat="@drawable/ic_kde_48dp"
app:drawableTint="@color/text_color" />
app:drawableStartCompat="@drawable/ic_kde_48dp"/>
<com.google.android.material.card.MaterialCardView
xmlns:card_view="https://schemas.android.com/apk/res-auto"

View File

@@ -27,7 +27,6 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:fadingEdge="horizontal"
android:singleLine="true"
android:text=""
android:textColor="@color/text_color"
tools:text="Item entry"
android:textAppearance="?android:attr/textAppearanceMedium" />

View File

@@ -15,7 +15,6 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
app:cardCornerRadius="8dp"
app:cardElevation="0dp"
app:contentPadding="8dp"
app:strokeColor="@color/card_stroke_color"
app:strokeWidth="1dp">
<LinearLayout
@@ -50,8 +49,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:background="@android:color/transparent"
android:contentDescription="@string/mute"
android:scaleType="fitXY"
android:src="@drawable/ic_volume_black"
app:tint="?attr/colorHighContrast" />
android:src="@drawable/ic_volume_black"/>
<SeekBar
android:id="@+id/systemvolume_seek"

View File

@@ -198,8 +198,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:layout_weight="0"
android:contentDescription="@string/mpris_volume"
android:maxWidth="30dip"
android:src="@drawable/ic_volume_black"
app:tint="?attr/colorHighContrast" />
android:src="@drawable/ic_volume_black"/>
<SeekBar

View File

@@ -65,7 +65,7 @@
android:layout_width="1dp"
android:layout_height="32dp"
android:layout_gravity="center"
android:background="?divider"
android:background="?colorPrimary"
/>
<!-- Preference will place its actual preference widget here. -->
<LinearLayout
@@ -76,6 +76,5 @@
android:gravity="center"
android:padding="16dp"
android:orientation="vertical"
tools:background="@color/primary"
/>
</LinearLayout>

View File

@@ -30,9 +30,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:importantForAccessibility="no"
android:paddingEnd="8dip"
android:paddingStart="0dip"
android:src="@drawable/ic_error_outline_48dp"
app:tint="?attr/colorHighContrast"
tools:ignore="UnusedAttribute" />
android:src="@drawable/ic_error_outline_48dp" />
<TextView
android:id="@+id/not_reachable_message"

View File

@@ -9,15 +9,15 @@ 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"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:background="@color/activity_background"
android:theme="@style/KdeConnectTheme"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="?colorSurface"
tools:ignore="RtlSymmetry">
<LinearLayout
android:id="@+id/widget_title_wrapper"
android:background="@color/on_secondary"
android:background="?colorSecondary"
android:gravity="center_vertical|start"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -28,8 +28,8 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:paddingEnd="6dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="@color/text_color"
android:src="@drawable/ic_kde_24dp"
android:tint="?attr/colorOnSecondary"
android:importantForAccessibility="no"
tools:ignore="UseAppTint"/> <!-- can't use app:tint in RemoteView -->
@@ -38,10 +38,10 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:textColor="@color/text_color"
android:text="@string/kde_connect"
android:fadingEdge="horizontal"
android:singleLine="true"
android:textColor="?attr/colorOnSecondary"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>

View File

@@ -115,7 +115,6 @@
<item>دقيقة واحدة</item>
<item>دقيقتان</item>
</string-array>
<string name="share_to">شارك مع...</string>
<string name="protocol_version_newer">يستخدم هذا الجهاز إصدار ميفاق أحدث</string>
<string name="plugin_settings_with_name">إعدادات %s</string>
<string name="invalid_device_name">اسم جهاز غير صالح</string>

View File

@@ -185,7 +185,6 @@
<string name="mpris_notifications_explanation">Bildirişlər çəkməcəsində məsafədəki medianı göstərmək üçün bildiriş icazələri lazımdır</string>
<string name="mpris_notification_settings_title">Media idarəetmə bildirişlərini göstərmək</string>
<string name="mpris_notification_settings_summary">KDE Connect açmadan media oynadıcınızın idarəsinə icazə vermək</string>
<string name="share_to">Paylaşmaq...</string>
<string name="protocol_version_newer">Bu cihaz yeni protokol versiyası istifadə edir</string>
<string name="plugin_settings_with_name">%s ayarları</string>
<string name="invalid_device_name">Səhv cihaz adı</string>

View File

@@ -191,6 +191,8 @@
<string name="mpris_notification_settings_title">Показване на известие за управление на медиите</string>
<string name="mpris_notification_settings_summary">Разрешаване на управлението на медийните плейъри, без да отваряте KDE Connect</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="protocol_version_newer">Това устройство използва по-нова версия на протокола</string>
<string name="plugin_settings_with_name">%s настройки</string>
<string name="invalid_device_name">Невалидно име на устройство</string>
@@ -227,7 +229,7 @@
<string name="sftp_no_storage_locations_configured">Няма конфигурирани места за съхранение</string>
<string name="sftp_saf_permission_explanation">За да получите достъп до файлове от разстояние, трябва да конфигурирате местата за съхранение</string>
<string name="sftp_manage_storage_permission_explanation">За да разрешите отдалечен достъп до файловете на това устройство, трябва да разрешите KDE Connect да управлява хранилището.</string>
<string name="no_players_connected">Не са открити играчи</string>
<string name="no_players_connected">Няма възпроизвеждане на медия</string>
<string name="send_files">Изпращане на файлове</string>
<string name="block_notification_contents">Блокиране на съдържанието в известията</string>
<string name="block_notification_images">Блокиране на изображения в известията</string>
@@ -327,8 +329,8 @@
<string name="location_permission_needed_title">Изисква се разрешение</string>
<string name="location_permission_needed_desc">KDE Connect се нуждае от разрешение за местоположението във фонов режим, за да познава WiFi към която сте свързани, дори когато приложението е във фонов режим. Това е така, защото имената на WiFi мрежите около вас могат да бъдат използвани за намиране на вашето местоположение, дори когато KDE Connect не прави това.</string>
<string name="clipboard_android_x_incompat">Android 10 премахна достъпа до клипборда за всички приложения. Тази приставка ще бъде деактивирана.</string>
<string name="mpris_open_url">Продължете да играете тук</string>
<string name="cant_open_url">Не мога да отворя URL адреса, за да продължа играта</string>
<string name="mpris_open_url">Продължаване на възпроизвеждането тук</string>
<string name="cant_open_url">Не може да се отвори URL адреса, за да се продължи възпроизвежданете</string>
<string name="bigscreen_home">Домашен адрес</string>
<string name="bigscreen_up">Преместване нагоре</string>
<string name="bigscreen_left">Ляво</string>
@@ -410,4 +412,8 @@
<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>
</resources>

View File

@@ -191,6 +191,8 @@
<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="share_to">Comparteix amb…</string>
<string name="unreachable_device">%s (no s\'hi pot accedir)</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_newer">Aquest dispositiu usa una versió nova del protocol</string>
<string name="plugin_settings_with_name">Configuració del %s</string>
<string name="invalid_device_name">El nom del dispositiu no és vàlid</string>
@@ -410,4 +412,8 @@
<string name="receive_notifications_permission_explanation">Cal permetre que les notificacions es rebin des d\'altres dispositius</string>
<string name="findmyphone_notifications_explanation">Cal el permís de notificacions perquè el telèfon pugui sonar quan l\'aplicació estigui en segon pla</string>
<string name="no_notifications">Les notificacions estan desactivades, no rebreu notificacions entrants d\'emparellament.</string>
<string name="mpris_keepwatching">Continua reproduint</string>
<string name="mpris_keepwatching_settings_title">Continua reproduint</string>
<string name="mpris_keepwatching_settings_summary">Mostra una notificació silenciosa per a continuar reproduint en aquest dispositiu després de tancar l\'element multimèdia</string>
<string name="notification_channel_keepwatching">Continua reproduint</string>
</resources>

View File

@@ -18,6 +18,7 @@
<string name="pref_plugin_clipboard_sent">Schránka poslána</string>
<string name="pref_plugin_mousepad">Vzdálený vstup</string>
<string name="pref_plugin_mousepad_desc">Používejte svůj telefon nebo tablet jako touchpad a klávesnici</string>
<string name="pref_plugin_presenter">Ovladač prezentace</string>
<string name="pref_plugin_presenter_desc">Použijte své zařízení pro přepínání snímků prezentace</string>
<string name="pref_plugin_remotekeyboard">Přijímat stisky kláves se vzdálených zařízení</string>
<string name="pref_plugin_remotekeyboard_desc">Přijímat události stisku kláves ze vzdálených zařízení</string>
@@ -51,6 +52,7 @@
<string name="remotekeyboard_multiple_connections">Je k dispozici více než jedno připojení klávesnice. Vyberte zařízení pro jeho nastavení.</string>
<string name="open_mousepad">Vzdálený vstup</string>
<string name="mousepad_info">Pohybujte prstem po obrazovce pro pohybování kurzorem myši. Ťukněte pro kliknutí a použijte dva/tři prsty jako pravé a prostřední tlačítko. Použijte 2 prsty pro posunování. Pro přetažení dlouze podržte. Funkčnost gyro myš lze povolit v předvolbách modulu.</string>
<string name="mousepad_info_no_gestures">Pohybujte prstem po obrazovce pro pohybování kurzorem myši, ťukněte pro kliknutí.</string>
<string name="mousepad_keyboard_input_not_supported">Vstup pomocí klávesnice není spárovaným zařízením podporován</string>
<string name="mousepad_single_tap_settings_title">Nastavit činnost pro ťuknutí prstem</string>
<string name="mousepad_double_tap_settings_title">Nastavit činnost pro ťuknutí dvěma prsty</string>
@@ -97,6 +99,7 @@
<string name="pref_plugin_mousepad_send_keystrokes">Posílat jako úhozy kláves</string>
<string name="mouse_receiver_plugin_description">Přijímat vzdálený pohyb myši</string>
<string name="mouse_receiver_plugin_name">Příjemce myši</string>
<string name="mouse_receiver_no_permissions">Pro příjem dotykového vstupu musíte nejdřív udělit oprávnění přístupnosti aby zařízení šlo ovládat</string>
<string name="view_status_title">Stav</string>
<string name="battery_status_format">Baterie: %d%%</string>
<string name="battery_status_low_format">Baterie: %d%% Téměř vybitá baterie</string>
@@ -119,6 +122,7 @@
<string name="my_device_fingerprint">Otisk SHA256 certifikátu vašeho zařízení je:</string>
<string name="remote_device_fingerprint">Otisk certifikátu SHA256 vzdáleného zařízení je:</string>
<string name="pair_requested">Bylo vyžádáno párování</string>
<string name="pair_succeeded">Párování bylo úspěšné</string>
<string name="pairing_request_from">Požadavek o párování z %1s</string>
<plurals name="incoming_file_title">
<item quantity="one">Přijímám %1$d soubor z %2$s</item>
@@ -172,6 +176,7 @@
<string name="received_file_text">Ťukněte pro otevření \'%1s\'</string>
<string name="cannot_create_file">Nelze vytvořit soubor %s</string>
<string name="tap_to_answer">Ťukněte pro odpovězení</string>
<string name="left_click">Poslat kliknutí levým tlačítkem myši</string>
<string name="right_click">Poslat kliknutí pravým tlačítkem</string>
<string name="middle_click">Poslat kliknutí prostředním tlačítkem</string>
<string name="show_keyboard">Zobrazit klávesnici</string>
@@ -201,6 +206,7 @@
<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="share_to">Sdílet s...</string>
<string name="unreachable_device">%s (nedostupná)</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="invalid_device_name">Neplatný název zařízení</string>

View File

@@ -181,7 +181,6 @@
</string-array>
<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="share_to">Freigeben für ...</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="invalid_device_name">Ungültiger Gerätename</string>

View File

@@ -169,7 +169,6 @@
</string-array>
<string name="mpris_notification_settings_title">Εμφάνιση ειδοποίησης κονσόλας πολυμέσων</string>
<string name="mpris_notification_settings_summary">Να επιτρέπεται ο έλεγχος των αναπαραφωγέων πολυμέσων χωρίς άνοιγμα του KDE Connect</string>
<string name="share_to">Διαμοιρασμός με…</string>
<string name="protocol_version_newer">Η συσκευή αυτή χρησιμοποιεί νεότερη έκδοση πρωτοκόλλου</string>
<string name="plugin_settings_with_name">%s ρυθμίσεις</string>
<string name="invalid_device_name">Μη έγκυρο όνομα συσκευής</string>

View File

@@ -183,7 +183,6 @@
</string-array>
<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="share_to">Share To…</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="invalid_device_name">Invalid device name</string>

View File

@@ -18,6 +18,7 @@
<string name="pref_plugin_clipboard_sent">Clipboard Sendita</string>
<string name="pref_plugin_mousepad">Fora enigo</string>
<string name="pref_plugin_mousepad_desc">Uzu vian telefonon aŭ tablojdon kiel tuŝplaton kaj klavaron</string>
<string name="pref_plugin_presenter">Prezento fora</string>
<string name="pref_plugin_presenter_desc">Uzu vian aparaton por ŝanĝi lumbildojn en prezento</string>
<string name="pref_plugin_remotekeyboard">Ricevi forajn klavojn</string>
<string name="pref_plugin_remotekeyboard_desc">Ricevi klavopremajn eventojn de foraj aparatoj</string>
@@ -41,11 +42,17 @@
<string name="cancel">Nuligi</string>
<string name="open_settings">Malfermi agordojn</string>
<string name="no_permissions">Vi devas doni permeson aliri sciigojn</string>
<string name="no_permission_mprisreceiver">Por povi regi viajn plurmediajn ludilojn, vi devas doni aliron al la sciigoj</string>
<string name="no_permissions_remotekeyboard">Por ricevi klavpremojn vi devas aktivigi la KDE Connect Remote Keyboard</string>
<string name="send_ping">Sendi ping</string>
<string name="open_mpris_controls">Mastrumo de Aŭdvidaĵoj</string>
<string name="remotekeyboard_editing_only_title">Pritrakti forajn klavojn nur dum redaktado</string>
<string name="remotekeyboard_not_connected">Ne estas aktiva fora klavara konekto, starigu unu en kdeconnect</string>
<string name="remotekeyboard_connected">Fora klavara konekto estas aktiva</string>
<string name="remotekeyboard_multiple_connections">Estas pli ol unu fora klavara konekto, elektu la aparaton por agordi</string>
<string name="open_mousepad">Fora enigo</string>
<string name="mousepad_info">Movu fingron sur la ekrano por movi la muskursonon. Frapu por klako, kaj uzu du/tri fingrojn por dekstraj kaj mezaj butonoj. Uzu 2 fingrojn por rulumi. Uzu longan premon por treni kaj faligi. Gyro-musfunkcio povas esti ebligita de aldonaĵaj preferoj</string>
<string name="mousepad_info_no_gestures">Movu fingron sur la ekranon por movi la muskursonon, frapetu por klako.</string>
<string name="mousepad_keyboard_input_not_supported">Klavara enigo ne subtenata de la parigita aparato</string>
<string name="mousepad_single_tap_settings_title">Agordi unufingran frapet-agon</string>
<string name="mousepad_double_tap_settings_title">Agordi dufingran frapet-agon</string>
@@ -83,6 +90,7 @@
<string name="sendkeystrokes_disabled_toast">Sendi klavopremojn estas malŝaltita - ebligu ĝin en la agordoj</string>
<string name="sendkeystrokes_wrong_data">Nevalida mimspeco - devas esti \'teksto/x-klavopremoj\'</string>
<string name="sendkeystrokes_sent_text">Sendis %1$s al aparato %2$s</string>
<string name="sendkeystrokes_pref_category_summary">Ĉi tiu modulo permesas al aliaj programoj dividi tekstajn segmentojn kiel klavopremojn, kiuj estos senditaj al la konektita gastiganto</string>
<string name="sendkeystrokes_pref_category_title">Sendi klavopremojn</string>
<string name="sendkeystrokes_pref_enabled">Ebligi la sendon de klavopremoj</string>
<string name="sendkeystrokes_pref_enabled_summary">Aŭskulti datumojn kun mimo-tipo \'teksto/x-klavopremoj\'</string>
@@ -91,6 +99,7 @@
<string name="pref_plugin_mousepad_send_keystrokes">Sendi kiel klavopremojn</string>
<string name="mouse_receiver_plugin_description">Ricevi foran musan movon</string>
<string name="mouse_receiver_plugin_name">Musa ricevilo</string>
<string name="mouse_receiver_no_permissions">Por ricevi tuŝajn enigojn malproksime, vi devas doni permesojn de Alirebleco por plene regi vian aparaton</string>
<string name="view_status_title">Statuso</string>
<string name="battery_status_format">Baterio: %d%%</string>
<string name="battery_status_low_format">Baterio: %d%% Malalta Baterio</string>
@@ -109,6 +118,7 @@
<string name="error_canceled_by_user">Nuligite de uzanto</string>
<string name="error_canceled_by_other_peer">Nuligite de alia kunulo</string>
<string name="encryption_info_title">Ĉifrada Informo</string>
<string name="encryption_info_msg_no_ssl">La alia aparato ne uzas lastatempan version de KDE Connect, uzante la heredan ĉifradan metodon.</string>
<string name="my_device_fingerprint">SHA256-fingrospuro de via aparato-atestilo estas:</string>
<string name="remote_device_fingerprint">SHA256-fingrospuro de atestilo de fora aparato estas:</string>
<string name="pair_requested">Parigo alpetiĝis</string>
@@ -150,6 +160,7 @@
<string name="received_file_text">Frapeti por malfermi \'%1s\'</string>
<string name="cannot_create_file">Ne eblas krei dosieron %s</string>
<string name="tap_to_answer">Frapeti por respondi</string>
<string name="left_click">Sendi Maldekstran Klakon</string>
<string name="right_click">Sendi Dekstran Klakon</string>
<string name="middle_click">Sendi Mezan Klakon</string>
<string name="show_keyboard">Montri Klavaron</string>
@@ -176,9 +187,12 @@
<item>1 minuton</item>
<item>2 minutoj</item>
</string-array>
<string name="mpris_notifications_explanation">La sciiga permeso estas necesa por montri malproksimajn datumportilojn en la sciigokesto</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="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="protocol_version_newer">Ĉi tiu aparato uzas pli novan protokolversion</string>
<string name="plugin_settings_with_name">%s agordoj</string>
<string name="invalid_device_name">Nevalida aparato nomo</string>
@@ -186,6 +200,7 @@
<string name="custom_devices_settings">Propra aparato listo</string>
<string name="custom_device_list">Aldoni aparatojn per IP</string>
<string name="custom_device_deleted">Propra aparato forigita</string>
<string name="custom_device_list_help">Se via aparato ne estas aŭtomate detektita, vi povas aldoni ĝian IP-adreson aŭ gastigan nomon alklakante la Ŝveban Ago-Butonon</string>
<string name="custom_device_fab_hint">Aldoni aparaton</string>
<string name="undo">Malfari</string>
<string name="share_notification_preference">Bruaj sciigoj</string>
@@ -213,19 +228,24 @@
<string name="sftp_action_mode_menu_delete">Forigi</string>
<string name="sftp_no_storage_locations_configured">Neniuj konservejoj agordis</string>
<string name="sftp_saf_permission_explanation">Por aliri dosierojn malproksime vi devas agordi konservadlokojn</string>
<string name="sftp_manage_storage_permission_explanation">Por permesi foran aliron al dosieroj sur ĉi tiu aparato, vi devas permesi al KDE Connect administri la konservejon.</string>
<string name="no_players_connected">Neniuj ludantoj trovitaj</string>
<string name="send_files">Sendi dosierojn</string>
<string name="block_notification_contents">Bloki sciigan enhavon</string>
<string name="block_notification_images">Bloki sciigajn bildojn</string>
<string name="pairing_title">KDE Konekti Aparatojn</string>
<string name="pairing_description">Aliaj aparatoj rulantaj KDE Connect en via sama reto devus aperi ĉi tie.</string>
<string name="device_rename_title">Alinomi la aparaton</string>
<string name="device_rename_confirm">Alinomi</string>
<string name="refresh">Refreŝigi</string>
<string name="unreachable_description">Ĉi tiu parigita aparato ne estas atingebla. Certigu, ke ĝi estas konektita al via sama reto.</string>
<string name="no_wifi">Vi ne estas konektita al reto Wifi, do vi eble ne povos vidi iujn ajn aparatojn. Klaku ĉi tie por ebligi Vifion.</string>
<string name="on_non_trusted_message">Ne en fidinda reto: aŭtomalkovro estas malŝaltita.</string>
<string name="no_file_browser">Ne estas instalitaj dosieraj retumiloj.</string>
<string name="pref_plugin_telepathy">Sendi SMS</string>
<string name="pref_plugin_telepathy_desc">Sendi tekstmesaĝojn de via labortablo</string>
<string name="pref_plugin_telepathy_mms">Sendi MMS</string>
<string name="pref_plugin_telepathy_mms_desc">Por povi sendi MMS de KDE Connect, vi devas agordi ĝin kiel la defaŭltan SMS-aplikaĵon.</string>
<string name="findmyphone_title">Trovi mian telefonon</string>
<string name="findmyphone_title_tablet">Trovi mian tableton</string>
<string name="findmyphone_title_tv">Trovi mian televidilon</string>
@@ -237,13 +257,22 @@
<string name="permission_explanation">Ĉi tiu kromaĵo bezonas permesojn por funkcii</string>
<string name="all_permissions_granted">Ĉiuj permesoj donitaj 🎉</string>
<string name="optional_permission_explanation">Vi devas doni kromajn permesojn por ebligi ĉiujn funkciojn</string>
<string name="plugins_need_optional_permission">Iuj kromprogramoj havas funkciojn malŝaltitaj pro manko de permeso (frapu por pliaj informoj):</string>
<string name="share_optional_permission_explanation">Por ricevi dosierojn vi devas permesi konservan aliron</string>
<string name="share_notifications_explanation">Por vidi la progreson dum sendado kaj ricevado de dosieroj, vi devas permesi sciigojn</string>
<string name="telepathy_permission_explanation">Por legi kaj skribi SMS de via labortablo vi devas doni permeson al SMS</string>
<string name="telephony_permission_explanation">Por vidi telefonvokojn sur la labortablo, vi devas doni permeson al telefonvokaj protokoloj kaj telefona stato</string>
<string name="telephony_optional_permission_explanation">Por vidi kontaktonomon anstataŭ telefonnumero vi devas doni aliron al la kontaktoj de la telefono</string>
<string name="contacts_permission_explanation">Por dividi vian kontaktlibron kun la labortablo, vi devas doni permeson al kontaktoj</string>
<string name="contacts_per_device_confirmation">Viaj telefonaj kontaktoj estos kopiitaj al ĉi tiu aparato, do ili povas esti uzataj de la KDE Connect SMS-aplikaĵo kaj aliaj aplikaĵoj.</string>
<string name="select_ringtone">Elekti sonoron</string>
<string name="telephony_pref_blocked_title">Blokitaj nombroj</string>
<string name="telephony_pref_blocked_dialog_desc">Ne montru vokojn kaj SMS de ĉi tiuj numeroj. Bonvolu specifi unu numeron po linio</string>
<string name="mpris_coverart_description">Kovrilo de aktuala aŭdvidaĵo</string>
<string name="settings_icon_description">Piktogramo de agordoj</string>
<string name="presenter_fullscreen">Plenekrane</string>
<string name="presenter_exit">Eliri prezenton</string>
<string name="presenter_lock_tip">Vi povas ŝlosi vian aparaton kaj uzi la laŭtec-klavojn por iri al la antaŭa/sekva lumbildo</string>
<string name="add_command">Aldoni komandon</string>
<string name="addcommand_explanation">Ne estas komandoj registritaj</string>
<string name="addcommand_explanation2">Vi povas aldoni novajn komandojn en la KDE Connect System Settings</string>
@@ -265,6 +294,7 @@
<string name="runcommand_nosuchdevice">Ne ekzistas tia aparato</string>
<string name="runcommand_noruncommandplugin">Ĉi tiu aparato ne havas la Run Command Plugin ebligita</string>
<string name="runcommand_category_device_controls_title">Aparataj Regiloj</string>
<string name="runcommand_device_controls_summary">Se via aparato subtenas Aparatajn Regilojn, komandoj, kiujn vi agordis, aperos tie.</string>
<string name="set_runcommand_name_as_title">set_runcommand_name_as_title</string>
<string name="runcommand_name_as_title_title">Montri nomon kiel titolon</string>
<string name="pref_plugin_findremotedevice">Trovi malproksiman aparaton</string>
@@ -278,6 +308,7 @@
<string name="settings_rename">Aparatnomo</string>
<string name="settings_dark_mode">Malhela etoso</string>
<string name="settings_more_settings_title">Pli da agordoj</string>
<string name="settings_more_settings_text">Per-aparataj agordoj troveblas sub \'Kromaĵo-agordoj\' de ene de aparato.</string>
<string name="setting_persistent_notification">Montri konstantan sciigon</string>
<string name="setting_persistent_notification_oreo">Konstanta sciigo</string>
<string name="setting_persistent_notification_description">Frapi por aktivigi/malŝalti en Sciigaj agordoj</string>
@@ -296,6 +327,8 @@
<string name="empty_trusted_networks_list_text">Vi ankoraŭ ne aldonis neniun fidindan reton</string>
<string name="allow_all_networks_text">Permesi ĉion</string>
<string name="location_permission_needed_title">Permeso bezonata</string>
<string name="location_permission_needed_desc">KDE Connect bezonas la fonlokan permeson por scii la WiFi-reton al kiu vi estas konektita eĉ kiam la programo estas en la fono. Ĉi tio estas ĉar la nomo de la WiFi-retoj ĉirkaŭ vi povus esti uzata por trovi vian lokon, eĉ kiam tion ne faras KDE Connect.</string>
<string name="clipboard_android_x_incompat">Android 10 forigis aliron al tondujo al ĉiuj aplikaĵoj. Ĉi tiu kromaĵo estos malŝaltita.</string>
<string name="mpris_open_url">Daŭre ludi ĉi tie</string>
<string name="cant_open_url">Ne povas malfermi URL por daŭrigi ludadon</string>
<string name="bigscreen_home">Hejmo</string>
@@ -307,6 +340,7 @@
<string name="bigscreen_mic">Mikrofono</string>
<string name="pref_plugin_bigscreen">Grandekrana fora</string>
<string name="pref_plugin_bigscreen_desc">Uzu vian aparaton kiel fora por Plasma Bigscreen</string>
<string name="bigscreen_optional_permission_explanation">Por dividi mikrofonan enigon de via telefono, vi devas doni aliron al la sonenigo de la telefono</string>
<string name="bigscreen_speech_extra_prompt">Parolado</string>
<string name="message_reply_label">RESPONDO</string>
<string name="mark_as_read_label">MARKI KIEL LEGITA</string>
@@ -342,6 +376,8 @@
<string name="authors">Aŭtoroj</string>
<string name="thanks_to">Dankon al</string>
<string name="easter_egg">Paska Ovo</string>
<string name="email_contributor">Retpoŝti kontribuanton\n%s</string>
<string name="visit_contributors_homepage">Viziti hejmpaĝon de kontribuanto\n%s</string>
<string name="version">Versio %s</string>
<string name="about_kde">Pri KDE</string>
<string name="kde_be_free">KDE - Estu Libera!</string>
@@ -354,6 +390,7 @@
<string name="send_compose">Sendi</string>
<string name="compose_send_title">Verki sendon</string>
<string name="open_compose_send">Verki tekston</string>
<string name="about_kde_about">&lt;h1&gt;Pri&lt;/h1&gt; &lt;p&gt;KDE estas tutmonda komunumo de softvar-inĝenieroj, artistoj, verkistoj, tradukistoj kaj kreintoj kiuj engaĝiĝas al &lt;a href=https://www.gnu.org/philosophy/free -sw.html&gt;Disvolvado de Libera Programaro&lt;/a&gt;. KDE produktas la Plasma labortablan medion, centojn da aplikaĵoj, kaj la multajn programarajn bibliotekojn kiuj subtenas ilin.&lt;/p&gt; &lt;/p&gt;KDE estas kunlabora entrepreno: neniu unuopa ento stiras ĝian direkton aŭ produktojn. Anstataŭe, ni kunlaboras por atingi la komunan celon konstrui la plej bonan Liberan Programaron de la mondo. Ĉiuj bonvenas &lt;a href=https://community.kde.org/Get_Involved&gt;aliiĝi kaj kontribui&lt;/a&gt; al KDE, inkluzive de vi.&lt;/p&gt; Vizitu &lt;a href=https://www.kde.org/&gt;https://www.kde.org/&lt;/a&gt; por pliaj informoj pri la KDE-komunumo kaj la programaro, kiun ni produktas.</string>
<string name="maintainer_and_developer">Prizorganto kaj programisto</string>
<string name="developer">Ellaboranto</string>
<string name="apple_support">subteno de macOS. Laborante pri iOS-subteno</string>
@@ -363,10 +400,17 @@
<string name="alex_fiestas_task">Pliboniĝoj de aldonaĵo de Kontaktoj</string>
<string name="maxim_leshchenko_task">UI-plibonigoj kaj ĉi tiu pri paĝo</string>
<string name="holger_kaelberer_task">Fora klavara kromaĵo kaj korektoj de cimoj</string>
<string name="saikrishna_arcot_task">Subteno por uzi la klavaron en la fora eniga kromaĵo, korektoj de cimoj kaj ĝeneralaj plibonigoj</string>
<string name="everyone_else">Ĉiuj aliaj, kiuj kontribuis al KDE Connect tra la jaroj</string>
<string name="send_clipboard">Sendi tondujon</string>
<string name="tap_to_execute">Frapi por plenumi</string>
<string name="plugin_stats">Statistiko de kromprogramoj</string>
<string name="enable_udp_broadcast">Ebligi UDP-aparatan malkovron</string>
<string name="receive_notifications_permission_explanation">Sciigoj devas esti permesitaj ricevi ilin de aliaj aparatoj</string>
<string name="findmyphone_notifications_explanation">La sciiga permeso estas necesa por ke la telefono povu sonori kiam la app estas en la fono</string>
<string name="no_notifications">Sciigoj estas malŝaltitaj, vi ne ricevos alvenantajn parajn sciigojn.</string>
<string name="mpris_keepwatching">Daŭrigi ludadon</string>
<string name="mpris_keepwatching_settings_title">Daŭrigi ludadon</string>
<string name="mpris_keepwatching_settings_summary">Montri silentan sciigon por daŭrigi ludadon en ĉi tiu aparato post fermo de datumportilo</string>
<string name="notification_channel_keepwatching">Daŭrigi ludadon</string>
</resources>

View File

@@ -191,6 +191,8 @@
<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="share_to">Compartir con...</string>
<string name="unreachable_device">%s (no accesible)</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_newer">Este dispositivo usa una versión más reciente del protocolo</string>
<string name="plugin_settings_with_name">Preferencias de %s</string>
<string name="invalid_device_name">Nombre de dispositivo no válido</string>
@@ -410,4 +412,8 @@
<string name="receive_notifications_permission_explanation">Las notificaciones tienen que estar activadas para recibirlas desde otros dispositivos</string>
<string name="findmyphone_notifications_explanation">Se necesita el permiso de notificaciones para que el teléfono pueda sonar cuando la aplicación está en segundo plano</string>
<string name="no_notifications">Las notificaciones están desactivadas, no recibirá notificaciones de vinculación entrantes.</string>
<string name="mpris_keepwatching">Continuar reproduciendo</string>
<string name="mpris_keepwatching_settings_title">Continuar reproduciendo</string>
<string name="mpris_keepwatching_settings_summary">Mostrar una notificación silenciosa para continuar reproduciendo en este dispositivo tras cerrar el reproductor.</string>
<string name="notification_channel_keepwatching">Continuar reproduciendo</string>
</resources>

View File

@@ -145,7 +145,6 @@
</string-array>
<string name="mpris_notification_settings_title">Meedia juhtimise märguannete näitamine</string>
<string name="mpris_notification_settings_summary">Meediamängija juhtimise võimaldamine ilma KDE Connecti avamata</string>
<string name="share_to">Jaga ...</string>
<string name="protocol_version_newer">See seade kasutab uuemat protokolli versiooni</string>
<string name="plugin_settings_with_name">%s seadistused</string>
<string name="invalid_device_name">Vigane seadme nimi</string>

View File

@@ -186,7 +186,6 @@
<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_summary">Utzi zure euskarri-jotzaileak kontrolatzen KDE Connect ireki gabe</string>
<string name="share_to">Partekatu honekin...</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="invalid_device_name">Gailuaren izen baliogabea</string>

View File

@@ -186,7 +186,6 @@
<string name="mpris_notifications_explanation">Ilmoituskäyttöoikeus vaaditaan etämedian näyttämiseksi ilmoitussovelmassa</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="share_to">Jaa…</string>
<string name="protocol_version_newer">Laite käyttää uudempaa yhteyskäytäntöversiota</string>
<string name="plugin_settings_with_name">%s-asetukset</string>
<string name="invalid_device_name">Virheellinen laitenimi</string>

View File

@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="kde_connect">KDE Connect</string>
<string name="kde_connect">KDEConnect</string>
<string name="manifest_label_share">Envoyer vers un périphérique</string>
<string name="foreground_notification_no_devices">Connecté à aucun périphérique</string>
<string name="foreground_notification_devices">Connecté à : %s</string>
@@ -43,7 +43,7 @@
<string name="open_settings">Accéder aux paramètres</string>
<string name="no_permissions">Vous devez accorder la permission d\'accéder aux notifications</string>
<string name="no_permission_mprisreceiver">Pour pouvoir contrôler vos lecteurs multimédia, veuillez permettre l\'accès aux notifications</string>
<string name="no_permissions_remotekeyboard">Vous devez activer le Clavier à distance KDE Connect pour recevoir les appuis sur les touches</string>
<string name="no_permissions_remotekeyboard">Vous devez activer le Clavier à distance KDEConnect pour recevoir les appuis sur les touches</string>
<string name="send_ping">Envoyer un « Ping »</string>
<string name="open_mpris_controls">Contrôles multimédia</string>
<string name="remotekeyboard_editing_only_title">Gérer les appuis de touches à distance uniquement lors de l\'édition</string>
@@ -88,12 +88,12 @@
<string name="sendkeystrokes_send_to">Envoyez les appuis de touches vers</string>
<string name="sendkeystrokes_textbox_hint">Envoyez les appuis de touches vers l\'hôte</string>
<string name="sendkeystrokes_disabled_toast">L\'envoi des appuis de touches est désactivé. Veuillez l\'activer dans la configuration.</string>
<string name="sendkeystrokes_wrong_data">Type « MIME » non valable. Doit être « text/x-keystrokes »</string>
<string name="sendkeystrokes_wrong_data">Type « MIME » non valable. Doit être « text / x-keystrokes »</string>
<string name="sendkeystrokes_sent_text">%1s envoyés vers le périphérique %2s</string>
<string name="sendkeystrokes_pref_category_summary">Ce module permet aux autres applications de partager des portions de texte comme des appuis de touches, qui seront envoyées vers l\'hôte connecté.</string>
<string name="sendkeystrokes_pref_category_title">Envoyez les appuis de touches</string>
<string name="sendkeystrokes_pref_enabled">Autoriser l\'envoi des appuis de touches</string>
<string name="sendkeystrokes_pref_enabled_summary">Attendre des données avec le type « MIME » « text/x-keystrokes »</string>
<string name="sendkeystrokes_pref_enabled_summary">Attendre des données avec le type « MIME » « text / x-keystrokes »</string>
<string name="sendkeystrokes_safe_text_enabled">Envoyez du texte confirmé immédiatement</string>
<string name="sendkeystrokes_safe_text_enabled_summary">Envoyez des chaînes courtes uniquement numériques sans confirmation</string>
<string name="pref_plugin_mousepad_send_keystrokes">Envoyez comme appuis de touches</string>
@@ -118,7 +118,7 @@
<string name="error_canceled_by_user">Annulé par l\'utilisateur</string>
<string name="error_canceled_by_other_peer">Annulé par un autre homologue</string>
<string name="encryption_info_title">Informations de chiffrement</string>
<string name="encryption_info_msg_no_ssl">Ce périphérique n\'utilise pas une version récente de KDE Connect qui utilise l\'ancienne méthode de chiffrement.</string>
<string name="encryption_info_msg_no_ssl">Ce périphérique n\'utilise pas une version récente de KDEConnect qui utilise l\'ancienne méthode de chiffrement.</string>
<string name="my_device_fingerprint">L\'empreinte SHA256 du certificat de votre périphérique est :</string>
<string name="remote_device_fingerprint">L\'empreinte « SHA256 » du certificat du périphérique distant est :</string>
<string name="pair_requested">Paire demandée</string>
@@ -189,8 +189,10 @@
</string-array>
<string name="mpris_notifications_explanation">Les permissions pour les notifications sont nécessaires pour afficher des supports distants dans le panneau des notifications</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 KDE Connect.</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="unreachable_device">%s (Inaccessible)</string>
<string name="unreachable_device_url_share_text">Les URL partagées vers un appareil inaccessible lui seront transmises une fois quil re-deviendra accessible.\n\n</string>
<string name="protocol_version_newer">Le périphérique utilise une version plus récente du protocole</string>
<string name="plugin_settings_with_name">Configuration %s</string>
<string name="invalid_device_name">Nom de périphérique non valable</string>
@@ -226,13 +228,13 @@
<string name="sftp_action_mode_menu_delete">Supprimer</string>
<string name="sftp_no_storage_locations_configured">Aucun emplacement stockage n\'est configuré</string>
<string name="sftp_saf_permission_explanation">Vous devez configurer des emplacements de stockage pour accéder aux fichiers à distance</string>
<string name="sftp_manage_storage_permission_explanation">Pour permettre l\'accès à distance aux fichiers sur ce périphérique, vous devez autoriser KDE Connect à gérer l\'enregistrement.</string>
<string name="sftp_manage_storage_permission_explanation">Pour permettre l\'accès à distance aux fichiers sur ce périphérique, vous devez autoriser KDEConnect à gérer l\'enregistrement.</string>
<string name="no_players_connected">Aucun lecteur trouvé</string>
<string name="send_files">Envoyer des fichiers</string>
<string name="block_notification_contents">Bloquer les contenus de notifications</string>
<string name="block_notification_images">Bloquer les images de notifications</string>
<string name="pairing_title">Périphériques KDE Connect</string>
<string name="pairing_description">Les autres périphériques utilisant KDE Connect dans votre réseau apparaissent ici.</string>
<string name="pairing_title">Périphériques KDEConnect</string>
<string name="pairing_description">Les autres périphériques utilisant KDEConnect dans votre réseau apparaissent ici.</string>
<string name="device_rename_title">Renommer le périphérique</string>
<string name="device_rename_confirm">Renommer</string>
<string name="refresh">Mettre à jour</string>
@@ -273,7 +275,7 @@
<string name="presenter_lock_tip">Vous pouvez verrouiller votre appareil et utiliser les touches de volume pour passer d\'une diapositive à l\'autre</string>
<string name="add_command">Ajouter une commande</string>
<string name="addcommand_explanation">Aucune commande enregistrée</string>
<string name="addcommand_explanation2">Vous pouvez ajouter de nouvelles commandes dans la configuration système de KDE Connect</string>
<string name="addcommand_explanation2">Vous pouvez ajouter de nouvelles commandes dans la configuration système de KDEConnect</string>
<string name="add_command_description">Vous pouvez ajouter des commandes sur votre ordinateur</string>
<string name="pref_plugin_mprisreceiver">Contrôle du lecteur multimédia</string>
<string name="pref_plugin_mprisreceiver_desc">Contrôlez les lecteurs multimédia de votre téléphone depuis un autre appareil</string>
@@ -317,7 +319,7 @@
<string name="block_images">Bloquer les images des notifications</string>
<string name="notification_channel_receivenotification">Notifications provenant d\'autres périphériques</string>
<string name="no_app_for_opening">Aucune application adaptée trouvée pour ouvrir ce fichier.</string>
<string name="remote_keyboard_service">Clavier à distance KDE Connect</string>
<string name="remote_keyboard_service">Clavier à distance KDEConnect</string>
<string name="presenter_pointer">Pointeur</string>
<string name="trusted_networks">Réseaux de confiance</string>
<string name="trusted_networks_desc">Restreindre la découverte automatique aux réseaux connus</string>
@@ -394,7 +396,7 @@
<string name="about_kde_support_kde">&lt;h1&gt;Soutenir KDE&lt;/h1&gt; &lt;p&gt; Les logiciels de KDE sont et seront toujours disponibles gratuitement. Cependant, leur création n\'est pas gratuite. &lt;p&gt;Pour soutenir le développement, la communauté KDE a créée KDE e.V., une organisation à but non lucratif, légalement fondée en Allemagne. KDE e.V. représente la communauté KDE pour les questions juridiques et financières. Veuillez consulter la page &lt;a href=https://ev.kde.org/&gt;https://ev.kde.org/&lt;/a&gt; pour plus d\'informations sur KDE e.V.&lt;/p&gt; &lt;p&gt;KDE bénéficie de plusieurs types de contributions, y compris financières. Nous utilisons les fonds pour rembourser les membres et d\'autres personnes pour les dépenses qu\'ils engagent pour leurs contributions. D\'autres fonds sont utilisés pour le soutien juridique et l\'organisation de conférences et de réunions. Nous aimerions vous encourager à soutenir nos efforts par un don financier, en utilisant l\'un des moyens décrits sur la page &lt;a href=https://www.kde.org/community/donations/&gt;https://www.kde.org/community/donations/&lt;/a&gt;. &lt;/p&gt; Nous vous remercions par avance pour votre soutien.</string>
<string name="maintainer_and_developer">Mainteneur et développeur</string>
<string name="developer">Développeur</string>
<string name="apple_support">Prise en charge de MacOS. Travail en cours sur la prise en charge de iOS.</string>
<string name="apple_support">Prise en charge de macOS. Travail en cours sur la prise en charge de iOS.</string>
<string name="bug_fixes_and_general_improvements">Correction de bogues et améliorations générales</string>
<string name="samoilenko_yuri_task">Implémentation de SFTP, corrections de bogues et améliorations générales</string>
<string name="aniket_kumar_task">Améliorations du module externe pour SMS</string>
@@ -402,7 +404,7 @@
<string name="maxim_leshchenko_task">Améliorations de l\'interface utilisateur et de cette page d\'à propos</string>
<string name="holger_kaelberer_task">Corrections du module externe de clavier sans fil et de bogues</string>
<string name="saikrishna_arcot_task">Prise en charge de l\'utilisation du clavier dans le module d\'entrée à distance, corrections de bogues et améliorations générales</string>
<string name="everyone_else">Toutes les autres personnes ayant contribué à « KDE Connect » depuis plusieurs années</string>
<string name="everyone_else">"Toutes les autres personnes ayant contribué KDEConnect depuis plusieurs années"</string>
<string name="send_clipboard">Envoyer le presse-papier</string>
<string name="tap_to_execute">Tapotez pour lancer</string>
<string name="plugin_stats">Statistiques des modules externes</string>

View File

@@ -112,7 +112,7 @@
<string name="pair_new_device">Emparellar cun novo dispositivo</string>
<string name="cancel_pairing">Cancelar o emparellamento</string>
<string name="unknown_device">Dispositivo descoñecido</string>
<string name="error_not_reachable">Dispositivo fóra do alcance</string>
<string name="error_not_reachable">O dispositivo está inaccesíbel.</string>
<string name="error_already_paired">O dispositivo xa está emparellado.</string>
<string name="error_timed_out">Esgotouse o tempo límite</string>
<string name="error_canceled_by_user">Cancelouno a persoa usuaria.</string>
@@ -191,6 +191,8 @@
<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="share_to">Compartir con…</string>
<string name="unreachable_device">%s (inaccesíbel)</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_newer">Este dispositivo usa unha versión máis nova do protocolo.</string>
<string name="plugin_settings_with_name">Configuración de %s</string>
<string name="invalid_device_name">Nome de dispositivo incorrecto</string>
@@ -236,7 +238,7 @@
<string name="device_rename_title">Renomear o dispositivo</string>
<string name="device_rename_confirm">Renomear</string>
<string name="refresh">Actualizar</string>
<string name="unreachable_description">Este dispositivo emparellado está fóra do alcance. Asegúrese de que está conectado á mesma rede.</string>
<string name="unreachable_description">Este dispositivo emparellado está inaccesíbel. Asegúrese de que está conectado á mesma rede.</string>
<string name="no_wifi">Non ten conexión a unha rede Wi-Fi así que pode que non vexa ningún dispositivo. Prema aquí para activar a Wi-Fi.</string>
<string name="on_non_trusted_message">Non é unha rede de confianza: desactivouse o descubrimento automático.</string>
<string name="no_file_browser">Non hai navegadores de ficheiros instalados.</string>
@@ -287,7 +289,7 @@
<string name="mpris_stop">Deter o reprodutor actual</string>
<string name="copy_url_to_clipboard">Copiar o URL no portapapeis</string>
<string name="clipboard_toast">Copiouse no portapapeis</string>
<string name="runcommand_notreachable">O dispositivo está fóra de alcance</string>
<string name="runcommand_notreachable">O dispositivo está inaccesíbel.</string>
<string name="runcommand_notpaired">O dispositivo non está emparellado</string>
<string name="runcommand_nosuchdevice">Non hai tal dispositivo</string>
<string name="runcommand_noruncommandplugin">O dispositivo non ten o complemento de «Executar unha orde» activado</string>
@@ -410,4 +412,8 @@
<string name="receive_notifications_permission_explanation">Debe permitir notificacións para recibilas doutros dispositivos.</string>
<string name="findmyphone_notifications_explanation">Necesita o permiso de notificacións para que o teléfono poda soar cando a aplicación está en segundo plano.</string>
<string name="no_notifications">As notificacións están desactivadas, non recibirá notificacións entrantes de emparellamento.</string>
<string name="mpris_keepwatching">Continuar reproducindo</string>
<string name="mpris_keepwatching_settings_title">Continuar reproducindo</string>
<string name="mpris_keepwatching_settings_summary">Amosar unha notificación silenciosa para continuar reproducindo neste dispositivo tras pechar o contido multimedia.</string>
<string name="notification_channel_keepwatching">Continuar reproducindo</string>
</resources>

View File

@@ -177,7 +177,6 @@
</string-array>
<string name="mpris_notification_settings_title">Médiavezérlő értesítéseinek megjelenítése</string>
<string name="mpris_notification_settings_summary">Lehetővé teszi a médialejátszók vezérlését a KDE Connect megnyitása nélkül</string>
<string name="share_to">Megosztás…</string>
<string name="protocol_version_newer">Ez az eszköz egy újabb protokollverziót használ</string>
<string name="plugin_settings_with_name">%s beállításai</string>
<string name="invalid_device_name">Érvénytelen eszköznév</string>

View File

@@ -15,6 +15,7 @@
<string name="pref_plugin_clipboard_desc">Comparti le contento de area de transferentia</string>
<string name="pref_plugin_clipboard_sent">Area de transferentia inviate</string>
<string name="pref_plugin_mousepad">Entrata remote</string>
<string name="pref_plugin_presenter">Presentation Remote</string>
<string name="pref_plugin_presenter_desc">Usa tu dispositivo per cambiar diapositivas in un presentation</string>
<string name="pref_plugin_mpris">Controlos de Multimedia</string>
<string name="pref_plugin_runcommand">Executa commando</string>
@@ -72,6 +73,7 @@
</plurals>
<string name="tap_to_open">Tocca per aperir</string>
<string name="left_click">Invia Click sinistre</string>
<string name="show_keyboard">Monstra Claviero</string>
<string name="pairing_accept">Accepta</string>
<string name="pairing_reject">Rejecta</string>
<string name="settings">Preferentias</string>
@@ -92,6 +94,7 @@
<item>2 minutas</item>
</string-array>
<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="undo">Annulla</string>
<string name="share">Comparti</string>

View File

@@ -169,7 +169,6 @@
</string-array>
<string name="mpris_notification_settings_title">Tampilkan notifikasi kendali media</string>
<string name="mpris_notification_settings_summary">Memungkinkan pengendalian pemutar media Anda tanpa membuka KDE Connect</string>
<string name="share_to">Berbagi Ke...</string>
<string name="protocol_version_newer">Perangkat ini menggunakan sebuah versi protokol baru</string>
<string name="plugin_settings_with_name">Pengesetan %s</string>
<string name="invalid_device_name">Nama peranti tak absah</string>

View File

@@ -181,7 +181,6 @@
</string-array>
<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="share_to">Deila með…</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="invalid_device_name">Ógilt heiti tækis</string>

View File

@@ -191,6 +191,8 @@
<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="share_to">Condividi con…</string>
<string name="unreachable_device">%s (non raggiungibile)</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_newer">Questo dispositivo usa una nuova versione del protocollo di rete</string>
<string name="plugin_settings_with_name">Impostazioni di %s</string>
<string name="invalid_device_name">Nome dispositivo non valido</string>
@@ -410,4 +412,8 @@
<string name="receive_notifications_permission_explanation">Le notifiche devono essere consentite per riceverle da altri dispositivi</string>
<string name="findmyphone_notifications_explanation">L\'autorizzazione alle notifiche è necessaria affinché il telefono possa squillare quando l\'applicazione è sullo sfondo</string>
<string name="no_notifications">Le notifiche sono disabilitate, non riceverai notifiche di associazione in arrivo.</string>
<string name="mpris_keepwatching">Continua la riproduzione</string>
<string name="mpris_keepwatching_settings_title">Continua la riproduzione</string>
<string name="mpris_keepwatching_settings_summary">Mostra una notifica silenziosa per continuare a giocare su questo dispositivo dopo aver chiuso il supporto multimediale</string>
<string name="notification_channel_keepwatching">Continua la riproduzione</string>
</resources>

View File

@@ -207,6 +207,8 @@
<string name="mpris_notification_settings_title">הצגת התראות בקרת מדיה</string>
<string name="mpris_notification_settings_summary">לאפשר שליטה בנגני המדיה שלך מבלי לפתוח את KDE Connect</string>
<string name="share_to">שיתוף אל…</string>
<string name="unreachable_device">%s (לא נגיש)</string>
<string name="unreachable_device_url_share_text">כתובות שותפו להתקן בלתי נגיש והן תועברנה אליו ברגע שישוב להיות נגיש.\n\n</string>
<string name="protocol_version_newer">המכשיר משתמש בגרסה חדשה יותר</string>
<string name="plugin_settings_with_name">הגדרות %s</string>
<string name="invalid_device_name">שם המכשיר שגוי</string>
@@ -426,4 +428,8 @@
<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>
</resources>

View File

@@ -178,7 +178,6 @@
<string name="mpris_notifications_explanation">通知ドロアにメディア情報を表示するためには、通知の許可が必要です。</string>
<string name="mpris_notification_settings_title">メディア操作の通知を表示</string>
<string name="mpris_notification_settings_summary">KDE Connect を開かずにメディアプレーヤーをコントロール可能にします</string>
<string name="share_to">共有先...</string>
<string name="protocol_version_newer">このデバイスはより新しいプロトコルバージョンを使用しています</string>
<string name="plugin_settings_with_name">%s 設定</string>
<string name="invalid_device_name">不正なデバイス名</string>

View File

@@ -129,7 +129,6 @@
<item>1 წუთი</item>
<item>2 წუთი</item>
</string-array>
<string name="share_to">გაზიარება…</string>
<string name="protocol_version_newer">მოწყობილობა პროტოკოლის უფრო ახალ ვერსიას იყენებს</string>
<string name="plugin_settings_with_name">%s-ის მორგება</string>
<string name="invalid_device_name">მოწყობილობის არასწორი სახელი</string>

View File

@@ -178,7 +178,6 @@
<string name="mpris_notifications_explanation">알림 서랍에 원격 미디어를 표시하려면 알림 권한이 필요합니다</string>
<string name="mpris_notification_settings_title">미디어 제어 알림 표시</string>
<string name="mpris_notification_settings_summary">KDE Connect를 열지 않고 미디어 재생기 제어</string>
<string name="share_to">다음으로 공유…</string>
<string name="protocol_version_newer">이 장치의 프로토콜 버전이 더 새롭습니다</string>
<string name="plugin_settings_with_name">%s 설정</string>
<string name="invalid_device_name">잘못된 장치 이름</string>

View File

@@ -194,7 +194,6 @@
</string-array>
<string name="mpris_notification_settings_title">Rodyti įvairialypės terpės valdymo pranešimus</string>
<string name="mpris_notification_settings_summary">Leisti valdyti medijos leistuves neatveriant KDE Connect</string>
<string name="share_to">Bendrinti su…</string>
<string name="protocol_version_newer">Šis įrenginys naudoja naujesnę protokolo versiją</string>
<string name="plugin_settings_with_name">%s nuostatos</string>
<string name="invalid_device_name">Netinkamas įrenginio pavadinimas</string>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2022 Arun Parolikkal <actuday6418@gmail.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
-->
<resources>
<color name="primary">@android:color/system_accent2_300</color>
<color name="primaryDark">@android:color/system_neutral1_900</color>
<color name="accent">@android:color/system_accent2_300</color>
<color name="disabled_grey">#EEEEEE</color>
<color name="on_secondary">@android:color/system_accent1_700</color>
<color name="on_high_contrast">@android:color/system_neutral1_50</color>
<color name="text_color_primary">@android:color/system_neutral2_0</color>
<color name="text_color">@android:color/system_neutral2_50</color>
<color name="toolbar_color">@android:color/system_neutral1_900</color>
<color name="card_stroke_color">@android:color/system_neutral2_800</color>
<color name="activity_background">@android:color/system_neutral1_900</color>
<!-- This is for dark theme. In dark theme both selected and unselected text in the
navigation bar should be white. This is different from the light theme as both states have
different colors so light theme has a selector for this value-->
<color name="state_list_drawer_text">@android:color/white</color>
</resources>

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2020 Anjani Kumar <anjanik012@gmail.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
-->
<resources>
<color name="primaryDark">@android:color/black</color>
<color name="darkGrey">#555555</color>
<color name="darkToolbarBackground">#222222</color>
<color name="darkStatusBarBackground">#333333</color>
<color name="on_secondary">@android:color/black</color>
<color name="on_high_contrast">@android:color/white</color>
<color name="text_color_primary">@android:color/white</color>
<color name="text_color">@android:color/white</color>
<color name="toolbar_color">@android:color/black</color>
<color name="card_stroke_color">#8C8C8C</color>
<color name="activity_background">@android:color/black</color>
<!-- This is for dark theme. In dark theme both selected and unselected text in the
navigation bar should be white. This is different from the light theme as both states have
different colors so light theme has a selector for this value-->
<color name="state_list_drawer_text">@android:color/white</color>
</resources>

View File

@@ -190,7 +190,9 @@
<string name="mpris_notifications_explanation">Het recht op meldingen is nodig om media op afstand te tonen in de meldingenschuiflade</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="share_to">Delen met...</string>
<string name="share_to">Delen met</string>
<string name="unreachable_device">%s (niet bereikbaar)</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_newer">Dit apparaat gebruikt een nieuwere protocolversie</string>
<string name="plugin_settings_with_name">Instellingen van %s</string>
<string name="invalid_device_name">Ongeldige apparaatnaam</string>
@@ -410,4 +412,8 @@
<string name="receive_notifications_permission_explanation">Meldingen moeten toegestaan worden om ze te ontvangen van andere apparaten</string>
<string name="findmyphone_notifications_explanation">Het recht op meldingen is nodig zodat de telefoon af kan gaan wanneer de toepassing in de achtergrond is</string>
<string name="no_notifications">Meldingen zijn uitgeschakeld, u zult inkomende paringmeldingen ontvangen.</string>
<string name="mpris_keepwatching">Doorgaan met afspelen</string>
<string name="mpris_keepwatching_settings_title">Doorgaan met afspelen</string>
<string name="mpris_keepwatching_settings_summary">Een stille melding tonen om door te gaan met afspelen op dit apparaat na sluiten van het medium</string>
<string name="notification_channel_keepwatching">Doorgaan met afspelen</string>
</resources>

View File

@@ -190,6 +190,7 @@
<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="share_to">Del til </string>
<string name="unreachable_device">%s (får ikkje kontakt med)</string>
<string name="protocol_version_newer">Denne eininga brukar ein nyare protokollversjon</string>
<string name="plugin_settings_with_name">%s-innstillingar</string>
<string name="invalid_device_name">Ugyldig einingsnamn</string>
@@ -402,4 +403,6 @@
<string name="plugin_stats">Programtillegg-statistikk</string>
<string name="enable_udp_broadcast">Slå på einingsoppdaging via UDP</string>
<string name="receive_notifications_permission_explanation">Du må tillata varslingar for å kunna frå varslingar frå andre einingar</string>
<string name="mpris_keepwatching_settings_title">Hald fram avspeling</string>
<string name="notification_channel_keepwatching">Hald fram avspeling</string>
</resources>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2022 Arun Parolikkal <actuday6418@gmail.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
-->
<resources>
<color name="primary">@android:color/system_accent2_500</color>
<color name="primaryDark">@android:color/system_neutral1_50</color>
<color name="accent">@android:color/system_accent2_500</color>
<color name="disabled_grey">#EEEEEE</color>
<color name="on_secondary">@android:color/system_accent1_200</color>
<color name="on_high_contrast">@android:color/system_accent1_700</color>
<color name="text_color_primary">@android:color/system_accent2_700</color>
<color name="text_color">@android:color/system_neutral2_700</color>
<color name="toolbar_color">@android:color/system_neutral1_50</color>
<color name="card_stroke_color">@android:color/system_neutral2_100</color>
<color name="activity_background">@android:color/system_neutral1_50</color>
</resources>

View File

@@ -206,7 +206,6 @@
<string name="mpris_notifications_explanation">Uprawnienia powiadomień są potrzebne, aby móc pokazywać zdalne odtwarzacze na belce powiadomień</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="share_to">Udostępnij urządzeniu...</string>
<string name="protocol_version_newer">Urządzenie to używa nowszej wersji protokołu</string>
<string name="plugin_settings_with_name">Ustawienia %s</string>
<string name="invalid_device_name">Nieprawidłowa nazwa urządzenia</string>

View File

@@ -184,7 +184,6 @@
</string-array>
<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="share_to">Compartilhar com...</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="invalid_device_name">Nome do dispositivo inválido</string>

View File

@@ -183,7 +183,6 @@
</string-array>
<string name="mpris_notification_settings_title">Mostrar a notificação do controlo multimédia</string>
<string name="mpris_notification_settings_summary">Permite controlar os seus leitores multimédia sem abrir o KDE Connect</string>
<string name="share_to">Partilhar Com...</string>
<string name="protocol_version_newer">Este dispositivo usa uma versão mais recente do protocolo</string>
<string name="plugin_settings_with_name">Configuração do %s</string>
<string name="invalid_device_name">Nome do dispositivo inválido</string>

View File

@@ -194,7 +194,6 @@
<string name="mpris_notifications_explanation">Permisiunea pentru notificări e necesară pentru a arăta piesele distante în sertarul cu notificări</string>
<string name="mpris_notification_settings_title">Arată notificare cu control multimedia</string>
<string name="mpris_notification_settings_summary">Permite controlul lectorilor multimedia fără a deschide KDE Connect</string>
<string name="share_to">Partajează cu...</string>
<string name="protocol_version_newer">Acest dispozitiv folosește o versiune mai nouă a protocolului</string>
<string name="plugin_settings_with_name">Configurări „%s”</string>
<string name="invalid_device_name">Denumire nevalidă a dispozitivului</string>

File diff suppressed because one or more lines are too long

View File

@@ -184,7 +184,6 @@
</string-array>
<string name="mpris_notification_settings_title">Zobraziť upozornenie ovládania médií</string>
<string name="mpris_notification_settings_summary">Umožní ovládanie vašich multimediálnych prehrávačov bez otvorenia aplikácie KDE Connect</string>
<string name="share_to">Zdieľať do…</string>
<string name="protocol_version_newer">Toto zariadenie používa novšiu verziu protokolu</string>
<string name="plugin_settings_with_name">Nastavenia modulu %s</string>
<string name="invalid_device_name">Neplatný názov zariadenia</string>

View File

@@ -131,14 +131,14 @@
<item quantity="other">Prejemanje %1$d datotek od %2$s</item>
</plurals>
<plurals name="incoming_files_text">
<item quantity="one">(Datoteke %2$d od %3$d) : %1$s</item>
<item quantity="one">(Datotek %2$d od %3$d) : %1$s</item>
<item quantity="two">(Datoteka %2$d od %3$d) : %1$s</item>
<item quantity="few">(Datoteki %2$d od %3$d) : %1$s</item>
<item quantity="other">(Datoteke %2$d od %3$d) : %1$s</item>
</plurals>
<plurals name="outgoing_file_title">
<item quantity="one">Pošiljanje %1$d datoteke na %2$s</item>
<item quantity="two">Pošiljanje %1$d datotek na %2$s</item>
<item quantity="one">Pošiljanje %1$d datotek na %2$s</item>
<item quantity="two">Pošiljanje %1$d datoteke na %2$s</item>
<item quantity="few">Pošiljanje %1$d datotek na %2$s</item>
<item quantity="other">Pošiljanje %1$d datotek na %2$s</item>
</plurals>
@@ -207,6 +207,8 @@
<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="share_to">Deli z…</string>
<string name="unreachable_device">%s (Nedosegljiva)</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_newer">Ta naprava uporablja novejšo različico protokola</string>
<string name="plugin_settings_with_name">Nastavitve %s</string>
<string name="invalid_device_name">Neveljavno ime naprave</string>
@@ -426,4 +428,8 @@
<string name="receive_notifications_permission_explanation">Morate imeti dovoljenje za obvestila, če jih želite sprejemati iz drugih naprav</string>
<string name="findmyphone_notifications_explanation">Potrebno je dovoljenje za obvestila, da lahko telefon zazvoni, ko je aplikacija v ozadju</string>
<string name="no_notifications">Obvestila so onemogočena, ne boste prejemali obvestil o dohodnih parih.</string>
<string name="mpris_keepwatching">Nadaljuj s predvajanjem</string>
<string name="mpris_keepwatching_settings_title">Nadaljuj s predvajanjem</string>
<string name="mpris_keepwatching_settings_summary">Pokaži tiho obvestilo za nadaljevanje predvajanja v tej napravi po zaprtju predstavnosti</string>
<string name="notification_channel_keepwatching">Nadaljuj s predvajanjem</string>
</resources>

View File

@@ -18,6 +18,7 @@
<string name="pref_plugin_clipboard_sent">Klippbordet skickat</string>
<string name="pref_plugin_mousepad">Extern inmatning</string>
<string name="pref_plugin_mousepad_desc">Använd telefonen eller surfplattan som mus och tangentbord</string>
<string name="pref_plugin_presenter">Fjärrkontroll för presentation</string>
<string name="pref_plugin_presenter_desc">Använd apparaten för att byta bilder i en presentation</string>
<string name="pref_plugin_remotekeyboard">Ta emot externa tangentnedtryckningar</string>
<string name="pref_plugin_remotekeyboard_desc">Ta emot tangentnedtryckningar från externa apparater</string>
@@ -51,6 +52,7 @@
<string name="remotekeyboard_multiple_connections">Det finns mer än en anslutning till externt tangentbord, välj apparat att anpassa</string>
<string name="open_mousepad">Extern inmatning</string>
<string name="mousepad_info">Flytta fingret på skärmen för att röra muspekaren. Rör för att klicka, och använd två eller tre fingrar för höger- och mittenknapparna. Använd två fingrar för att panorera. Använd en längre beröring för drag och släpp. Musens gyroskopiska funktion kan aktiveras från insticksprogrammets inställningar.</string>
<string name="mousepad_info_no_gestures">Flytta ett finger på skärmen för att flytta muspekaren, rör för att klicka.</string>
<string name="mousepad_keyboard_input_not_supported">Tangentbordsinmatning stöds inte av den ihopparade apparaten</string>
<string name="mousepad_single_tap_settings_title">Ställ in åtgärd vid en fingerberöring</string>
<string name="mousepad_double_tap_settings_title">Ställ in åtgärd vid två fingerberöringar</string>
@@ -59,6 +61,7 @@
<string name="mousepad_mouse_buttons_title">Visa musknappar</string>
<string name="mousepad_acceleration_profile_settings_title">Ställ in pekaracceleration</string>
<string name="mousepad_scroll_direction_title">Omvänd rullningsriktning</string>
<string name="mousepad_scroll_sensitivity_title">Rullningskänslighet</string>
<string name="gyro_mouse_enabled_title">Aktivera gyroskopisk mus</string>
<string name="gyro_mouse_sensitivity_title">Gyroskop-känslighet</string>
<string-array name="mousepad_tap_entries">
@@ -119,6 +122,7 @@
<string name="my_device_fingerprint">SHA256-fingeravtryck för din apparats certifikat är:</string>
<string name="remote_device_fingerprint">SHA256-fingeravtryck för den andra apparatens certifikat är:</string>
<string name="pair_requested">Ihopparning begärd</string>
<string name="pair_succeeded">Ihopparning lyckades</string>
<string name="pairing_request_from">Begäran om ihopparning från %1s</string>
<plurals name="incoming_file_title">
<item quantity="one">Tar emot %1$d fil från %2$s</item>
@@ -156,6 +160,7 @@
<string name="received_file_text">Rör för att öppna \'%1s\'</string>
<string name="cannot_create_file">Kan inte skapa filen %s</string>
<string name="tap_to_answer">Rör för att svara</string>
<string name="left_click">Skicka vänsterklick</string>
<string name="right_click">Skicka högerklick</string>
<string name="middle_click">Skicka mittenklick</string>
<string name="show_keyboard">Visa tangentbord</string>
@@ -186,6 +191,8 @@
<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="share_to">Dela med…</string>
<string name="unreachable_device">%s (kan inte nå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="protocol_version_newer">Apparaten använder en nyare protokollversion</string>
<string name="plugin_settings_with_name">Inställningar av %s</string>
<string name="invalid_device_name">Ogiltigt apparatnamn</string>
@@ -405,4 +412,8 @@
<string name="receive_notifications_permission_explanation">Underrättelser måste vara tillåtna för att kunna ta emot dem från andra apparater</string>
<string name="findmyphone_notifications_explanation">Underrättelserättigheter krävs så att telefonen kan ringa när programmet är i bakgrunden</string>
<string name="no_notifications">Underrättelser är inaktiverade, så en underrättelse om inkommande begäran att para ihop inte tas emot.</string>
<string name="mpris_keepwatching">Fortsätt spela</string>
<string name="mpris_keepwatching_settings_title">Fortsätt spela</string>
<string name="mpris_keepwatching_settings_summary">Visa en tyst underrättelse för att fortsätta spela på apparaten efter att media har stängts.</string>
<string name="notification_channel_keepwatching">Fortsätt spela</string>
</resources>

View File

@@ -186,7 +186,6 @@
<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="protocol_version_newer">இச்சாதனம் புதிய நெறிமுறை பதிப்பைப் பயன்படுத்துகிறது</string>
<string name="plugin_settings_with_name">%s அமைப்புகள்</string>
<string name="invalid_device_name">முறையற்ற சாதன பெயர்</string>

View File

@@ -190,7 +190,9 @@
<string name="mpris_notifications_explanation">Bildirim izni, bildirim çekmecesinde uzak konum ortamını göstermek için gereklidir</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="share_to">Paylaş…</string>
<string name="share_to">Şuraya Paylaş…</string>
<string name="unreachable_device">%s (Erişilebilir değil)</string>
<string name="unreachable_device_url_share_text">Erişilemeyen bir aygıta gönderilen URLler, aygıt erişilebilir olduğunda teslim edilir.\n\n</string>
<string name="protocol_version_newer">Bu aygıt, daha yeni bir protokol sürümü kullanıyor</string>
<string name="plugin_settings_with_name">%s ayarları</string>
<string name="invalid_device_name">Geçersiz aygıt adı</string>
@@ -410,4 +412,8 @@
<string name="receive_notifications_permission_explanation">Başka aygıtlardan gelen bildirimleri alabilmek için bildirimlere izin verilmesi gereklidir</string>
<string name="findmyphone_notifications_explanation">Uygulama arka plandayken telefonun çalabilmesi için bildirim izni gereklidir</string>
<string name="no_notifications">Bildirimler devre dışı; herhangi bir gelen eş bildirimi almayacaksınız.</string>
<string name="mpris_keepwatching">Oynamayı Sürdür</string>
<string name="mpris_keepwatching_settings_title">Oynamayı Sürdür</string>
<string name="mpris_keepwatching_settings_summary">Ortamı kapattıktan sonra bu aygıtta oynatmayı sürdürmek için sessiz bir bildirim göster</string>
<string name="notification_channel_keepwatching">Oynamayı Sürdür</string>
</resources>

View File

@@ -206,7 +206,9 @@
<string name="mpris_notifications_explanation">Для показу віддалених носіїв даних на панелі сповіщень потрібні права доступу до сповіщень</string>
<string name="mpris_notification_settings_title">Показувати сповіщення щодо керування відтворенням</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">Адреси, які оприлюднено на недоступному пристрої, буде надіслано, щойно пристрій стане доступним.\n\n</string>
<string name="protocol_version_newer">На цьому пристрої використовується новіша версія протоколу</string>
<string name="plugin_settings_with_name">Параметри %s</string>
<string name="invalid_device_name">Некоректна назва пристрою</string>
@@ -426,4 +428,8 @@
<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>
</resources>

View File

@@ -182,7 +182,9 @@
<string name="mpris_notifications_explanation">在通知栏中显示远程媒体需要通知权限</string>
<string name="mpris_notification_settings_title">显示媒体控制通知</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</string>
<string name="protocol_version_newer">此设备使用较新版本的协议</string>
<string name="plugin_settings_with_name">%s设置</string>
<string name="invalid_device_name">无效的设备名</string>

View File

@@ -182,7 +182,6 @@
<string name="mpris_notifications_explanation">需要通知權限來在通知欄內顯示遠端媒體</string>
<string name="mpris_notification_settings_title">顯示媒體控制項通知</string>
<string name="mpris_notification_settings_summary">允許控制您的媒體播放器而不需要開啟 KDE 連線</string>
<string name="share_to">分享給…</string>
<string name="protocol_version_newer">此裝置使用較新的通訊協定</string>
<string name="plugin_settings_with_name">%s 設定</string>
<string name="invalid_device_name">無效的裝置名稱</string>

View File

@@ -6,12 +6,9 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<resources>
<!-- A high-contrast color for important visual elements (for less important elements, use colorControlNormal instead) -->
<attr name="colorHighContrast" format="color" />
<declare-styleable name="AutoGridLayout">
<!-- The width of one column. Used to align -->
<attr name="columnWidth" format="dimension" />
<!-- I think that everything is clear from the name -->
<attr name="changeColumnCountIfTheyHaveOnlyOneElement" format="boolean" />
</declare-styleable>

View File

@@ -1,21 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2020 Anjani Kumar <anjanik012@gmail.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
-->
<resources>
<color name="primary">#F67400</color>
<color name="primaryDark">@android:color/white</color>
<color name="accent">#F67400</color>
<color name="disabled_grey">#EEEEEE</color>
<color name="on_secondary">#C8C8C8</color>
<color name="on_high_contrast">@android:color/black</color>
<color name="text_color_primary">@android:color/black</color>
<color name="text_color">@android:color/black</color>
<color name="toolbar_color">@android:color/white</color>
<color name="card_stroke_color">#C8C8C8</color>
<color name="activity_background">@android:color/white</color>
<color name="launcher_background">#3daee9</color>
<!-- Whenever possible, don't hardcode colors here and rely on the default ones (eg: from the system or user theme) -->
</resources>

View File

@@ -261,7 +261,9 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<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_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_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="plugin_settings_with_name">%s settings</string>
<string name="invalid_device_name">Invalid device name</string>
@@ -567,4 +569,11 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<string name="findmyphone_notifications_explanation">The notifications permission is needed so the phone can ring when the app is in the background</string>
<string name="no_notifications">Notifications are disabled, you won\'t receive incoming pair notifications.</string>
<string name="mpris_keepwatching">Continue playing</string>
<string name="mpris_keepwatching_key" translatable="false">mpris_keepwatching_enabled</string>
<string name="mpris_keepwatching_settings_title">Continue playing</string>
<string name="mpris_keepwatching_settings_summary">Show a silent notification to continue playing on this device after closing media</string>
<string name="notification_channel_keepwatching">Continue playing</string>
</resources>

View File

@@ -8,28 +8,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<!-- NoActionBar because we use a Toolbar widget as ActionBar -->
<style name="KdeConnectThemeBase" parent="Theme.Material3.DayNight.NoActionBar">
<!-- The main color attributes -->
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primaryDark</item>
<item name="colorSecondary">@color/primary</item>
<item name="colorOnSecondary">@color/on_secondary</item>
<item name="colorHighContrast">@color/on_high_contrast</item>
<!-- TODO: The 2 items below change too much (eg snackbar text is now black, should be white) -->
<item name="android:textColorPrimary">@color/text_color_primary</item>
<item name="android:textColor">@color/text_color</item>
<!--For android below 23 api-->
<item name="android:statusBarColor">@android:color/black</item>
<!-- Drawable definitions and overrides -->
<item name="divider">?colorHighContrast</item>
<!-- Style overrides -->
<item name="actionModeStyle">@style/Widget.Material3.ActionMode</item>
<item name="toolbarStyle">@style/Widget.Material3.Toolbar</item>
<!-- Theme overrides -->
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.DayNight</item>
<item name="materialCardViewStyle">@style/KdeConnectCardStyle</item>
@@ -47,13 +26,11 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<style name="KdeConnectTheme.NoActionBar" parent="KdeConnectThemeBase.NoActionBar" />
<style name="KdeConnectTheme.Toolbar" parent="Widget.AppCompat.Toolbar">
<item name="android:background">@color/toolbar_color</item>
</style>
<style name="KdeConnectDialogStyle" parent="ThemeOverlay.Material3.MaterialAlertDialog">
<item name="android:layout" tools:ignore="PrivateResource">@layout/m3_alert_dialog</item>
<item name="dialogCornerRadius" tools:ignore="PrivateResource">@dimen/m3_alert_dialog_corner_size</item>
<item name="android:colorBackground">?colorSurface</item>
</style>
<style name="KdeConnectCardStyle" parent="@style/Widget.Material3.CardView.Elevated"/>
@@ -61,14 +38,6 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<style name="KdeConnectCardStyle.Filled" parent="@style/Widget.Material3.CardView.Filled"/>
<style name="MainNavigationView">
<item name="android:background">@drawable/state_list_drawer_background</item>
<item name="itemBackground">@drawable/state_list_drawer_background</item>
<item name="itemIconTint">@color/state_list_drawer_text</item>
<item name="itemTextColor">@color/state_list_drawer_text</item>
</style>
<style name="DisableableButton" parent="ThemeOverlay.AppCompat">
<item name="colorButtonNormal">@drawable/disableable_button</item>
</style>
<style name="KdeConnectButton.IconButton" parent="Widget.Material3.Button.IconButton.Filled">
@@ -82,7 +51,6 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
</style>
<style name="ActionModeStyle" parent="Widget.AppCompat.ActionMode">
<item name="background">@color/primaryDark</item>
</style>
<style name="Theme.Transparent" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
@@ -106,6 +74,5 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<item name="android:drawablePadding">4dp</item>
<item name="android:gravity">center</item>
<item name="android:textSize">12sp</item>
<item name="drawableTint">@color/text_color</item>
</style>
</resources>

View File

@@ -28,4 +28,11 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:summary="@string/mpris_notification_settings_summary"
android:title="@string/mpris_notification_settings_title" />
<SwitchPreference
android:id="@+id/mpris_keepwatching_preference"
android:defaultValue="true"
android:key="@string/mpris_keepwatching_key"
android:summary="@string/mpris_keepwatching_settings_summary"
android:title="@string/mpris_keepwatching_settings_title" />
</PreferenceScreen>

View File

@@ -136,6 +136,11 @@ class BluetoothLinkProvider(private val context: Context) : BaseLinkProvider() {
return
} catch (e: SecurityException) {
Log.e("KDEConnect", "Security Exception for CONNECT", e)
val prefenceEditor = PreferenceManager.getDefaultSharedPreferences(context).edit()
prefenceEditor.putBoolean(SettingsFragment.KEY_BLUETOOTH_ENABLED, false)
prefenceEditor.apply()
return
}
try {
@@ -231,21 +236,25 @@ class BluetoothLinkProvider(private val context: Context) : BaseLinkProvider() {
}
override fun run() {
Log.i("ClientRunnable", "run called")
val filter = IntentFilter(BluetoothDevice.ACTION_UUID)
context.registerReceiver(this, filter)
Log.i("ClientRunnable", "receiver registered")
if (continueProcessing) {
Log.i("ClientRunnable", "before connectToDevices")
discoverDeviceServices()
Log.i("ClientRunnable", "after connectToDevices")
try {
Thread.sleep(15000)
} catch (ignored: InterruptedException) {
try {
Log.i("ClientRunnable", "run called")
val filter = IntentFilter(BluetoothDevice.ACTION_UUID)
context.registerReceiver(this, filter)
Log.i("ClientRunnable", "receiver registered")
if (continueProcessing) {
Log.i("ClientRunnable", "before connectToDevices")
discoverDeviceServices()
Log.i("ClientRunnable", "after connectToDevices")
try {
Thread.sleep(15000)
} catch (ignored: InterruptedException) {
}
}
Log.i("ClientRunnable", "unregisteringReceiver")
context.unregisterReceiver(this)
} catch (se: SecurityException) {
Log.w("BluetoothLinkProvider", se)
}
Log.i("ClientRunnable", "unregisteringReceiver")
context.unregisterReceiver(this)
}
/**

View File

@@ -414,7 +414,7 @@ public class LanLinkProvider extends BaseLinkProvider {
DatagramSocket socket;
try {
socket = new DatagramSocket();
if (network != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
if (network != null) {
try {
network.bindSocket(socket);
} catch (IOException e) {

View File

@@ -241,6 +241,8 @@ public class Device implements BaseLink.PacketReceiver {
cb.unpaired();
}
notifyPluginsOfDeviceUnpaired(context, deviceInfo.id);
reloadPluginsFromSettings();
}
};
@@ -358,7 +360,11 @@ public class Device implements BaseLink.PacketReceiver {
if (deviceInfo.outgoingCapabilities != newDeviceInfo.outgoingCapabilities ||
deviceInfo.incomingCapabilities != newDeviceInfo.incomingCapabilities) {
if (newDeviceInfo.outgoingCapabilities != null && newDeviceInfo.incomingCapabilities != null) {
if (newDeviceInfo.outgoingCapabilities != null
&& !newDeviceInfo.outgoingCapabilities.isEmpty()
&& newDeviceInfo.incomingCapabilities != null
&& !newDeviceInfo.incomingCapabilities.isEmpty()
) {
hasChanges = true;
Log.i("updateDeviceInfo", "Updating supported plugins according to new capabilities");
supportedPlugins = new Vector<>(PluginFactory.pluginsForCapabilities(newDeviceInfo.incomingCapabilities, newDeviceInfo.outgoingCapabilities));
@@ -474,7 +480,8 @@ public class Device implements BaseLink.PacketReceiver {
if (packetQueue == null) {
callback.onFailure(new Exception("Device disconnected!"));
} else {
packetQueue.addPacket(np, replaceID, callback);
// TODO: Migrate to coroutine version (addPacket)
packetQueue.addPacketSync(np, replaceID, callback);
}
}
@@ -488,7 +495,8 @@ public class Device implements BaseLink.PacketReceiver {
if (packetQueue == null) {
return null;
} else {
return packetQueue.getAndRemoveUnsentPacket(replaceID);
// TODO: Migrate to coroutine version (getAndRemoveUnsentPacket)
return packetQueue.getAndRemoveUnsentPacketSync(replaceID);
}
}
@@ -639,6 +647,25 @@ public class Device implements BaseLink.PacketReceiver {
return settings.getBoolean(pluginKey, enabledByDefault);
}
public void notifyPluginsOfDeviceUnpaired(Context context, String deviceId) {
for (String pluginKey : supportedPlugins) {
Plugin plugin = getPlugin(pluginKey);
if (plugin != null) {
plugin.onDeviceUnpaired(context, deviceId);
} else {
// This is a hacky way to temporarily create plugins just so that they can be notified of the
// device being unpaired. This else part will only come into picture when 1) the user tries to
// unpair a device while that device is not reachable or 2) the plugin was never initialized
// for this device, e.g., the plugins that need additional permissions from the user, and those
// permissions were never granted.
plugin = PluginFactory.instantiatePluginForDevice(context, pluginKey, this);
if (plugin != null) {
plugin.onDeviceUnpaired(context, deviceId);
}
}
}
}
public void reloadPluginsFromSettings() {
Log.i("Device", deviceInfo.name +": reloading plugins");
MultiValuedMap<String, String> newPluginsByIncomingInterface = new ArrayListValuedHashMap<>();

View File

@@ -89,7 +89,7 @@ class DeviceInfo(
fun fromIdentityPacketAndCert(identityPacket: NetworkPacket, certificate: Certificate) =
with(identityPacket) {
DeviceInfo(
id = getString("deviceId"),
id = getString("deviceId"), // Redundant: We could read this from the certificate instead
name = getString("deviceName", "unknown"),
type = DeviceType.fromString(getString("deviceType", "desktop")),
certificate = certificate,

View File

@@ -1,142 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019 Matthijs Tijink <matthijstijink@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
package org.kde.kdeconnect;
import android.util.Log;
import org.kde.kdeconnect.Helpers.ThreadHelper;
import java.util.ArrayDeque;
import java.util.Optional;
/**
* Keeps a queue of packets to send to a device, to prevent either blocking or using lots of threads
*/
class DevicePacketQueue {
/**
* Holds the packet and related stuff to keep in the queue
*/
private static final class Item {
NetworkPacket packet;
/**
* Replacement ID: if positive, it can be replaced by later packets with the same ID
*/
final int replaceID;
Device.SendPacketStatusCallback callback;
Item(NetworkPacket packet, int replaceID, Device.SendPacketStatusCallback callback) {
this.packet = packet;
this.callback = callback;
this.replaceID = replaceID;
}
}
private final ArrayDeque<Item> items = new ArrayDeque<>();
private final Device mDevice;
private final Object lock = new Object();
private boolean exit = false;
DevicePacketQueue(Device device) {
this(device, true);
}
DevicePacketQueue(Device device, Boolean startThread) {
mDevice = device;
if (startThread) {
ThreadHelper.execute(new SendingRunnable());
}
}
/**
* Send a packet (at some point in the future)
* @param packet The packet
* @param replaceID If positive, it will replace all older packets still in the queue
* @param callback The callback after sending the packet
*/
void addPacket(NetworkPacket packet, int replaceID, Device.SendPacketStatusCallback callback) {
synchronized (lock) {
if (exit) {
callback.onFailure(new Exception("Device disconnected!"));
} else {
boolean replaced = false;
if (replaceID >= 0) {
for (Item item : items) {
if (item.replaceID == replaceID) {
item.packet = packet;
item.callback = callback;
replaced = true;
break;
}
}
}
if (!replaced) {
items.addLast(new Item(packet, replaceID, callback));
lock.notify();
}
}
}
}
/**
* Check if we still have an unsent packet in the queue with the given ID.
* If so, remove it from the queue and return it
* @param replaceID The replace ID (must be positive)
* @return The found packet, or null
*/
NetworkPacket getAndRemoveUnsentPacket(int replaceID) {
synchronized (lock) {
final Optional<Item> itemOptional = items.stream()
.filter(item -> item.replaceID == replaceID).findFirst();
if (itemOptional.isPresent()) {
final Item item = itemOptional.get();
items.remove(item);
return item.packet;
}
}
return null;
}
void disconnected() {
synchronized (lock) {
exit = true;
lock.notifyAll();
}
}
private final class SendingRunnable implements Runnable {
@Override
public void run() {
while (true) {
Item item;
synchronized (lock) {
while (items.isEmpty() && !exit) {
try {
lock.wait();
} catch (InterruptedException ignored) {
}
}
if (exit) {
Log.i("DevicePacketQueue", "Terminating sending loop");
break;
}
item = items.removeFirst();
}
mDevice.sendPacketBlocking(item.packet, item.callback);
}
while (!items.isEmpty()) {
Item item = items.removeFirst();
item.callback.onFailure(new Exception("Device disconnected!"));
}
}
}
}

View File

@@ -0,0 +1,131 @@
/*
* SPDX-FileCopyrightText: 2019 Matthijs Tijink <matthijstijink@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
package org.kde.kdeconnect
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlin.collections.ArrayDeque
/**
* Keeps a queue of packets to send to a device, to prevent either blocking or using lots of threads
*/
class DevicePacketQueue @JvmOverloads constructor(private val device: Device, startRunning: Boolean = true) {
/**
* Holds the packet and related stuff to keep in the queue
*/
private class Item(
var packet: NetworkPacket,
/**
* Replacement ID: if positive, it can be replaced by later packets with the same ID
*/
val replaceID: Int,
var callback: Device.SendPacketStatusCallback
)
private val scope = CoroutineScope(Dispatchers.IO)
private val sendingJob = SupervisorJob()
private val loopJob = Job()
private val items = ArrayDeque<Item>()
private val mutex = Mutex()
init {
if (startRunning) {
scope.launch(loopJob) {
sending()
}
}
}
fun addPacketSync(packet: NetworkPacket, replaceID: Int, callback: Device.SendPacketStatusCallback) {
runBlocking {
addPacket(packet, replaceID, callback)
}
}
/**
* Send a packet (at some point in the future)
* @param packet The packet
* @param replaceID If positive, it will replace all older packets still in the queue
* @param callback The callback after sending the packet
*/
suspend fun addPacket(packet: NetworkPacket, replaceID: Int, callback: Device.SendPacketStatusCallback) {
if (sendingJob.isCancelled) {
callback.onFailure(Exception("Device disconnected!"))
} else {
mutex.withLock {
var replaced = false
if (replaceID >= 0) {
items.forEach {
if (it.replaceID == replaceID) {
it.packet = packet
it.callback = callback
replaced = true
}
}
}
if (!replaced) {
items.addLast(Item(packet, replaceID, callback))
}
}
}
}
fun getAndRemoveUnsentPacketSync(replaceID: Int): NetworkPacket? {
return runBlocking {
getAndRemoveUnsentPacket(replaceID)
}
}
/**
* Check if we still have an unsent packet in the queue with the given ID.
* If so, remove it from the queue and return it
* @param replaceID The replace ID (must be positive)
* @return The found packet, or null
*/
suspend fun getAndRemoveUnsentPacket(replaceID: Int): NetworkPacket? {
mutex.withLock {
val itemOptional = items.stream()
.filter { item: Item -> item.replaceID == replaceID }.findFirst()
if (itemOptional.isPresent) {
val item = itemOptional.get()
items.remove(item)
return item.packet
}
}
return null
}
fun disconnected() {
sendingJob.cancel()
}
private suspend fun sending() {
while (true) {
val item = mutex.withLock {
if (items.isEmpty()) {
null
} else {
items.removeFirst()
}
}
if (item == null) {
yield()
continue
}
if (sendingJob.isCancelled) {
item.callback.onFailure(Exception("Device disconnected!"))
} else {
scope.launch(sendingJob) {
device.sendPacketBlocking(item.packet, item.callback)
}
}
}
}
}

View File

@@ -1,49 +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.Helpers;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.util.Log;
public class AppsHelper {
public static String appNameLookup(Context context, String packageName) {
try {
PackageManager pm = context.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
return pm.getApplicationLabel(ai).toString();
} catch (final PackageManager.NameNotFoundException e) {
Log.e("AppsHelper", "Could not resolve name " + packageName, e);
return null;
}
}
public static Drawable appIconLookup(Context context, String packageName) {
try {
PackageManager pm = context.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
return pm.getApplicationIcon(ai);
} catch (final PackageManager.NameNotFoundException e) {
Log.e("AppsHelper", "Could not find icon for " + packageName, e);
return null;
}
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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.Helpers
import android.content.Context
import android.content.pm.PackageManager
import android.util.Log
object AppsHelper {
@JvmStatic
fun appNameLookup(context: Context, packageName: String): String? {
return try {
val manager = context.packageManager
val info = manager.getApplicationInfo(packageName, 0)
manager.getApplicationLabel(info).toString()
} catch (e: PackageManager.NameNotFoundException) {
Log.e("AppsHelper", "Could not resolve name $packageName", e)
null
}
}
}

View File

@@ -35,6 +35,8 @@ public class NotificationHelper {
public final static String RECEIVENOTIFICATION = "receive";
public final static String HIGHPRIORITY = "highpriority";
public final static String CONTINUEWATCHING = "continuewatching";
}
public static void notifyCompat(NotificationManager notificationManager, int notificationId, Notification notification) {
@@ -87,14 +89,23 @@ public class NotificationHelper {
.Builder(Channels.RECEIVENOTIFICATION, NotificationManagerCompat.IMPORTANCE_DEFAULT)
.setName(context.getString(R.string.notification_channel_receivenotification))
.build();
final NotificationChannelCompat highPriorityChannel = new NotificationChannelCompat
final NotificationChannelCompat continueWatchingChannel = new NotificationChannelCompat
.Builder(Channels.HIGHPRIORITY, NotificationManagerCompat.IMPORTANCE_HIGH)
.setName(context.getString(R.string.notification_channel_high_priority))
.build();
/* This notification should be highly visible *only* if the user looks at their phone */
/* It should not be a distraction. It should be a convenient button to press */
final NotificationChannelCompat highPriorityChannel = new NotificationChannelCompat
.Builder(Channels.CONTINUEWATCHING, NotificationManagerCompat.IMPORTANCE_HIGH)
.setName(context.getString(R.string.notification_channel_keepwatching))
.setVibrationEnabled(false)
.setLightsEnabled(false)
.setSound(null, null)
.build();
final List<NotificationChannelCompat> channels = Arrays.asList(persistentChannel,
defaultChannel, mediaChannel, fileTransferDownloadChannel, fileTransferUploadChannel,
fileTransferErrorChannel, receiveNotificationChannel, highPriorityChannel);
fileTransferErrorChannel, receiveNotificationChannel, highPriorityChannel,
continueWatchingChannel);
NotificationManagerCompat.from(context).createNotificationChannelsCompat(channels);
@@ -102,7 +113,7 @@ public class NotificationHelper {
// Use this to deprecate old channels.
NotificationManagerCompat.from(context).deleteUnlistedNotificationChannels(
channels.stream()
.map(notificationChannelCompat -> notificationChannelCompat.getId())
.map(NotificationChannelCompat::getId)
.collect(Collectors.toList()));
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
package org.kde.kdeconnect.Helpers.SecurityHelpers
fun constantTimeCompare(a: ByteArray, b: ByteArray): Boolean {
if (a.size != b.size) {
return false
}
var result = 0
for (i in a.indices) {
result = result or (a[i].toInt() xor b[i].toInt())
}
return result == 0
}

View File

@@ -35,16 +35,10 @@ public class RsaHelper {
String keyAlgorithm;
try {
KeyPairGenerator keyGen;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
keyAlgorithm = KeyProperties.KEY_ALGORITHM_EC;
keyGen = KeyPairGenerator.getInstance(keyAlgorithm);
ECGenParameterSpec spec = new ECGenParameterSpec("secp256r1");
keyGen.initialize(spec);
} else {
keyAlgorithm = "RSA";
keyGen = KeyPairGenerator.getInstance(keyAlgorithm);
keyGen.initialize(2048);
}
keyAlgorithm = KeyProperties.KEY_ALGORITHM_EC;
keyGen = KeyPairGenerator.getInstance(keyAlgorithm);
ECGenParameterSpec spec = new ECGenParameterSpec("secp256r1");
keyGen.initialize(spec);
keyPair = keyGen.generateKeyPair();
} catch (Exception e) {
Log.e("KDE/initializeRsaKeys", "Exception", e);

View File

@@ -37,7 +37,6 @@ public class TelephonyHelper {
* Get all subscriptionIDs of the device
* As far as I can tell, this is essentially a way of identifying particular SIM cards
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
public static List<Integer> getActiveSubscriptionIDs(
@NonNull Context context)
throws SecurityException {
@@ -73,7 +72,6 @@ public class TelephonyHelper {
* This lets you identify additions/removals of SIM cards.
* Make sure to call `cancelActiveSubscriptionIDsListener` with the return value of this once you're done.
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
public static OnSubscriptionsChangedListener listenActiveSubscriptionIDs(
@NonNull Context context, SubscriptionCallback onAdd, SubscriptionCallback onRemove) {
SubscriptionManager sm = ContextCompat.getSystemService(context, SubscriptionManager.class);
@@ -117,7 +115,6 @@ public class TelephonyHelper {
/**
* Cancels a listener created by `listenActiveSubscriptionIDs`
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
public static void cancelActiveSubscriptionIDsListener(@NonNull Context context, @NonNull OnSubscriptionsChangedListener listener) {
SubscriptionManager sm = ContextCompat.getSystemService(context, SubscriptionManager.class);
if (sm == null) {
@@ -139,44 +136,26 @@ public class TelephonyHelper {
public static @NonNull List<LocalPhoneNumber> getAllPhoneNumbers(
@NonNull Context context)
throws SecurityException {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
// Single-sim case
// From https://stackoverflow.com/a/25131061/3723163
// Android added support for multi-sim devices in Lollypop v5.1 (api 22)
// See: https://developer.android.com/about/versions/android-5.1.html#multisim
// There were vendor-specific implmentations before then, but those are very difficult to support
// S/O Reference: https://stackoverflow.com/a/28571835/3723163
TelephonyManager telephonyManager = ContextCompat.getSystemService(context,
TelephonyManager.class);
if (telephonyManager == null) {
// I don't know why or when this happens...
Log.w(LOGGING_TAG, "Could not get TelephonyManager");
return Collections.emptyList();
}
LocalPhoneNumber phoneNumber = getPhoneNumber(telephonyManager);
return Collections.singletonList(phoneNumber);
} else {
// Potentially multi-sim case
SubscriptionManager subscriptionManager = ContextCompat.getSystemService(context,
SubscriptionManager.class);
if (subscriptionManager == null) {
// I don't know why or when this happens...
Log.w(LOGGING_TAG, "Could not get SubscriptionManager");
return Collections.emptyList();
}
List<SubscriptionInfo> subscriptionInfos = subscriptionManager.getActiveSubscriptionInfoList();
if (subscriptionInfos == null) {
// This happens when there is no SIM card inserted
Log.w(LOGGING_TAG, "Could not get SubscriptionInfos");
return Collections.emptyList();
}
List<LocalPhoneNumber> phoneNumbers = new ArrayList<>(subscriptionInfos.size());
for (SubscriptionInfo info : subscriptionInfos) {
LocalPhoneNumber thisPhoneNumber = new LocalPhoneNumber(info.getNumber(), info.getSubscriptionId());
phoneNumbers.add(thisPhoneNumber);
}
return phoneNumbers.stream().filter(localPhoneNumber -> localPhoneNumber.number != null).collect(Collectors.toList());
// Potentially multi-sim
SubscriptionManager subscriptionManager = ContextCompat.getSystemService(context,
SubscriptionManager.class);
if (subscriptionManager == null) {
// I don't know why or when this happens...
Log.w(LOGGING_TAG, "Could not get SubscriptionManager");
return Collections.emptyList();
}
List<SubscriptionInfo> subscriptionInfos = subscriptionManager.getActiveSubscriptionInfoList();
if (subscriptionInfos == null) {
// This happens when there is no SIM card inserted
Log.w(LOGGING_TAG, "Could not get SubscriptionInfos");
return Collections.emptyList();
}
List<LocalPhoneNumber> phoneNumbers = new ArrayList<>(subscriptionInfos.size());
for (SubscriptionInfo info : subscriptionInfos) {
LocalPhoneNumber thisPhoneNumber = new LocalPhoneNumber(info.getNumber(), info.getSubscriptionId());
phoneNumbers.add(thisPhoneNumber);
}
return phoneNumbers.stream().filter(localPhoneNumber -> localPhoneNumber.number != null).collect(Collectors.toList());
}
/**
@@ -245,14 +224,7 @@ public class TelephonyHelper {
Uri telephonyCarriersUri = Telephony.Carriers.CONTENT_URI;
Uri telephonyCarriersPreferredApnUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
telephonyCarriersPreferredApnUri = Uri.withAppendedPath(telephonyCarriersUri, "/preferapn/subId/" + subscriptionId);
} else {
// Ignore subID for devices before that existed
telephonyCarriersPreferredApnUri = Uri.withAppendedPath(telephonyCarriersUri, "/preferapn/");
}
Uri telephonyCarriersPreferredApnUri = Uri.withAppendedPath(telephonyCarriersUri, "/preferapn/subId/" + subscriptionId);
try (Cursor cursor = context.getContentResolver().query(
telephonyCarriersPreferredApnUri,

View File

@@ -11,13 +11,14 @@ import org.json.JSONObject
import java.io.ByteArrayInputStream
import java.io.IOException
import java.io.InputStream
import java.lang.RuntimeException
import java.net.Socket
import kotlin.concurrent.Volatile
data class NetworkPacket(
class NetworkPacket private constructor(
val id: Long,
val type: String,
val mBody: JSONObject,
private val mBody: JSONObject,
var payload: Payload?,
var payloadTransferInfo: JSONObject,
) {
@@ -42,6 +43,11 @@ data class NetworkPacket(
return mBody.optString(key, "")
}
fun getStringOrNull(key: String): String? {
return if (mBody.has(key)) mBody.getString(key)
else null
}
fun getString(key: String, defaultValue: String): String {
return mBody.optString(key, defaultValue)
}
@@ -211,7 +217,11 @@ data class NetworkPacket(
jo.put("payloadTransferInfo", payloadTransferInfo)
}
// QJSon does not escape slashes, but Java JSONObject does. Converting to QJson format.
return jo.toString().replace("\\/", "/") + "\n"
try {
return jo.toString().replace("\\/", "/") + "\n"
} catch (e : OutOfMemoryError) {
throw RuntimeException("OOM serializing packet of type $type", e)
}
}
val payloadSize: Long

View File

@@ -1,211 +0,0 @@
/*
* 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
*/
package org.kde.kdeconnect;
import android.util.Log;
import org.kde.kdeconnect_tp.R;
import java.util.Timer;
import java.util.TimerTask;
public class PairingHandler {
public enum PairState {
NotPaired,
Requested,
RequestedByPeer,
Paired
}
public interface PairingCallback {
void incomingPairRequest();
void pairingFailed(String error);
void pairingSuccessful();
void unpaired();
}
protected final Device mDevice;
protected PairState mPairState;
protected final PairingCallback mCallback;
public PairState getState() {
return mPairState;
}
private Timer mPairingTimer;
public PairingHandler(Device device, final PairingCallback callback, PairState initialState) {
this.mDevice = device;
this.mCallback = callback;
this.mPairState = initialState;
}
public void packetReceived(NetworkPacket np) {
cancelTimer();
boolean wantsPair = np.getBoolean("pair");
if (wantsPair) {
switch (mPairState) {
case Requested: // We started pairing and tis is a confirmation
pairingDone();
break;
case RequestedByPeer:
Log.w("PairingHandler", "Ignoring second pairing request before the first one timed out");
break;
case Paired:
case NotPaired:
if (mPairState == PairState.Paired) {
Log.w("PairingHandler", "Received pairing request from a device we already trusted.");
// It would be nice to auto-accept the pairing request here, but since the pairing accept and pairing request
// messages are identical, this could create an infinite loop if both devices are "accepting" each other pairs.
// Instead, unpair and handle as if "NotPaired".
mPairState = PairState.NotPaired;
mCallback.unpaired();
}
mPairState = PairState.RequestedByPeer;
mPairingTimer = new Timer();
mPairingTimer.schedule(new TimerTask() {
@Override
public void run() {
Log.w("PairingHandler", "Unpairing (timeout after we started pairing)");
mPairState = PairState.NotPaired;
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_timed_out));
}
}, 25 * 1000); //Time to show notification, waiting for user to accept (peer will timeout in 30 seconds)
mCallback.incomingPairRequest();
break;
}
} else {
Log.i("PairingHandler", "Unpair request received");
switch (mPairState) {
case NotPaired:
Log.i("PairingHandler", "Ignoring unpair request for already unpaired device");
break;
case Requested: // We started pairing and got rejected
case RequestedByPeer: // They stared pairing, then cancelled
mPairState = PairState.NotPaired;
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_canceled_by_other_peer));
break;
case Paired:
mPairState = PairState.NotPaired;
mCallback.unpaired();
break;
}
}
}
public void requestPairing() {
cancelTimer();
if (mPairState == PairState.Paired) {
Log.w("PairingHandler", "requestPairing was called on an already paired device");
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_already_paired));
return;
}
if (mPairState == PairState.RequestedByPeer) {
Log.w("PairingHandler", "Pairing already started by the other end, accepting their request.");
acceptPairing();
return;
}
if (!mDevice.isReachable()) {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_not_reachable));
return;
}
mPairState = PairState.Requested;
mPairingTimer = new Timer();
mPairingTimer.schedule(new TimerTask() {
@Override
public void run() {
Log.w("PairingHandler","Unpairing (timeout after receiving pair request)");
mPairState = PairState.NotPaired;
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_timed_out));
}
}, 30*1000); //Time to wait for the other to accept
Device.SendPacketStatusCallback statusCallback = new Device.SendPacketStatusCallback() {
@Override
public void onSuccess() { }
@Override
public void onFailure(Throwable e) {
cancelTimer();
Log.e("PairingHandler", "Exception sending pairing request", e);
mPairState = PairState.NotPaired;
mCallback.pairingFailed(mDevice.getContext().getString(R.string.runcommand_notreachable));
}
};
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", true);
mDevice.sendPacket(np, statusCallback);
}
public void acceptPairing() {
cancelTimer();
Device.SendPacketStatusCallback StateCallback = new Device.SendPacketStatusCallback() {
@Override
public void onSuccess() {
pairingDone();
}
@Override
public void onFailure(Throwable e) {
Log.e("PairingHandler", "Exception sending accept pairing packet", e);
mPairState = PairState.NotPaired;
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_not_reachable));
}
};
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", true);
mDevice.sendPacket(np, StateCallback);
}
public void cancelPairing() {
cancelTimer();
mPairState = PairState.NotPaired;
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", false);
mDevice.sendPacket(np);
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_canceled_by_user));
}
private void pairingDone() {
Log.i("PairingHandler", "Pairing done");
mPairState = PairState.Paired;
try {
mCallback.pairingSuccessful();
} catch (Exception e) {
Log.e("PairingHandler", "Exception in pairingSuccessful callback, unpairing");
e.printStackTrace();
mPairState = PairState.NotPaired;
}
}
public void unpair() {
mPairState = PairState.NotPaired;
if (mDevice.isReachable()) {
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", false);
mDevice.sendPacket(np);
}
mCallback.unpaired();
}
private void cancelTimer() {
if (mPairingTimer != null) {
mPairingTimer.cancel();
}
}
}

View File

@@ -0,0 +1,182 @@
/*
* 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
*/
package org.kde.kdeconnect
import android.util.Log
import kotlinx.coroutines.*
import org.kde.kdeconnect_tp.R
import kotlin.time.Duration.Companion.seconds
class PairingHandler(private val device: Device, private val callback: PairingCallback, var state: PairState) {
enum class PairState {
NotPaired,
Requested,
RequestedByPeer,
Paired
}
interface PairingCallback {
fun incomingPairRequest()
fun pairingFailed(error: String)
fun pairingSuccessful()
fun unpaired()
}
private val pairingJob = SupervisorJob()
private val pairingScope = CoroutineScope(Dispatchers.IO + pairingJob)
fun packetReceived(np: NetworkPacket) {
cancelTimer()
val wantsPair = np.getBoolean("pair")
if (wantsPair) {
when (state) {
PairState.Requested -> pairingDone()
PairState.RequestedByPeer -> {
Log.w(
"PairingHandler",
"Ignoring second pairing request before the first one timed out"
)
}
PairState.Paired, PairState.NotPaired -> {
if (state == PairState.Paired) {
Log.w("PairingHandler", "Received pairing request from a device we already trusted.")
// It would be nice to auto-accept the pairing request here, but since the pairing accept and pairing request
// messages are identical, this could create an infinite loop if both devices are "accepting" each other pairs.
// Instead, unpair and handle as if "NotPaired".
state = PairState.NotPaired
callback.unpaired()
}
state = PairState.RequestedByPeer
pairingScope.launch {
delay(25.seconds)
Log.w("PairingHandler", "Unpairing (timeout after we started pairing)")
this@PairingHandler.state = PairState.NotPaired
callback.pairingFailed(device.context.getString(R.string.error_timed_out))
} // Time to show notification, waiting for user to accept (peer will timeout in 30 seconds)
callback.incomingPairRequest()
}
}
} else {
Log.i("PairingHandler", "Unpair request received")
when (state) {
PairState.NotPaired -> Log.i("PairingHandler", "Ignoring unpair request for already unpaired device")
// Requested: We started pairing and got rejected
// RequestedByPeer: They stared pairing, then cancelled
PairState.Requested, PairState.RequestedByPeer -> {
state = PairState.NotPaired
callback.pairingFailed(device.context.getString(R.string.error_canceled_by_other_peer))
}
PairState.Paired -> {
state = PairState.NotPaired
callback.unpaired()
}
}
}
}
fun requestPairing() {
cancelTimer()
if (state == PairState.Paired) {
Log.w("PairingHandler", "requestPairing was called on an already paired device")
callback.pairingFailed(device.context.getString(R.string.error_already_paired))
return
}
if (state == PairState.RequestedByPeer) {
Log.w("PairingHandler", "Pairing already started by the other end, accepting their request.")
acceptPairing()
return
}
if (!device.isReachable) {
callback.pairingFailed(device.context.getString(R.string.error_not_reachable))
return
}
state = PairState.Requested
pairingScope.launch {
delay(30.seconds)
Log.w("PairingHandler", "Unpairing (timeout after receiving pair request)")
this@PairingHandler.state = PairState.NotPaired
callback.pairingFailed(device.context.getString(R.string.error_timed_out))
} // Time to wait for the other to accept
val statusCallback: Device.SendPacketStatusCallback = object : Device.SendPacketStatusCallback() {
override fun onSuccess() {}
override fun onFailure(e: Throwable) {
cancelTimer()
Log.e("PairingHandler", "Exception sending pairing request", e)
this@PairingHandler.state = PairState.NotPaired
callback.pairingFailed(device.context.getString(R.string.runcommand_notreachable))
}
}
val np = NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR)
np["pair"] = true
device.sendPacket(np, statusCallback)
}
fun acceptPairing() {
cancelTimer()
val stateCallback = object : Device.SendPacketStatusCallback() {
override fun onSuccess() {
pairingDone()
}
override fun onFailure(e: Throwable) {
Log.e("PairingHandler", "Exception sending accept pairing packet", e)
this@PairingHandler.state = PairState.NotPaired
callback.pairingFailed(device.context.getString(R.string.error_not_reachable))
}
}
val np = NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR)
np["pair"] = true
device.sendPacket(np, stateCallback)
}
fun cancelPairing() {
cancelTimer()
state = PairState.NotPaired
val np = NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR)
np["pair"] = false
device.sendPacket(np)
callback.pairingFailed(device.context.getString(R.string.error_canceled_by_user))
}
private fun pairingDone() {
Log.i("PairingHandler", "Pairing done")
state = PairState.Paired
kotlin.runCatching {
callback.pairingSuccessful()
}.onFailure { e ->
Log.e("PairingHandler", "Exception in pairingSuccessful callback, unpairing", e)
state = PairState.NotPaired
}
}
fun unpair() {
state = PairState.NotPaired
if (device.isReachable) {
val np = NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR)
np["pair"] = false
device.sendPacket(np)
}
callback.unpaired()
}
private fun cancelTimer() {
pairingJob.cancelChildren()
}
}

View File

@@ -11,33 +11,6 @@ import android.telephony.CellInfo;
import android.telephony.SignalStrength;
public class ASUUtils {
/**
* Implementation of SignalStrength.toLevel usable from API Level 7+
*/
public static int signalStrengthToLevel(SignalStrength signalStrength) {
int level;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
level = signalStrength.getLevel();
} else {
// Should work on all supported versions, uses copied functions from modern SDKs
// Needs testing
int gsmLevel = signalStrength.getGsmSignalStrength();
if (gsmLevel >= 0 && gsmLevel <= 31) {
// Convert getGsmSignalStrength range (0..31) to getLevel range (0..4)
gsmLevel = gsmLevel * 4 / 31;
} else {
gsmLevel = 0;
}
int cdmaLevel = getCdmaLevel(signalStrength.getCdmaDbm(), signalStrength.getCdmaEcio());
int evdoLevel = getEvdoLevel(signalStrength.getEvdoDbm(), signalStrength.getEvdoSnr());
level = Math.max(gsmLevel, Math.max(cdmaLevel, evdoLevel));
}
return level;
}
/**
* Get cdma as level 0..4

View File

@@ -136,7 +136,7 @@ public class ConnectivityReportPlugin extends Plugin {
return new PhoneStateListener() {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
int level = ASUUtils.signalStrengthToLevel(signalStrength);
int level = signalStrength.getLevel();
SubscriptionState state = states.get(subID);
if (state != null) {

View File

@@ -48,6 +48,7 @@ public class MousePadActivity
private float mPrevX;
private float mPrevY;
boolean dragging = false;
private float mCurrentSensitivity;
private float displayDpiMultiplier;
private int scrollDirection = 1;
@@ -382,6 +383,7 @@ public class MousePadActivity
return;
}
plugin.sendSingleHold();
dragging = true;
}
@Override
@@ -468,7 +470,12 @@ public class MousePadActivity
finish();
return;
}
plugin.sendLeftClick();
if (dragging) {
plugin.sendSingleRelease();
dragging = false;
} else {
plugin.sendLeftClick();
}
}
private void sendMiddleClick() {

View File

@@ -136,6 +136,12 @@ public class MousePadPlugin extends Plugin {
getDevice().sendPacket(np);
}
public void sendSingleRelease() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("singlerelease", true);
device.sendPacket(np);
}
public void sendScroll(float dx, float dy) {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("scroll", true);

View File

@@ -58,7 +58,6 @@ public class SendKeystrokesToHostActivity extends AppCompatActivity {
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1) // needed for this.getReferrer()
@Override
protected void onStart() {
super.onStart();

View File

@@ -369,7 +369,6 @@ class MprisMediaSession : OnSharedPreferenceChangeListener, NotificationReceiver
.setContentIntent(piOpenActivity)
.setSmallIcon(R.drawable.ic_play_white)
.setShowWhen(false)
.setColor(ContextCompat.getColor(context!!, R.color.primary))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSubText(device.name)

View File

@@ -276,7 +276,6 @@ class MprisNowPlayingFragment : Fragment(), VolumeKeyListener {
if (albumArt == null) {
val drawable = ContextCompat.getDrawable(requireContext(), R.drawable.ic_album_art_placeholder)!!
val placeholder_art = DrawableCompat.wrap(drawable)
DrawableCompat.setTint(placeholder_art, ContextCompat.getColor(requireContext(), R.color.primary))
activityMprisBinding.albumArt.setImageDrawable(placeholder_art)
} else {
activityMprisBinding.albumArt.setImageBitmap(albumArt)

View File

@@ -7,12 +7,20 @@ package org.kde.kdeconnect.Plugins.MprisPlugin
import android.Manifest
import android.app.Activity
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.util.Log
import androidx.annotation.DrawableRes
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceManager
import org.kde.kdeconnect.Helpers.NotificationHelper
import org.kde.kdeconnect.Helpers.VideoUrlsHelper
import org.kde.kdeconnect.NetworkPacket
import org.kde.kdeconnect.Plugins.MprisPlugin.AlbumArtCache.deregisterPlugin
import org.kde.kdeconnect.Plugins.MprisPlugin.AlbumArtCache.getAlbumArt
@@ -243,6 +251,7 @@ class MprisPlugin : Plugin() {
if (np.has("player")) {
val playerStatus = players[np.getString("player")]
if (playerStatus != null) {
val wasPlaying = playerStatus.isPlaying
//Note: title, artist and album will not be available for all desktop clients
playerStatus.title = np.getString("title", playerStatus.title)
playerStatus.artist = np.getString("artist", playerStatus.artist)
@@ -286,6 +295,11 @@ class MprisPlugin : Plugin() {
playerStatusUpdated.remove(key)
}
}
// Check to see if a stream has stopped playing and we should deliver a notification
if (np.has("isPlaying") && !playerStatus.isPlaying && wasPlaying) {
showContinueWatchingNotification(playerStatus)
}
}
}
@@ -309,8 +323,13 @@ class MprisPlugin : Plugin() {
val oldPlayer = it.key
val found = newPlayerList.stream().anyMatch { newPlayer -> newPlayer == oldPlayer }
if (!found) {
iter.remove()
// Player got removed
equals = false
iter.remove()
val playerStatus = it.value
if (playerStatus.isPlaying) {
showContinueWatchingNotification(playerStatus)
}
}
}
if (!equals) {
@@ -328,6 +347,34 @@ class MprisPlugin : Plugin() {
return true
}
private fun showContinueWatchingNotification(playerStatus: MprisPlayer) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
if (prefs.getBoolean(context.getString(R.string.mpris_keepwatching_key), true) &&
(playerStatus.url.startsWith("http://") || playerStatus.url.startsWith("https://"))
) {
try {
val url = VideoUrlsHelper.formatUriWithSeek(playerStatus.url, playerStatus.position).toString()
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
val pendingIntent = PendingIntent.getActivity(device.context, 0, browserIntent, PendingIntent.FLAG_IMMUTABLE)
val notificationManager = ContextCompat.getSystemService(device.context, NotificationManager::class.java)
val builder = NotificationCompat.Builder(device.context, NotificationHelper.Channels.CONTINUEWATCHING)
.setContentTitle(context.resources.getString(R.string.kde_connect))
.setSmallIcon(R.drawable.ic_play_white)
.setTimeoutAfter(3000)
.setContentIntent(pendingIntent)
.setContentText(context.resources.getString(R.string.mpris_keepwatching) + " " + playerStatus.title)
NotificationHelper.notifyCompat(
notificationManager,
System.currentTimeMillis().toInt(),
builder.build()
)
} catch (e: MalformedURLException) {
e.printStackTrace();
}
}
}
override val supportedPacketTypes: Array<String> = arrayOf(PACKET_TYPE_MPRIS)
override val outgoingPacketTypes: Array<String> = arrayOf(PACKET_TYPE_MPRIS_REQUEST)

Some files were not shown because too many files have changed in this diff Show More