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

Compare commits

...

46 Commits

Author SHA1 Message Date
Albert Vaca Cintora
f2af39aa8e Release 1.29.0 2023-09-20 21:22:53 +02:00
Albert Vaca Cintora
31fce7fdb0 Use Elliptic Curve encryption instead of RSA
This should fix SFTP not working when using GSConnect (which
doesn't specify the SSH parameters we do to allow old cyphers).

Requires API 23, so on pre-23 we still use RSA.
2023-09-20 18:38:34 +00:00
l10n daemon script
41f511d675 GIT_SILENT made messages (after extraction) 2023-09-20 00:45:21 +00:00
Albert Vaca Cintora
14e61246ff Add a per-device confirmation before copying the contacts
The contacts plugin is the only one that copies (and persists) data to the
remote device just by connecting. By adding this extra confirmation once
per device, we prevent this from happening in cases where someone paired
with a friend to transfer a file, or paired by accident.
2023-09-19 12:30:58 +00:00
l10n daemon script
9fdb71096e GIT_SILENT made messages (after extraction) 2023-09-19 00:45:16 +00:00
Albert Vaca Cintora
d0931f28a9 Split file transfer error notification to a separate channel 2023-09-18 21:23:56 +00:00
Albert Vaca Cintora
2ba79a2f58 Long-tapping the "Send clipboard" quick settings tile opens the app
Instead of launching the system app settings activity.
2023-09-18 21:22:20 +00:00
Albert Vaca Cintora
7c649be2ce Add "laptop" as a device type
For consistency with the other implementations, which distinguish the
two kinds of computers.
2023-09-18 07:31:06 +00:00
Albert Vaca Cintora
3baa9fa14e Using collect() instead of java16-only toList() to fix crash 2023-09-18 04:12:54 +02:00
l10n daemon script
48919bddcd GIT_SILENT made messages (after extraction) 2023-09-18 00:45:26 +00:00
l10n daemon script
4d3480399d GIT_SILENT Sync po/docbooks with svn 2023-09-17 02:00:02 +00:00
l10n daemon script
9290110fd8 GIT_SILENT made messages (after extraction) 2023-09-17 00:44:48 +00:00
l10n daemon script
dfb647536b GIT_SILENT made messages (after extraction) 2023-09-16 00:45:18 +00:00
Albert Vaca Cintora
3eedc88c3c Remove photo plugin
As discussed in Matrix and BUG: 474121 this plugin is confusing (because
it doesn't actually take a photo, it just launches the camera on your
phone) and its use case can be covered by taking a photo and sharing it,
which only requires a couple extra clicks.
2023-09-15 23:04:21 +00:00
l10n daemon script
1d3c818a2c GIT_SILENT made messages (after extraction) 2023-09-15 00:45:32 +00:00
l10n daemon script
a67447e3f5 GIT_SILENT made messages (after extraction) 2023-09-14 00:44:51 +00:00
Albert Vaca Cintora
57ec71e60b Add accessibility description to FABs 2023-09-12 13:06:06 +02:00
Albert Vaca Cintora
17757908c4 Split notification channels for received and sent files
BUG: 433051
2023-09-12 05:14:37 +02:00
Albert Vaca Cintora
708889eed7 Use setFailed for errors when sending/receiving files 2023-09-12 05:06:48 +02:00
Simon Redman
1096ace12c Remove smsMmsChannel notification channel
## Summary

Remove the dead "New Message" notification channel.

This channel was used for a tiny period, probably around 4 years ago, when we thought the only way to support sending MMS on Android was to be the default SMS app, thus we wanted to show users a notification when they received messages while our app was in charge of handling them.

Thankfully, we do not need to be the default SMS app, so this notification channel should be removed.

## Test Plan

### Before:
Looking at the list of notification streams in the settings for KDE Connect will include a "New Message" channel. Notifications are never posted to this channel.

### After:
Users will not see a "New Message" channel. Note that it does show a count of deleted streams, to prevent spam. See [documentation](https://developer.android.com/develop/ui/views/notifications/channels#DeleteChannel) for explanation.
2023-09-12 02:31:52 +00:00
l10n daemon script
b4f33adb6c GIT_SILENT made messages (after extraction) 2023-09-11 00:46:21 +00:00
l10n daemon script
6ff71c3965 GIT_SILENT made messages (after extraction) 2023-09-08 00:45:32 +00:00
Albert Vaca Cintora
cd0ae95e58 Revert "Partially revert "Add MDNS discovery""
Adds back MDNS discovery and the setting to toggle UDP broacasts on/off.

We can probably remove the setting at some point, and just keep it enabled.

Another thing we can probably improve is the acquisition of the multicast
lock, so we only hold it when the app is open, or at least only when the
device is connected to Wifi (which we know). For more context, see commit
https://invent.kde.org/network/kdeconnect-android/-/merge_requests/375/diffs?commit_id=f71a3fe6b95af404d2a675afb78f24847064f8a9

This reverts commit 5da804939d.
2023-09-07 09:40:22 +02:00
Albert Vaca Cintora
f89c01ec17 Release 1.28.0 2023-09-07 09:33:14 +02:00
Albert Vaca Cintora
5da804939d Partially revert "Add MDNS discovery"
This partially reverts commit 8f8a09a99a.

Removing MDNS to do one last bugfix-only release.
2023-09-07 09:27:55 +02:00
Albert Vaca Cintora
3fbef1da87 Add some logs to ConnectivityManager.NetworkCallback 2023-09-07 09:27:55 +02:00
Albert Vaca Cintora
ce055818c9 Bump deps, do not use alpha accompanist 2023-09-07 09:27:55 +02:00
l10n daemon script
79a59a125f GIT_SILENT made messages (after extraction) 2023-09-07 00:45:20 +00:00
Albert Vaca Cintora
ae98b5c71f When permissions are granted, reload plugins for all devices 2023-09-06 08:09:09 +00:00
Albert Vaca Cintora
6b1b12a178 Bump dependencies 2023-09-06 08:08:53 +02:00
Albert Vaca Cintora
b01266d654 Fix ForegroundServiceStartNotAllowedException in ACTION_SCREEN_ON
The same way we did for ACTION_BOOT_COMPLETED
2023-09-06 07:42:18 +02:00
l10n daemon script
e9a862f27c GIT_SILENT made messages (after extraction) 2023-09-04 00:46:15 +00:00
l10n daemon script
cb0cea827f GIT_SILENT Sync po/docbooks with svn 2023-09-03 02:05:47 +00:00
l10n daemon script
6e5cfd9b2e GIT_SILENT made messages (after extraction) 2023-09-03 00:45:30 +00:00
l10n daemon script
1080bae5e2 GIT_SILENT Sync po/docbooks with svn 2023-09-02 01:49:59 +00:00
l10n daemon script
d2290bedb0 GIT_SILENT made messages (after extraction) 2023-09-02 00:46:41 +00:00
Albert Vaca Cintora
4d2efe6b89 Request notifications permission so we can target Android 13
Starting next month (September 2023) it will be required to target
Android 13 to publish to the Play Store.

On Android 13, we need to request the POST_NOTIFICATIONS permission. 

This change adds the permission as required/optional to the plugins
that do create notifications. It also adds a popup to request it the
first time you open the app.
2023-09-01 03:34:32 +00:00
Albert Vaca Cintora
37db0810aa Bind only the socket we use for UDP broadcast, not the process 2023-08-30 23:12:17 +02:00
Axel Pirek
f9a3598edf Bind sockets to network
Fixes a race condition where onNetworkChange was called before the new
network became the default and the identity packet would be broadcast to
the wrong (e.g. cellular) network.
2023-08-30 23:09:02 +02:00
Albert Vaca Cintora
1d822e1610 Fix keyboard/d-pad navigation
Allows navigating the app using the arrow keys on a keyboard or the
D-pad on a TV remote, up until the plugin list (I haven't checked
specific plugins).
2023-08-30 13:55:08 +00:00
l10n daemon script
4e9dece3b2 GIT_SILENT made messages (after extraction) 2023-08-30 00:46:01 +00:00
Albert Vaca Cintora
8f8a09a99a Add MDNS discovery
Uses Android's `NsdManager` to announce a `_kdeconnect._udp` service using MDNS. This is done in addition to sending UDP broadcasts.

When we detect a device this way, we send a UDP identity packet to it (identical to the ones we broadcast but sent to a single device).

I also added a toggle in settings to disable the UDP broadcasts, so we can test MDNS by itself.
2023-08-28 21:37:55 +00:00
l10n daemon script
b545257fa7 GIT_SILENT Sync po/docbooks with svn 2023-08-28 02:06:33 +00:00
l10n daemon script
2c72619ae7 GIT_SILENT made messages (after extraction) 2023-08-28 00:46:12 +00:00
l10n daemon script
418cf720ab GIT_SILENT made messages (after extraction) 2023-08-27 00:45:55 +00:00
l10n daemon script
5ef5be87ca GIT_SILENT made messages (after extraction) 2023-08-23 00:46:18 +00:00
107 changed files with 1020 additions and 501 deletions

View File

@@ -8,9 +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"
package="org.kde.kdeconnect_tp"
android:versionCode="12701"
android:versionName="1.27.1">
android:versionCode="12900"
android:versionName="1.29.0">
<uses-feature
android:name="android.hardware.telephony"
@@ -49,6 +48,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:icon="@mipmap/ic_launcher"
@@ -107,6 +107,9 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES"/>
</intent-filter>
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.PluginSettingsActivity"
@@ -379,8 +382,6 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:value="org.kde.kdeconnect.UserInterface.PluginSettingsActivity" />
</activity>
<activity android:name="org.kde.kdeconnect.Plugins.PhotoPlugin.PhotoActivity" />
<activity
android:name="org.kde.kdeconnect.UserInterface.TrustedNetworksActivity"
android:label="@string/trusted_networks"

View File

@@ -38,10 +38,10 @@ fun String.runCommand(
android {
namespace = "org.kde.kdeconnect_tp"
compileSdk = 33
compileSdk = 34
defaultConfig {
minSdk = 21
targetSdk = 32
targetSdk = 33
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
buildFeatures {
@@ -50,7 +50,7 @@ android {
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
kotlinCompilerExtensionVersion = "1.5.3"
}
compileOptions {
@@ -154,7 +154,7 @@ dependencies {
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.activity.compose)
implementation(libs.accompanist.themeadapter.material3)
implementation(libs.accompanist.themeadapter.material3) // TODO: Remove deprecated library https://google.github.io/accompanist/themeadapter-material3/
implementation(libs.androidx.constraintlayout.compose)
implementation(libs.androidx.compose.ui.tooling.preview)

View File

@@ -11,4 +11,10 @@ KDE Connect poskytuje sadu vlastností pro vzájemnou integraci vašich zaříze
Prosím pamatujte, že pro správnou funkci této aplikace je nutné abyste na vašem počítači měli nainstalován KDE Connect a udržovali jej aktuální zde i na Androidu.
Informace o citlivých oprávněních:
* Oprávnění přístupnosti: Nutné pro příjem vstupu z jiného zařízení aby mohlo ovládat váš telefon Android pokud používáte vlastnost Vzdálený vstup.
* Oprávnění o poloze na pozadí: Je potřebné pro rozpoznání, ke které síti WiFi jste připojeni, pokud používáte funkci Důvěryhodné sítě.
KDE Connect nikdy neposílá KDE ani nikomu jinému jakékoliv informace. KDE Connect odesílá data z jednoho zařízení druhému přímo přes místní síť, nikdy přes internet, a výhradně s použitím koncového šifrování.
Tato aplikace je součástí Open Source projektu a existuje jenom díky přispěvatelům. Zdrojové soubory naleznete na webových stránkách.

View File

@@ -1 +1 @@
KDE Connect propojuje váš mobilní telefon a počítač
KDE Connect integruje váš chytrý telefon a počítač

View File

@@ -0,0 +1,12 @@
1.28:
* Improved connection reliability.
1.27:
* Added back the mouse receiver plugin.
1.26:
* Allow having different widgets for diferent devices.
* Add stats about network packets sent and received.
* Add the option to cancel a pairing request after sending it.
* Fix device name set initially not being human-friendly.
* Rewrite some of the internals to improve performance.

View File

@@ -0,0 +1,7 @@
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,8 +1,8 @@
[versions]
accompanistThemeadapterMaterial3 = "0.31.0-alpha"
accompanistThemeadapterMaterial3 = "0.32.0"
activityCompose = "1.7.2"
androidDesugarJdkLibs = "2.0.3"
androidGradlePlugin = "8.1.0"
androidGradlePlugin = "8.1.1"
androidSmsmms = "kdeconnect-1-21-0"
appcompat = "1.6.1"
bcpkixJdk15on = "1.70"
@@ -14,12 +14,12 @@ constraintlayoutCompose = "1.0.1"
coreKtx = "1.10.1"
disklrucache = "2.0.2"
documentfile = "1.0.1"
gradle = "8.1.0"
gradle = "8.1.1"
gridlayout = "1.0.0"
jsonassert = "1.5.1"
junit = "4.13.2"
dependencyLicenseReport = "1.16"
kotlin = "1.9.0"
kotlin = "1.9.10"
kotlinxCoroutinesCore = "1.7.1"
lifecycleExtensions = "2.2.0"
lifecycleRuntimeKtx = "2.6.1"
@@ -30,13 +30,13 @@ media = "1.6.0"
minaCore = "2.0.19"
mockitoCore = "3.12.4"
powermockModuleJunit4 = "2.0.0"
preferenceKtx = "1.2.0"
preferenceKtx = "1.2.1"
reactiveStreams = "1.0.4"
recyclerview = "1.3.1"
rxjava = "2.2.21"
sshdCore = "0.14.0"
swiperefreshlayout = "1.1.0"
uiToolingPreview = "1.4.3"
uiToolingPreview = "1.5.1"
univocityParsers = "2.9.1"
[libraries]

View File

@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-30 00:45+0000\n"
"PO-Revision-Date: 2023-06-07 14:10+0200\n"
"PO-Revision-Date: 2023-08-07 16:43+0200\n"
"Last-Translator: Vit Pelcak <vit@pelcak.org>\n"
"Language-Team: Czech <kde-i18n-doc@kde.org>\n"
"Language: cs\n"
@@ -13,30 +13,8 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Lokalize 23.04.1\n"
"X-Generator: Lokalize 23.04.3\n"
#, fuzzy
#| msgid ""
#| "KDE Connect provides a set of features to integrate your workflow across "
#| "devices:\n"
#| "\n"
#| "- Shared clipboard: copy and paste between your devices.\n"
#| "- Share files and URLs to your computer from any app.\n"
#| "- Get notifications for incoming calls and SMS messages on your PC.\n"
#| "- Virtual touchpad: Use your phone screen as your computer's touchpad.\n"
#| "- Notifications sync: Read your Android notifications from the desktop.\n"
#| "- Multimedia remote control: Use your phone as a remote for Linux media "
#| "players.\n"
#| "- WiFi connection: no USB wire or bluetooth needed.\n"
#| "- End-to-end TLS encryption: your information is safe.\n"
#| "\n"
#| "Please note you will need to install KDE Connect on your computer for "
#| "this app to work, and keep the desktop version up-to-date with the "
#| "Android version for the latest features to work.\n"
#| "\n"
#| "This app is part of an open source project and it exists thanks to all "
#| "the people who contributed to it. Visit the website to grab the source "
#| "code."
msgid ""
"KDE Connect provides a set of features to integrate your workflow across "
"devices:\n"
@@ -86,5 +64,15 @@ msgstr ""
"vašem počítači měli nainstalován KDE Connect a udržovali jej aktuální zde i "
"na Androidu.\n"
"\n"
"Informace o citlivých oprávněních:\n"
"* Oprávnění přístupnosti: Nutné pro příjem vstupu z jiného zařízení aby "
"mohlo ovládat váš telefon Android pokud používáte vlastnost Vzdálený vstup.\n"
"* Oprávnění o poloze na pozadí: Je potřebné pro rozpoznání, ke které síti "
"WiFi jste připojeni, pokud používáte funkci Důvěryhodné sítě.\n"
"\n"
"KDE Connect nikdy neposílá KDE ani nikomu jinému jakékoliv informace. KDE "
"Connect odesílá data z jednoho zařízení druhému přímo přes místní síť, nikdy "
"přes internet, a výhradně s použitím koncového šifrování.\n"
"\n"
"Tato aplikace je součástí Open Source projektu a existuje jenom díky "
"přispěvatelům. Zdrojové soubory naleznete na webových stránkách."
"přispěvatelům. Zdrojové soubory naleznete na webových stránkách.\n"

View File

@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-07 00:47+0000\n"
"PO-Revision-Date: 2023-06-07 14:11+0200\n"
"PO-Revision-Date: 2023-07-27 14:30+0200\n"
"Last-Translator: Vit Pelcak <vit@pelcak.org>\n"
"Language-Team: Czech <kde-i18n-doc@kde.org>\n"
"Language: cs\n"
@@ -13,7 +13,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Lokalize 23.04.1\n"
"X-Generator: Lokalize 23.04.3\n"
msgid "KDE Connect integrates your smartphone and computer"
msgstr "KDE Connect propojuje váš mobilní telefon a počítač"
msgstr "KDE Connect integruje váš chytrý telefon a počítač"

View File

@@ -10,10 +10,10 @@ msgstr ""
"PO-Revision-Date: 2023-07-15 14:30+0200\n"
"Last-Translator: Karl Ove Hufthammer <karl@huftis.org>\n"
"Language-Team: Norwegian Nynorsk <l10n-no@lister.huftis.org>\n"
"Language: nn\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nn\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 23.04.3\n"
"X-Environment: kde\n"

View File

@@ -4,7 +4,7 @@ msgstr ""
"Project-Id-Version: kdeorg\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-30 00:45+0000\n"
"PO-Revision-Date: 2023-08-02 12:40\n"
"PO-Revision-Date: 2023-09-16 10:08\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-06-07 00:47+0000\n"
"PO-Revision-Date: 2023-08-02 12:40\n"
"PO-Revision-Date: 2023-09-16 10:08\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="24"
android:viewportHeight="24"
android:width="24dp"
android:height="24dp">
<path
android:pathData="M15.2 12A3.2 3.2 0 0 1 12 15.2 3.2 3.2 0 0 1 8.8 12 3.2 3.2 0 0 1 12 8.8 3.2 3.2 0 0 1 15.2 12Z"
android:fillColor="#000000" />
<path
android:pathData="M9 2L7.17 4 4 4C2.9 4 2 4.9 2 6l0 12c0 1.1 0.9 2 2 2l16 0c1.1 0 2 -0.9 2 -2L22 6C22 4.9 21.1 4 20 4L16.83 4 15 2 9 2Zm3 15C9.24 17 7 14.76 7 12 7 9.24 9.24 7 12 7c2.76 0 5 2.24 5 5 0 2.76 -2.24 5 -5 5z"
android:fillColor="#000000" />
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:height="32dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M21,2L3,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h7v2L8,20v2h8v-2h-2v-2h7c1.1,0 2,-0.9 2,-2L23,4c0,-1.1 -0.9,-2 -2,-2zM21,16L3,16L3,4h18v12z"/>
</vector>

View File

@@ -1,10 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2023 Albert Vaca Cintora <albertvaka@gmail.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="false"
android:focusable="false"
android:drawablePadding="8dp"
android:paddingTop="16dp"
android:paddingBottom="12dp"

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2023 Albert Vaca Cintora <albertvaka@gmail.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:drawablePadding="8dp"
android:paddingTop="16dp"
android:paddingBottom="12dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:text="@string/no_notifications"
app:drawableStartCompat="@drawable/ic_warning"
app:drawableTint="?attr/colorControlNormal">
</TextView>

View File

@@ -1,4 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"

View File

@@ -23,6 +23,7 @@
<FrameLayout
android:id="@+id/container"
android:descendantFocusability="afterDescendants"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

View File

@@ -48,6 +48,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:elevation="@dimen/fab_elevation"
android:contentDescription="@string/add_device_dialog_title"
android:src="@drawable/ic_add"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -9,6 +9,8 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:descendantFocusability="afterDescendants"
android:focusable="false"
android:layout_height="match_parent"
tools:context="org.kde.kdeconnect.UserInterface.DeviceFragment">
@@ -26,6 +28,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<androidx.core.widget.NestedScrollView
android:id="@+id/device_view"
android:descendantFocusability="afterDescendants"
android:layout_width="match_parent"
android:layout_height="match_parent">

View File

@@ -24,6 +24,8 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<FrameLayout
android:id="@+id/container"
android:descendantFocusability="afterDescendants"
android:focusable="false"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"

View File

@@ -39,6 +39,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:layout_margin="16dp"
app:srcCompat="@drawable/ic_action_image_edit_24dp"
app:layout_anchor="@id/run_commands_list"
android:contentDescription="@string/add_command"
app:layout_anchorGravity="bottom|end" />
<TextView

View File

@@ -19,6 +19,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:layout_height="match_parent"
android:addStatesFromChildren="true"
android:divider="@null"
android:descendantFocusability="afterDescendants"
android:dividerHeight="12dp"
android:orientation="vertical"
tools:listitem="@layout/list_card_entry"

View File

@@ -26,6 +26,8 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:clickable="false"
android:focusable="false"
card_view:cardUseCompatPadding="true">
<LinearLayout

View File

@@ -12,6 +12,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="false"
android:focusable="false"
android:drawablePadding="8dp"
android:paddingTop="16dp"
android:paddingBottom="12dp"

View File

@@ -16,6 +16,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
android:paddingRight="16dp"
android:text="@string/pairing_description"
android:clickable="false"
android:focusable="false"
android:background="@android:color/transparent"
>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2023 Albert Vaca Cintora <albertvaka@gmail.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:drawablePadding="8dp"
android:paddingTop="16dp"
android:paddingBottom="12dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:text="@string/no_notifications"
app:drawableStartCompat="@drawable/ic_warning"
app:drawableLeftCompat="@drawable/ic_warning">
</TextView>

View File

@@ -166,9 +166,7 @@
<string name="pref_plugin_mprisreceiver">متحكم الوسائط</string>
<string name="notification_channel_default">إخطارات أخرى</string>
<string name="notification_channel_media_control">متحكم الوسائط</string>
<string name="notification_channel_filetransfer">نقل الملفّات</string>
<string name="notification_channel_high_priority">مرتفعة الأولوية</string>
<string name="notification_channel_sms_mms">رسالة جديدة</string>
<string name="mpris_stop">أوقف المشغل الحالي</string>
<string name="copy_url_to_clipboard">انسخ المسار إلى الحافظة</string>
<string name="clipboard_toast">نُسخ إلى الحافظة</string>
@@ -189,7 +187,6 @@
<string name="block_contents">امنح محتويات الإخطارات</string>
<string name="block_images">امنع الصور في الإخطارات</string>
<string name="notification_channel_receivenotification">إخطارات من أجهزة أخرى</string>
<string name="take_picture">شغّل الكاميرا</string>
<string name="presenter_pointer">المؤشر</string>
<string name="trusted_networks">الشّبكات الموثوقة</string>
<string name="add_trusted_network">أضف %s</string>

View File

@@ -273,9 +273,7 @@
<string name="notification_channel_default">Digər bildirişlər</string>
<string name="notification_channel_persistent">"Daimi göstərici"</string>
<string name="notification_channel_media_control">Media İdarəsi</string>
<string name="notification_channel_filetransfer">Fayl göndərişi</string>
<string name="notification_channel_high_priority">Yüksək üstünlük</string>
<string name="notification_channel_sms_mms">Yeni İsmarıc</string>
<string name="mpris_stop">Cari pleyeri dayandırmaq</string>
<string name="copy_url_to_clipboard">URL\'u mübadilə buferinə kopyalamaq</string>
<string name="clipboard_toast">Mübadilə buferinə kopyalandı</string>
@@ -304,8 +302,6 @@
<string name="block_contents">Bildirişlərin məzmununu bloklamaq</string>
<string name="block_images">Bildirişlərin şəkillərini bloklamaq</string>
<string name="notification_channel_receivenotification">Digar cihazlardan bilsirişlər</string>
<string name="take_picture">Kameranı açmaq</string>
<string name="plugin_photo_desc">Şəkillər çəkmək və göndərməyi asanlaşdırmaq üçün kamera tətbiqini başladın</string>
<string name="no_app_for_opening">Bu faylı açmaq üçün uyğun tətbiq tapılmadı</string>
<string name="remote_keyboard_service">KDE Connect Uzaq Klaviaturası</string>
<string name="presenter_pointer">Kursor</string>

View File

@@ -183,6 +183,7 @@
<item>1 минута</item>
<item>2 минути</item>
</string-array>
<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>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">Трябва да предоставите допълнителни разрешения, за да активирате всички функции</string>
<string name="plugins_need_optional_permission">Някои плъгини имат деактивирани функции поради липса на разрешение (докоснете за повече информация):</string>
<string name="share_optional_permission_explanation">За да получавате файлове, трябва да разрешите достъпа до хранилището</string>
<string name="share_notifications_explanation">За да виждате напредъка при изпращане и получаване на файлове, трябва да разрешите известия</string>
<string name="telepathy_permission_explanation">За да четете и записвате SMS от работния плот, трябва да дадете разрешение за SMS</string>
<string name="telephony_permission_explanation">За да виждате телефонни обаждания на работния плот, трябва да дадете разрешение за телефонни обаждания дневници и състояние на телефона</string>
<string name="telephony_optional_permission_explanation">За да видите име на контакт вместо телефонен номер, трябва да дадете достъп до контактите на телефона</string>
@@ -274,9 +276,9 @@
<string name="notification_channel_default">Други известия</string>
<string name="notification_channel_persistent">Постоянен индикатор</string>
<string name="notification_channel_media_control">Контрол на медиите</string>
<string name="notification_channel_filetransfer">Прехвърляне на файл</string>
<string name="notification_channel_filetransfer">Прехвърляне на входящ файл</string>
<string name="notification_channel_filetransfer_upload">Прехвърляне на изходящ файл</string>
<string name="notification_channel_high_priority">Висок приоритет</string>
<string name="notification_channel_sms_mms">Ново съобщение</string>
<string name="mpris_stop">Спиране на текущия плейър</string>
<string name="copy_url_to_clipboard">Копиране на URL в клипборда</string>
<string name="clipboard_toast">Копиран в клипборда</string>
@@ -305,8 +307,6 @@
<string name="block_contents">Блокиране на съдържанието на известията</string>
<string name="block_images">Блокиране на изображения в известията</string>
<string name="notification_channel_receivenotification">Известия от други устройства</string>
<string name="take_picture">Стартиране на камерата</string>
<string name="plugin_photo_desc">Стартирайте приложението за камера, за да улесните правенето и прехвърлянето на снимки</string>
<string name="no_app_for_opening">Не е намерено подходящо приложение за отваряне на този файл</string>
<string name="remote_keyboard_service">Отдалечена клавиатура KDE Connect</string>
<string name="presenter_pointer">Показалец</string>
@@ -397,4 +397,8 @@
<string name="send_clipboard">Изпращане на клипборд</string>
<string name="tap_to_execute">Докоснете, за да се изпълни</string>
<string name="plugin_stats">Данни на приставки</string>
<string name="enable_udp_broadcast">Активиране на откриване на устройства чрез UDP</string>
<string name="receive_notifications_permission_explanation">Известията трябва са разрешени, за да може да се получават от други устройства</string>
<string name="findmyphone_notifications_explanation">Разрешение за известия е необходимо, за да може телефонът да звъни, когато приложението е във фонов режим</string>
<string name="no_notifications">Известията са деактивирани, няма да получавате известия за входящи двойки.</string>
</resources>

View File

@@ -183,6 +183,7 @@
<item>1 minut</item>
<item>2 minuts</item>
</string-array>
<string name="mpris_notifications_explanation">Cal el permís de notificacions per a mostrar els elements multimèdia remots al calaix de notificacions</string>
<string name="mpris_notification_settings_title">Mostra les notificacions dels reproductors</string>
<string name="mpris_notification_settings_summary">Permet controlar els reproductors multimèdia sense obrir el KDE Connect</string>
<string name="share_to">Comparteix amb…</string>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">Us caldrà atorgar permisos extres per a accedir a totes les característiques</string>
<string name="plugins_need_optional_permission">Alguns connectors tenen característiques desactivades per la falta de permís (toqueu per a més informació):</string>
<string name="share_optional_permission_explanation">Per a rebre fitxers cal permetre l\'accés a l\'emmagatzematge</string>
<string name="share_notifications_explanation">Per a veure el progrés en enviar i rebre fitxers, heu de permetre les notificacions</string>
<string name="telepathy_permission_explanation">Per a llegir i escriure SMS des de l\'escriptori, haureu de donar permís als SMS</string>
<string name="telephony_permission_explanation">Per a veure les trucades telefòniques des de l\'escriptori, haureu de donar permís d\'accés al registre de trucades telefòniques i a l\'estat del telèfon</string>
<string name="telephony_optional_permission_explanation">Per a veure un nom de contacte en comptes d\'un número de telèfon, haureu de donar permís als contactes del telèfon</string>
@@ -274,9 +276,10 @@
<string name="notification_channel_default">Altres notificacions</string>
<string name="notification_channel_persistent">Indicador de persistència</string>
<string name="notification_channel_media_control">Control multimèdia</string>
<string name="notification_channel_filetransfer">Transferència de fitxers</string>
<string name="notification_channel_filetransfer">Transferència de fitxer entrant</string>
<string name="notification_channel_filetransfer_upload">Transferència de fitxer de sortida</string>
<string name="notification_channel_filetransfer_error">Error de transferència de fitxer</string>
<string name="notification_channel_high_priority">Prioritat alta</string>
<string name="notification_channel_sms_mms">Missatge nou</string>
<string name="mpris_stop">Atura el reproductor actual</string>
<string name="copy_url_to_clipboard">Copia l\'URL al porta-retalls</string>
<string name="clipboard_toast">Copiat al porta-retalls</string>
@@ -305,8 +308,6 @@
<string name="block_contents">Bloca el contingut de les notificacions</string>
<string name="block_images">Bloca les imatges a les notificacions</string>
<string name="notification_channel_receivenotification">Notificacions des d\'altres dispositius</string>
<string name="take_picture">Inicia la càmera</string>
<string name="plugin_photo_desc">Llança l\'aplicació de càmera per a facilitar la presa i la transferència de fotografies</string>
<string name="no_app_for_opening">No s\'ha trobat cap aplicació adequada per a obrir aquest fitxer</string>
<string name="remote_keyboard_service">Teclat remot del KDE Connect</string>
<string name="presenter_pointer">Apuntador</string>
@@ -397,4 +398,8 @@
<string name="send_clipboard">Envia el porta-retalls</string>
<string name="tap_to_execute">Toqueu per a executar</string>
<string name="plugin_stats">Estadístiques del connector</string>
<string name="enable_udp_broadcast">Activa el descobriment UDP de dispositius</string>
<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>
</resources>

View File

@@ -289,9 +289,7 @@
<string name="notification_channel_default">Ostatní oznámení</string>
<string name="notification_channel_persistent">Stálý ukazatel</string>
<string name="notification_channel_media_control">Ovládání médií</string>
<string name="notification_channel_filetransfer">Přenos souboru</string>
<string name="notification_channel_high_priority">Vysoká priorita</string>
<string name="notification_channel_sms_mms">Nová zpráva</string>
<string name="mpris_stop">Zastavit současný přehrávač</string>
<string name="copy_url_to_clipboard">Kopírovat URL do schránky</string>
<string name="clipboard_toast">Zkopírováno do schránky</string>
@@ -320,8 +318,6 @@
<string name="block_contents">Blokovat obsah oznámení</string>
<string name="block_images">Blokovat obrázky v oznámení</string>
<string name="notification_channel_receivenotification">Oznámení z ostatních zařízení</string>
<string name="take_picture">Spustit fotoaparát</string>
<string name="plugin_photo_desc">Spusťte aplikaci fotoaparátu pro snadné zachytávání s přenos obrázků</string>
<string name="no_app_for_opening">Pro otevření tohoto souboru nebyla nalezena vhodná aplikace</string>
<string name="remote_keyboard_service">Vzdálená klávesnice pro KDE Connect</string>
<string name="presenter_pointer">Ukazatel</string>
@@ -331,7 +327,7 @@
<string name="empty_trusted_networks_list_text">Nepřidali jste žádné důvěryhodné sítě</string>
<string name="allow_all_networks_text">Povolit všechny</string>
<string name="location_permission_needed_title">Získán přístup</string>
<string name="location_permission_needed_desc">KDE Connect vyžaduje oprávnění o umístění na pozadí aby poznal WiFi, ke které jste připojeni i když je aplikace samotná na pozadí. To je kvůli tomu, že názvy sítí WiFi okolo vás by mohly být použity pro nalezení vaší polohy i když to není to, co KDE Connect dělá.</string>
<string name="location_permission_needed_desc">KDE Connect vyžaduje oprávnění o poloze na pozadí aby poznal WiFi, ke které jste připojeni i když je aplikace samotná na pozadí. To je kvůli tomu, že názvy sítí WiFi okolo vás by mohly být použity pro nalezení vaší polohy i když to není to, co KDE Connect dělá.</string>
<string name="clipboard_android_x_incompat">Android 10 odstranit přístup ke schránce pro všechny aplikace. Tento modul bude zakázán.</string>
<string name="mpris_open_url">Pokračovat v přehrávání zde</string>
<string name="cant_open_url">Nelze otevřít URL pro pokračování v přehrávání</string>

View File

@@ -269,9 +269,7 @@
<string name="notification_channel_default">Andere Benachrichtigungen</string>
<string name="notification_channel_persistent">Dauerhafte Benachrichtigung</string>
<string name="notification_channel_media_control">Medienkontrolle</string>
<string name="notification_channel_filetransfer">Dateiübertragung</string>
<string name="notification_channel_high_priority">Hohe Priorität</string>
<string name="notification_channel_sms_mms">Neue Nachricht</string>
<string name="mpris_stop">Die aktuelle Medienwiedergabe beenden</string>
<string name="copy_url_to_clipboard">Adresse in die Zwischenablage kopieren</string>
<string name="clipboard_toast">In die Zwischenablage kopiert</string>
@@ -300,8 +298,6 @@
<string name="block_contents">Inhalt von Benachrichtigungen blockieren</string>
<string name="block_images">Bilder in Benachrichtigungen blockieren</string>
<string name="notification_channel_receivenotification">Benachrichtigungen verbundener Geräte</string>
<string name="take_picture">Kamera starten</string>
<string name="plugin_photo_desc">Die Kamera starten um das Erstellen und Übertragen von Bildern zu vereinfachen</string>
<string name="no_app_for_opening">Es wurde keine passende App zum Öffnen dieser Datei gefunden</string>
<string name="remote_keyboard_service">Entfernte Tastatur für KDE Connect</string>
<string name="presenter_pointer">Laserpointer</string>

View File

@@ -252,9 +252,7 @@
<string name="pref_plugin_mprisreceiver_desc">Ελέγξτε τους αναπαραγωγείς πολυμέσων του τηλεφώνου σας από άλλη συσκευή</string>
<string name="notification_channel_default">Άλλες ειδοποιήσεις</string>
<string name="notification_channel_media_control">Κονσόλα πολυμέσων</string>
<string name="notification_channel_filetransfer">Μεταφορά αρχείου</string>
<string name="notification_channel_high_priority">Υψηλής προτεραιότητας</string>
<string name="notification_channel_sms_mms">Νέο μήνυμα</string>
<string name="mpris_stop">Διακοπή του τρέχοντος αναπαραγωγέα</string>
<string name="copy_url_to_clipboard">Αντιγραφή του URL στο πρόχειρο</string>
<string name="clipboard_toast">Έγινε αντιγραφή στο πρόχειρο</string>
@@ -283,8 +281,6 @@
<string name="block_contents">Φραγή περιεχομένου ειδοποιήσεων</string>
<string name="block_images">Φραγή εικόνων σε ειδοποιήσεις</string>
<string name="notification_channel_receivenotification">Ειδοποιήσεις από άλλες συσκευές</string>
<string name="take_picture">Εκτέλεση κάμερας</string>
<string name="plugin_photo_desc">Εκτέλεση της εφαρμογής κάμερας για διευκόλυνση στη λήψη και μεταφορά φωτογραφιών</string>
<string name="no_app_for_opening">Δεν βρέθηκε κατάλληλη εφαρμογή για το άνοιγμα αυτού του αρχείου</string>
<string name="remote_keyboard_service">Απομακρυσμένο πληκτρολόγιο KDE Connect</string>
<string name="presenter_pointer">Δείκτης</string>

View File

@@ -273,9 +273,7 @@
<string name="notification_channel_default">Other notifications</string>
<string name="notification_channel_persistent">Persistent indicator</string>
<string name="notification_channel_media_control">Media control</string>
<string name="notification_channel_filetransfer">File transfer</string>
<string name="notification_channel_high_priority">High priority</string>
<string name="notification_channel_sms_mms">New Message</string>
<string name="mpris_stop">Stop the current player</string>
<string name="copy_url_to_clipboard">Copy URL to clipboard</string>
<string name="clipboard_toast">Copied to clipboard</string>
@@ -304,8 +302,6 @@
<string name="block_contents">Block contents of notifications</string>
<string name="block_images">Block images in notifications</string>
<string name="notification_channel_receivenotification">Notifications from other devices</string>
<string name="take_picture">Launch camera</string>
<string name="plugin_photo_desc">Launch the camera app to ease taking and transferring pictures</string>
<string name="no_app_for_opening">No suitable app found to open this file</string>
<string name="remote_keyboard_service">KDE Connect Remote Keyboard</string>
<string name="presenter_pointer">Pointer</string>

View File

@@ -183,6 +183,7 @@
<item>1 minuto</item>
<item>2 minutos</item>
</string-array>
<string name="mpris_notifications_explanation">Se necesita el permiso de notificaciones para mostrar los medios remotos en el panel de notificaciones</string>
<string name="mpris_notification_settings_title">Mostrar notificación del control de medios</string>
<string name="mpris_notification_settings_summary">Permite controlar sus reproductores de medios sin abrir KDE Connect</string>
<string name="share_to">Compartir con...</string>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">Debe otorgar permisos extra para activar todas las funciones</string>
<string name="plugins_need_optional_permission">Algunos complementos tienen funcionalidades desactivadas por falta de permisos (pulse para más información):</string>
<string name="share_optional_permission_explanation">Para recibir archivos necesita permitir el acceso a almacenamiento</string>
<string name="share_notifications_explanation">Para ver el progreso al enviar y recibir archivos necesita activar las notificaciones</string>
<string name="telepathy_permission_explanation">Para leer y escribir SMS desde su escritorio, necesita dar permisos para SMS</string>
<string name="telephony_permission_explanation">Para ver las llamadas telefónicas en el escritorio, necesita dar permisos al registro de llamadas telefónicas y al estado del teléfono</string>
<string name="telephony_optional_permission_explanation">Para ver el nombre de un contacto en lugar de un número telefónico, necesita dar acceso a los contactos de su teléfono</string>
@@ -274,9 +276,9 @@
<string name="notification_channel_default">Otras notificaciones</string>
<string name="notification_channel_persistent">Indicador persistente</string>
<string name="notification_channel_media_control">Control multimedia</string>
<string name="notification_channel_filetransfer">Transferencia de archivo</string>
<string name="notification_channel_filetransfer">Transferencia de archivo entrante</string>
<string name="notification_channel_filetransfer_upload">Transferencia de archivo saliente</string>
<string name="notification_channel_high_priority">Alta prioridad</string>
<string name="notification_channel_sms_mms">Nuevo mensaje</string>
<string name="mpris_stop">Parar el reproductor actual</string>
<string name="copy_url_to_clipboard">Copiar URL al portapapeles</string>
<string name="clipboard_toast">Copiado en el portapapeles</string>
@@ -305,8 +307,6 @@
<string name="block_contents">Bloquear el contenido de las notificaciones</string>
<string name="block_images">Bloquear las imágenes en las notificaciones</string>
<string name="notification_channel_receivenotification">Notificaciones desde otros dispositivos</string>
<string name="take_picture">Lanzar cámara</string>
<string name="plugin_photo_desc">Lanzar la aplicación de la cámara para facilitar tomar y transferir imágenes</string>
<string name="no_app_for_opening">No se encontró ninguna aplicación adecuada para abrir este archivo</string>
<string name="remote_keyboard_service">Teclado remoto de KDE Connect</string>
<string name="presenter_pointer">Puntero</string>
@@ -397,4 +397,8 @@
<string name="send_clipboard">Enviar al portapapeles</string>
<string name="tap_to_execute">Pulse para ejecutar</string>
<string name="plugin_stats">Estadísticas del complemento</string>
<string name="enable_udp_broadcast">Activar descubrimiento de dispositivos por UDP</string>
<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>
</resources>

View File

@@ -228,9 +228,7 @@
<string name="pref_plugin_mprisreceiver_desc">Telefoni meediamängijate juhtimine teisest seadmest</string>
<string name="notification_channel_default">Muud märguanded</string>
<string name="notification_channel_media_control">Meedia juhtimine</string>
<string name="notification_channel_filetransfer">Failiülekanne</string>
<string name="notification_channel_high_priority">Kõrge prioriteediga</string>
<string name="notification_channel_sms_mms">Uus sõnum</string>
<string name="mpris_stop">Peata aktiivne mängija</string>
<string name="copy_url_to_clipboard">Kopeeri URL lõikepuhvrisse</string>
<string name="clipboard_toast">Kopeeriti lõikepuhvrisse</string>
@@ -259,8 +257,6 @@
<string name="block_contents">Märguannete sisu blokkimine</string>
<string name="block_images">Märguannete piltide blokkimine</string>
<string name="notification_channel_receivenotification">Märguanded teistest seadmetest</string>
<string name="take_picture">Käivita kaamera</string>
<string name="plugin_photo_desc">Kaamerarakenduse käivitamine piltide tegemiseks ja ülekandmiseks</string>
<string name="no_app_for_opening">Selle faili avamiseks ei leitud sobivat rakendust</string>
<string name="remote_keyboard_service">KDE Connecti kaugklaviatuur</string>
<string name="presenter_pointer">Osutusseade</string>

View File

@@ -183,6 +183,7 @@
<item>minutu 1</item>
<item>2 minutu</item>
</string-array>
<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>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">Baimen gehiago eman behar dituzu funtzio guztiak gaitzeko</string>
<string name="plugins_need_optional_permission">Plugin batzuek desgaitutako eginbideak dituzte baimenak faltan dituztelako (tak egin informazio gehiagorako):</string>
<string name="share_optional_permission_explanation">Fitxategiak jasotzeko biltegiratze sarbidea baimendu behar duzu</string>
<string name="share_notifications_explanation">Fitxategiak bidaltzean eta jasotzean aurrerapena ikusteko, jakinarazpenak baimendu behar dituzu</string>
<string name="telepathy_permission_explanation">SMSak zure mahaigainetik bidali ahal izateko, SMSak erabiltzeko baimena eman behar duzu</string>
<string name="telephony_permission_explanation">Telefono deiak zure mahaigainetik ikusteko, telefono deien egunkarira eta telefonoaren egoerara baimena eman behar duzu</string>
<string name="telephony_optional_permission_explanation">Telefono zenbakiaren ordez kontaktuaren izena ikusteko telefonoko kontaktuak atzitzeko baimena eman behar duzu</string>
@@ -274,9 +276,10 @@
<string name="notification_channel_default">Beste jakinarazpen batzuk</string>
<string name="notification_channel_persistent">Adierazle iraunkorra</string>
<string name="notification_channel_media_control">Euskarrien kontrola</string>
<string name="notification_channel_filetransfer">Fitxategi transferentzia</string>
<string name="notification_channel_filetransfer">Sarrerako fitxategi transmisioa</string>
<string name="notification_channel_filetransfer_upload">Irteerako fitxategi transmisioa</string>
<string name="notification_channel_filetransfer_error">Fitxategi transmisio errorea</string>
<string name="notification_channel_high_priority">Lehentasun handia</string>
<string name="notification_channel_sms_mms">Mezu berria</string>
<string name="mpris_stop">Gelditu uneko jotzailea</string>
<string name="copy_url_to_clipboard">Kopiatu URLa arbelera</string>
<string name="clipboard_toast">Arbelera kopiatua</string>
@@ -305,8 +308,6 @@
<string name="block_contents">Oztopatu jakinarazpenen edukiak</string>
<string name="block_images">Oztopatu jakinarazpenen irudiak</string>
<string name="notification_channel_receivenotification">Beste gailu batzuen jakinarazpenak</string>
<string name="take_picture">Abiarazi kamera</string>
<string name="plugin_photo_desc">Abiarazi kamerako aplikazioa argazkiak hartzeko eta transferitzeko</string>
<string name="no_app_for_opening">Ez da fitxategi hau irekitzeko aplikazio egokirik aurkitu</string>
<string name="remote_keyboard_service">KDE Connect urruneko teklatua</string>
<string name="presenter_pointer">Erakuslea</string>
@@ -397,4 +398,8 @@
<string name="send_clipboard">Bidali arbelekoa</string>
<string name="tap_to_execute">Tak egin exekutatzeko</string>
<string name="plugin_stats">Pluginaren estatistikak</string>
<string name="enable_udp_broadcast">Gaitu UDP bidez gailua aurkitzea</string>
<string name="receive_notifications_permission_explanation">Jakinarazpenak baimendu behar dira beste gailuetatik haiek jasotzeko</string>
<string name="findmyphone_notifications_explanation">Aplikazioa atzeko planoan dagoenean telefonoak jo dezan jakinarazpen-baimena behar da</string>
<string name="no_notifications">Jakinarazpenak ezgaituta daude, ez duzu jasoko parekatzeko sarrerako jakinarazpenik.</string>
</resources>

View File

@@ -273,9 +273,7 @@
<string name="notification_channel_default">Muut ilmoitukset</string>
<string name="notification_channel_persistent">Pysyvä ilmaisin</string>
<string name="notification_channel_media_control">Mediaohjaimet</string>
<string name="notification_channel_filetransfer">Tiedostonsiirto</string>
<string name="notification_channel_high_priority">Korkea etusija</string>
<string name="notification_channel_sms_mms">Uusi viesti</string>
<string name="mpris_stop">Pysäytä nykyinen soitin</string>
<string name="copy_url_to_clipboard">Kopioi verkko-osoite leikepöydälle</string>
<string name="clipboard_toast">Kopioitu leikepöydälle</string>
@@ -304,8 +302,6 @@
<string name="block_contents">Estä ilmoitusten sisältö</string>
<string name="block_images">Estä ilmoitusten kuvat</string>
<string name="notification_channel_receivenotification">Muiden laitteiden ilmoitukset</string>
<string name="take_picture">Käynnistä kamera</string>
<string name="plugin_photo_desc">Helpota kuvien ottamista ja siirtämistä käynnistämällä kamerasovellus</string>
<string name="no_app_for_opening">Tämän tiedoston avaamiseen sopivaa sovellusta ei löytynyt</string>
<string name="remote_keyboard_service">KDE Connect -etänäppäimistö</string>
<string name="presenter_pointer">Osoitin</string>

View File

@@ -97,6 +97,7 @@
<string name="pref_plugin_mousepad_send_keystrokes">Envoyez comme appuis de touches</string>
<string name="mouse_receiver_plugin_description">Recevoir les mouvements de la souri distante</string>
<string name="mouse_receiver_plugin_name">Récepteur de souris</string>
<string name="mouse_receiver_no_permissions">Pour recevoir des entrées tactiles à distance, vous devez accorder des autorisations daccessibilité pour contrôler entièrement votre périphérique</string>
<string name="view_status_title">État</string>
<string name="battery_status_format">Batterie : %d %%</string>
<string name="battery_status_low_format">Batterie : %d %% Batterie faible</string>
@@ -273,9 +274,7 @@
<string name="notification_channel_default">Autres notifications</string>
<string name="notification_channel_persistent">Notification persistante</string>
<string name="notification_channel_media_control">Contrôle multimédia</string>
<string name="notification_channel_filetransfer">Transfert de fichiers</string>
<string name="notification_channel_high_priority">Haute priorité</string>
<string name="notification_channel_sms_mms">Nouveau message</string>
<string name="mpris_stop">Arrêter le lecteur actuel</string>
<string name="copy_url_to_clipboard">Copier l\'URL dans le presse-papiers</string>
<string name="clipboard_toast">Copié dans le presse-papier</string>
@@ -304,8 +303,6 @@
<string name="block_contents">Bloquer les contenus des notifications</string>
<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="take_picture">Lancer l\'appareil photo</string>
<string name="plugin_photo_desc">Lancer l\'application appareil photo pour prendre et transférer des photos</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="presenter_pointer">Pointeur</string>

View File

@@ -8,7 +8,7 @@
<string name="pref_plugin_telephony">Notificador de telefonía</string>
<string name="pref_plugin_telephony_desc">Envíe notificacións de chamadas entrantes.</string>
<string name="pref_plugin_battery">Informe da batería</string>
<string name="pref_plugin_battery_desc">Envíe periodicamente un informe sobre o estado da batería.</string>
<string name="pref_plugin_battery_desc">Informar periodicamente do estado da batería.</string>
<string name="pref_plugin_connectivity_report">Informe de conectividade</string>
<string name="pref_plugin_connectivity_report_desc">Informar da forza do sinal e do estado da rede</string>
<string name="pref_plugin_sftp">Revelador do sistema de ficheiros</string>
@@ -86,7 +86,7 @@
<string name="sendkeystrokes_send_to">Enviar as pulsacións de tecla a</string>
<string name="sendkeystrokes_textbox_hint">Enviar as pulsacións de tecla á máquina</string>
<string name="sendkeystrokes_disabled_toast">O envío de pulsación de teclas está desactivado; actíveo na configuración.</string>
<string name="sendkeystrokes_wrong_data">Tipo MIME non válido, ten que ser «text/x-keystrokes».</string>
<string name="sendkeystrokes_wrong_data">Tipo MIME incorrecto, ten que ser «text/x-keystrokes».</string>
<string name="sendkeystrokes_sent_text">Enviouse %1$s ao dispositivo %2$s</string>
<string name="sendkeystrokes_pref_category_summary">Este módulo permite a outras aplicacións compartir segmentos de texto como pulsacións de tecla que se enviarán á máquina conectada</string>
<string name="sendkeystrokes_pref_category_title">Enviar pulsacións de tecla</string>
@@ -150,12 +150,12 @@
<item quantity="other">Enviáronse os %2$d ficheiros a %1$s</item>
</plurals>
<plurals name="send_files_fail_title">
<item quantity="one">Non se puido enviar o ficheiro a %1$s</item>
<item quantity="other">Non se puideron enviar %2$d dos %3$d ficheiros a %1$s</item>
<item quantity="one">Produciuse un erro ao enviar o ficheiro a %1$s</item>
<item quantity="other">Produciuse un erro ao enviar %2$d dos %3$d ficheiros a %1$s</item>
</plurals>
<string name="tap_to_open">Toque para abrir</string>
<string name="received_file_text">Toque para abrir «%1s».</string>
<string name="cannot_create_file">Non se pode crear o ficheiro %s</string>
<string name="cannot_create_file">Non é posíbel crear o ficheiro %s</string>
<string name="tap_to_answer">Toque para contestar</string>
<string name="right_click">Enviar un clic secundario</string>
<string name="middle_click">Enviar un clic central</string>
@@ -183,6 +183,7 @@
<item>1 minuto</item>
<item>2 minutos</item>
</string-array>
<string name="mpris_notifications_explanation">Necesítase o permiso de notificacións para amosar medios remotos no caixón de notificacións.</string>
<string name="mpris_notification_settings_title">Amosar a notificación de control de reprodución.</string>
<string name="mpris_notification_settings_summary">Permitir controlar os reprodutores sen abrir KDE Connect</string>
<string name="share_to">Compartir con…</string>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">Ten que conceder permisos adicionais para activar todas as funcións.</string>
<string name="plugins_need_optional_permission">Algúns complementos teñen funcionalidades desactivadas por mor dunha falta de permisos (toque para máis información):</string>
<string name="share_optional_permission_explanation">Para recibir ficheiros ten que permitir acceder ao almacenamento</string>
<string name="share_notifications_explanation">Para ver o progreso ao enviar ou recibir ficheiros ten que permitir notificacións.</string>
<string name="telepathy_permission_explanation">Para ler e escribir SMS desde o escritorio ten que dar permiso de SMS.</string>
<string name="telephony_permission_explanation">Para ver as chamadas de teléfono no escritorio ten que dar permiso aos rexistros de chamadas telefónicas e ao estado do teléfono</string>
<string name="telephony_optional_permission_explanation">Para ver o nome dun contacto en vez dun número de teléfono ten que dar acceso aos contactos do teléfono.</string>
@@ -274,9 +276,9 @@
<string name="notification_channel_default">Outras notificacións</string>
<string name="notification_channel_persistent">Indicador persistente</string>
<string name="notification_channel_media_control">Control de reprodución</string>
<string name="notification_channel_filetransfer">Transferencia de ficheiros</string>
<string name="notification_channel_filetransfer">Transferencia de ficheiros entrante</string>
<string name="notification_channel_filetransfer_upload">Transferencia de ficheiros saíntes</string>
<string name="notification_channel_high_priority">Prioridade alta</string>
<string name="notification_channel_sms_mms">Mensaxe nova</string>
<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>
@@ -305,8 +307,6 @@
<string name="block_contents">Bloquear o contido das notificacións</string>
<string name="block_images">Bloquear as imaxes nas notificacións</string>
<string name="notification_channel_receivenotification">Notificacións desde outros dispositivos</string>
<string name="take_picture">Iniciar a cámara</string>
<string name="plugin_photo_desc">Iniciar a aplicación da cámara para facilitar sacar e transferir imaxes.</string>
<string name="no_app_for_opening">Non se atopou ningunha aplicación axeitada para abrir o ficheiro.</string>
<string name="remote_keyboard_service">Teclado remoto de KDE Connect</string>
<string name="presenter_pointer">Punteiro</string>
@@ -316,7 +316,7 @@
<string name="empty_trusted_networks_list_text">Aínda non engadiu ningunha rede de confianza</string>
<string name="allow_all_networks_text">Permitilas todas</string>
<string name="location_permission_needed_title">Require permiso</string>
<string name="location_permission_needed_desc">KDE Connect necesita o permiso de localización en segundo planto para saber a rede WiFi á que o dispositivo está conectado incluso cando a aplicación está en segundo plano. Isto é porque o nome das redes WiFi ao redor seu podería usarse para descubrir a súa localización, aínda que KDE Connect non faga tal cousa.</string>
<string name="location_permission_needed_desc">KDE Connect necesita o permiso de localización en segundo planto para saber a que rede WiFi se conectou incluso cando a aplicación está en segundo plano. Isto é porque o nome das redes WiFi ao redor seu podería usarse para descubrir a súa localización, aínda que KDE Connect non faga tal cousa.</string>
<string name="clipboard_android_x_incompat">Android 10 retirou o acceso ao portapapeis a todas as aplicacións. Desactivarase este complemento.</string>
<string name="mpris_open_url">Continuar reproducindo aquí</string>
<string name="cant_open_url">Non se pode abrir o URL para continuar reproducindo</string>
@@ -365,7 +365,7 @@
<string name="authors">Autoría</string>
<string name="thanks_to">Agradecementos</string>
<string name="easter_egg">Ovo de Pascua</string>
<string name="email_contributor">Enviar unha mensaxe de correo electrónico á persoa colaboradora\n%s</string>
<string name="email_contributor">Escribir por correo electrónico á persoa colaboradora\n%s</string>
<string name="visit_contributors_homepage">Visitar a páxina persoal da persoa colaboradora\n%s</string>
<string name="version">Versión %s</string>
<string name="about_kde">Sobre KDE</string>
@@ -375,14 +375,14 @@
<string name="rise_up">Ir ao principio</string>
<string name="rise_down">Ir ao final</string>
<string name="click_here_to_type">Toque aquí para escribir</string>
<string name="clear_compose">Borrar</string>
<string name="clear_compose">Baleirar</string>
<string name="send_compose">Enviar</string>
<string name="compose_send_title">Preparar un envío</string>
<string name="open_compose_send">Escribir texto</string>
<string name="about_kde_about">"&lt;h1&gt;Sobre&lt;/h1&gt; &lt;p&gt;KDE é unha comunidade internacional de persoas dedicadas á enxeñaría de software, á arte, á documentación, á tradución e á creación, todas elas comprometidas co desenvolvemento de &lt;a href=https://www.gnu.org/philosophy/free-sw.html&gt;software libre&lt;/a&gt;. KDE produce o contorno de escritorio Plasma, centos de aplicacións, e as moitas bibliotecas de software sobre as que estas están construídas.&lt;/p&gt; &lt;p&gt;KDE é un esforzo cooperativo: non hai unha única entidade que controle a súa dirección ou os seus produtos. No seu lugar, xuntámonos para traballar no obxectivo común de construír o mellor software libre do mundo. Todas as persoas son benvidas a &lt;a href=https://community.kde.org/Get_Involved&gt;unirse e colaborar&lt;/a&gt; en KDE, incluída vostede.&lt;/p&gt; Visite &lt;a href=https://www.kde.org/&gt;https://www.kde.org/&lt;/a&gt; para máis información sobre a comunidade KDE e o software que produce."</string>
<string name="about_kde_about">"&lt;h1&gt;Sobre&lt;/h1&gt; &lt;p&gt;KDE é unha comunidade internacional de persoas dedicadas á enxeñaría de soporte lóxico, á arte, á documentación, á tradución e á creación, todas elas comprometidas co desenvolvemento de &lt;a href=https://www.gnu.org/philosophy/free-sw.html&gt;soporte lóxico libre&lt;/a&gt;. KDE produce o contorno de escritorio Plasma, centos de aplicacións, e as moitas bibliotecas de soporte lóxico sobre as que estas están construídas.&lt;/p&gt; &lt;p&gt;KDE é un esforzo cooperativo: non hai unha única entidade que controle a súa dirección ou os seus produtos. No seu lugar, xuntámonos para traballar no obxectivo común de construír o mellor soporte lóxico libre do mundo. Todas as persoas son benvidas a &lt;a href=https://community.kde.org/Get_Involved&gt;unirse e colaborar&lt;/a&gt; en KDE, incluída vostede.&lt;/p&gt; Visite &lt;a href=https://www.kde.org/&gt;https://www.kde.org/&lt;/a&gt; para máis información sobre a comunidade KDE e o soporte lóxico que produce."</string>
<string name="about_kde_report_bugs_or_wishes">&lt;h1&gt;Informe de fallos ou pida melloras&lt;/h1&gt; &lt;p&gt;O software sempre pode mellorarse, e o equipo de KDE está preparado para facelo. Porén, vostede, a persoa usuaria, ten que avisarnos cando algo non funciona como espera ou podería mellorarse.&lt;/p&gt; &lt;p&gt;KDE ten un sistema de seguimento de fallos. Visite &lt;a href=https://bugs.kde.org/&gt;https://bugs.kde.org/&lt;/a&gt; ou use o botón de «Informar dun fallo» da pantalla de información para informar dun fallo.&lt;/p&gt; Se ten unha suxestión de mellora tamén pode usar o sistema de seguimento de fallos para rexistrala. Asegúrese nese caso de usar a severidade «Lista de desexos».</string>
<string name="about_kde_join_kde">&lt;h1&gt;Únase a KDE&lt;/h1&gt; &lt;p&gt;Non necesita saber desenvolver software para formar parte do equipo de KDE. Pode unirse aos equipos nacionais que traducen as interfaces dos programas. Pode crear imaxes, temas, sons, e mellorar a documentación. Vostede decide!&lt;/p&gt; &lt;p&gt;Visite &lt;a href=https://community.kde.org/Get_Involved&gt;https://community.kde.org/Get_Involved&lt;/a&gt; para informarse sobre os proxectos nos que pode participar.&lt;/p&gt; Se necesita máis información ou documentación, ten o que necesita en &lt;a href=https://techbase.kde.org/&gt;https://techbase.kde.org/&lt;/a&gt;.</string>
<string name="about_kde_support_kde">&lt;h1&gt;Apoie KDE&lt;/h1&gt; &lt;p&gt;O software de KDE está e estará sempre dispoñíbel de balde, porén crealo ten custos.&lt;/p&gt; &lt;p&gt;Para apoiar o seu desenvolvemento, a comunidade KDE formou o KDE e.V., unha organización sen ánimo de lucro fundada legalmente na Alemaña. KDE e.V. representa á comunidade KDE en asuntos legais e financeiros. Consulte &lt;a href=https://ev.kde.org/&gt;https://ev.kde.org/&lt;/a&gt; para máis información sobre KDE e.V.&lt;/p&gt; &lt;p&gt;KDE benefíciase de moitos tipos de contribucións, incluídas as monetarias. Usamos os fondos para cubrir gastos derivados de colaborar. A maiores, os fondos úsanse para asistencia legal e para organizar conferencias e encontros.&lt;/p&gt; &lt;p&gt;Animámoslle a apoiar os nosos esforzos cunha doazón monetaria, mediante un dos sistemas detallados en &lt;a href=https://www.kde.org/community/donations/&gt;https://www.kde.org/community/donations/&lt;/a&gt;.&lt;/p&gt; Moitas grazas de antemán polo seu apoio.</string>
<string name="about_kde_join_kde">&lt;h1&gt;Únase a KDE&lt;/h1&gt; &lt;p&gt;Non necesita saber desenvolver software para formar parte do equipo de KDE. Pode unirse aos equipos nacionais que traducen as interfaces dos programas. Pode fornecer imaxes, temas, sons, e mellorar a documentación. Vostede decide!&lt;/p&gt; &lt;p&gt;Visite &lt;a href=https://community.kde.org/Get_Involved&gt;https://community.kde.org/Get_Involved&lt;/a&gt; para informarse sobre os proxectos nos que pode participar.&lt;/p&gt; Se necesita máis información ou documentación, ten o que necesita en &lt;a href=https://techbase.kde.org/&gt;https://techbase.kde.org/&lt;/a&gt;.</string>
<string name="about_kde_support_kde">&lt;h1&gt;Apoie KDE&lt;/h1&gt; &lt;p&gt;O soporte lóxico de KDE está e estará sempre dispoñíbel de balde, porén crealo ten custos.&lt;/p&gt; &lt;p&gt;Para apoiar o seu desenvolvemento, a comunidade KDE formou o KDE e.V., unha organización sen ánimo de lucro fundada legalmente na Alemaña. KDE e.V. representa á comunidade KDE en asuntos legais e financeiros. Consulte &lt;a href=https://ev.kde.org/&gt;https://ev.kde.org/&lt;/a&gt; para máis información sobre KDE e.V.&lt;/p&gt; &lt;p&gt;KDE benefíciase de moitos tipos de contribucións, incluídas as monetarias. Usamos os fondos para cubrir gastos derivados de colaborar. A maiores, os fondos úsanse para asistencia legal e para organizar conferencias e encontros.&lt;/p&gt; &lt;p&gt;Animámoslle a apoiar os nosos esforzos cunha doazón monetaria, mediante un dos sistemas detallados en &lt;a href=https://www.kde.org/community/donations/&gt;https://www.kde.org/community/donations/&lt;/a&gt;.&lt;/p&gt; Moitas grazas de antemán polo seu apoio.</string>
<string name="maintainer_and_developer">Mantemento e desenvolvemento</string>
<string name="developer">Desenvolvemento</string>
<string name="apple_support">Compatibilidade con macOS. Traballando na compatibilidade con iOS</string>
@@ -390,11 +390,15 @@
<string name="samoilenko_yuri_task">Compatibilidade con SFTP, correccións de fallos e melloras xerais</string>
<string name="aniket_kumar_task">Melloras no complemento de SMS</string>
<string name="alex_fiestas_task">Melloras no complemento de contactos</string>
<string name="maxim_leshchenko_task">Melloras na interface de uso e nesta páxina de información</string>
<string name="maxim_leshchenko_task">Melloras na UI e nesta páxina de información</string>
<string name="holger_kaelberer_task">Complemento de teclado remoto e correccións de fallos</string>
<string name="saikrishna_arcot_task">Posibilidade de usar o teclado no complemento de entrada remota, correccións de fallos e melloras xerais</string>
<string name="everyone_else">O resto de xente que colaborou en KDE Connect ao longo dos anos</string>
<string name="send_clipboard">Enviar o portapapeis</string>
<string name="tap_to_execute">Toque para executar</string>
<string name="plugin_stats">Estatísticas do complemento</string>
<string name="enable_udp_broadcast">Activar o descubrimento de dispositivos UDP.</string>
<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>
</resources>

View File

@@ -261,9 +261,7 @@
<string name="pref_plugin_mprisreceiver_desc">A telefon médialejátszóinak vezérlése egy másik eszközről</string>
<string name="notification_channel_default">Egyéb értesítések</string>
<string name="notification_channel_media_control">Médiavezérlő</string>
<string name="notification_channel_filetransfer">Fájlátvitel</string>
<string name="notification_channel_high_priority">Magas prioritás</string>
<string name="notification_channel_sms_mms">Új üzenet</string>
<string name="mpris_stop">Az aktuális lejátszó leállítása</string>
<string name="copy_url_to_clipboard">URL másolása a vágólapra</string>
<string name="clipboard_toast">Másolva a vágólapra</string>
@@ -292,8 +290,6 @@
<string name="block_contents">Értesítések tartalmának blokkolása</string>
<string name="block_images">Képek blokkolása az értesítésekben</string>
<string name="notification_channel_receivenotification">Értesítések más eszközökről</string>
<string name="take_picture">Kamera indítása</string>
<string name="plugin_photo_desc">A kamera alkalmazás indítása képek készítésének és átvitelének megkönnyítésére</string>
<string name="no_app_for_opening">Nem található alkalmazás a fájl megnyitásához</string>
<string name="remote_keyboard_service">KDE Connect távoli billentyűzet</string>
<string name="presenter_pointer">Mutató</string>

View File

@@ -113,9 +113,9 @@
<string name="settings_icon_description">Icone de Preferentias</string>
<string name="presenter_fullscreen">Schermo plen</string>
<string name="notification_channel_media_control">Controlo de multimedia</string>
<string name="notification_channel_filetransfer">Transferimento de file</string>
<string name="notification_channel_filetransfer">Transferimento de file in arrivata</string>
<string name="notification_channel_filetransfer_upload">Transferimento de file in partita</string>
<string name="notification_channel_high_priority">Prioritate alte</string>
<string name="notification_channel_sms_mms">Nove message</string>
<string name="copy_url_to_clipboard">Copia URL a area de transferentia</string>
<string name="runcommand_notpaired">Dispositivo non es associate</string>
<string name="pref_plugin_systemvolume">Volumine de systema</string>
@@ -127,7 +127,6 @@
<string name="settings_more_settings_title">Altere preferentias</string>
<string name="extra_options">Optiones extra</string>
<string name="privacy_options">Optiones de confidentialitate</string>
<string name="take_picture">Lancea camera</string>
<string name="presenter_pointer">Punctator</string>
<string name="trusted_networks">Retes digne de fide</string>
<string name="add_trusted_network">Adde %1s</string>

View File

@@ -253,9 +253,7 @@
<string name="pref_plugin_mprisreceiver_desc">Kendalikan pemutar media ponsel Anda dari peranti lainnya</string>
<string name="notification_channel_default">Notifikasi lainnya</string>
<string name="notification_channel_media_control">Kontrol multimedia</string>
<string name="notification_channel_filetransfer">Transfer file</string>
<string name="notification_channel_high_priority">Prioritas tinggi</string>
<string name="notification_channel_sms_mms">Pesan Baru</string>
<string name="mpris_stop">Hentikan player saat ini</string>
<string name="copy_url_to_clipboard">Salin URL ke clipboard</string>
<string name="clipboard_toast">Disalin ke clipboard</string>
@@ -284,8 +282,6 @@
<string name="block_contents">Blokir konten-konten notifikasi</string>
<string name="block_images">Blokir citra-citra dalam notifikasi</string>
<string name="notification_channel_receivenotification">Notifikasi dari peranti lainnya</string>
<string name="take_picture">Luncurkan kamera</string>
<string name="plugin_photo_desc">Luncurkan aplikasi kamera untuk memudahkan mengambil dan mentransfer foto</string>
<string name="no_app_for_opening">Tidak menemukan aplikasi yang dapat membuka berkas ini</string>
<string name="remote_keyboard_service">Keyboard Remote KDE Connect</string>
<string name="presenter_pointer">Penunjuk</string>

View File

@@ -235,9 +235,7 @@
<string name="notification_channel_default">Aðrar tilkynningar</string>
<string name="notification_channel_persistent">Viðvarandi gaumvísir</string>
<string name="notification_channel_media_control">Margmiðlunarstýring</string>
<string name="notification_channel_filetransfer">Skráarflutningur</string>
<string name="notification_channel_high_priority">Hár forgangur</string>
<string name="notification_channel_sms_mms">Ný skilaboð</string>
<string name="mpris_stop">Stöðva virkan spilara</string>
<string name="copy_url_to_clipboard">Afrita slóð á klippispjaldið</string>
<string name="clipboard_toast">Afritað á klippispjald</string>
@@ -263,7 +261,6 @@
<string name="block_contents">Loka á efni tilkynninga</string>
<string name="block_images">Loka á myndir í tilkynningum</string>
<string name="notification_channel_receivenotification">Tilkynningar frá öðrum tækjum</string>
<string name="take_picture">Ræsa myndavél</string>
<string name="no_app_for_opening">Ekkert hentugt forrit fannst til að opna þessa skrá</string>
<string name="remote_keyboard_service">Fjartengt lyklaborð KDE Connect</string>
<string name="presenter_pointer">Bendill</string>

View File

@@ -183,6 +183,7 @@
<item>1 minuto</item>
<item>2 minuti</item>
</string-array>
<string name="mpris_notifications_explanation">L\'autorizzazione alle notifiche è necessaria per mostrare i media remoti nel riquadro delle notifiche</string>
<string name="mpris_notification_settings_title">Mostra la notifica del controllo multimediale</string>
<string name="mpris_notification_settings_summary">Consenti di controllare i lettori multimediali senza aprire KDE Connect</string>
<string name="share_to">Condividi con…</string>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">Devi concedere permessi aggiuntivi per abilitare tutte le funzioni</string>
<string name="plugins_need_optional_permission">Alcune estensioni hanno funzioni disabilitate per una mancanza di permessi (tocca per maggiori informazioni):</string>
<string name="share_optional_permission_explanation">Per ricevere i file devi consentire l\'accesso allo spazio di archiviazione</string>
<string name="share_notifications_explanation">Per vedere lo stato di avanzamento durante l\'invio e la ricezione di file è necessario consentire le notifiche</string>
<string name="telepathy_permission_explanation">Per leggere e scrivere SMS dal tuo desktop, devi concedere l\'autorizzazione per SMS</string>
<string name="telephony_permission_explanation">Per vedere le chiamate telefoniche dal desktop devi dare l\'autorizzazione per accedere al registro delle chiamate e allo stato del telefono</string>
<string name="telephony_optional_permission_explanation">Per vedere il nome di un contatto invece del numero di telefono devi dare accesso alla rubrica del telefono</string>
@@ -274,9 +276,9 @@
<string name="notification_channel_default">Altre notifiche</string>
<string name="notification_channel_persistent">Indicatore persistente</string>
<string name="notification_channel_media_control">Controllo multimediale</string>
<string name="notification_channel_filetransfer">Trasferimento file</string>
<string name="notification_channel_filetransfer">Trasferimento di file in arrivo</string>
<string name="notification_channel_filetransfer_upload">Trasferimento di file in uscita</string>
<string name="notification_channel_high_priority">Priorità alta</string>
<string name="notification_channel_sms_mms">Nuovo messaggio</string>
<string name="mpris_stop">Ferma il lettore attuale</string>
<string name="copy_url_to_clipboard">Copia l\'URL negli appunti</string>
<string name="clipboard_toast">Copiato negli appunti</string>
@@ -305,8 +307,6 @@
<string name="block_contents">Blocca i contenuti delle notifiche</string>
<string name="block_images">Blocca le immagini nelle notifiche</string>
<string name="notification_channel_receivenotification">Notifiche da altri dispositivi</string>
<string name="take_picture">Avvia fotocamera</string>
<string name="plugin_photo_desc">Avvia l\'applicazione della fotocamera per scattare e trasferire foto con facilità</string>
<string name="no_app_for_opening">Nessuna applicazione appropriata trovata per aprire questo file</string>
<string name="remote_keyboard_service">Tastiera remota di KDE Connect</string>
<string name="presenter_pointer">Puntatore</string>
@@ -397,4 +397,8 @@
<string name="send_clipboard">Invia gli appunti</string>
<string name="tap_to_execute">Tocca per eseguire</string>
<string name="plugin_stats">Statistiche delle estensioni</string>
<string name="enable_udp_broadcast">Abilita rilevamento UDP dei dispositivi</string>
<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>
</resources>

View File

@@ -266,9 +266,7 @@
<string name="notification_channel_default">他の通知</string>
<string name="notification_channel_persistent">永続的なインジケータ</string>
<string name="notification_channel_media_control">メディアの操作</string>
<string name="notification_channel_filetransfer">ファイル転送</string>
<string name="notification_channel_high_priority">高い優先度</string>
<string name="notification_channel_sms_mms">新しいメッセージ</string>
<string name="mpris_stop">現在のプレーヤーを停止</string>
<string name="copy_url_to_clipboard">URL をクリップボードにコピー</string>
<string name="clipboard_toast">クリップボードにコピーしました</string>
@@ -297,8 +295,6 @@
<string name="block_contents">通知の内容をブロック</string>
<string name="block_images">通知の画像をブロック</string>
<string name="notification_channel_receivenotification">他のデバイスからの通知</string>
<string name="take_picture">カメラを起動</string>
<string name="plugin_photo_desc">写真を撮影して転送するためにカメラを起動</string>
<string name="no_app_for_opening">このファイルを開くための適切なアプリが見つかりません</string>
<string name="remote_keyboard_service">KDE Connect リモートキーボード</string>
<string name="presenter_pointer">ポインタ</string>

View File

@@ -195,9 +195,9 @@
<string name="notification_channel_default">სხვა გაფრთხილებები</string>
<string name="notification_channel_persistent">მუდმივი მაჩვენებელი</string>
<string name="notification_channel_media_control">მედიის კონტროლი</string>
<string name="notification_channel_filetransfer">ფაილის მიმოცვლ</string>
<string name="notification_channel_filetransfer">ფაილის გადაგზავნის შემომავალი მოთხოვნ</string>
<string name="notification_channel_filetransfer_upload">გამავალი ფაილის მიმოცვლა</string>
<string name="notification_channel_high_priority">მაღალი პრიორიტეტი</string>
<string name="notification_channel_sms_mms">ახალი შეტყობინება</string>
<string name="mpris_stop">მიმდინარე დამკვრელის გაჩერება</string>
<string name="copy_url_to_clipboard">URL-ის ბუფერში კოპირება</string>
<string name="clipboard_toast">დაკოპირდა გაცვლის ბაფერში</string>
@@ -219,7 +219,6 @@
<string name="set_privacy_options">თქვენი კონფიდენციალობის პარამეტრების დაყენება</string>
<string name="block_contents">გაფრთხილების შემცველობის დაბლოკვა</string>
<string name="block_images">გაფრთხილებებში გამოსახულებების დაბლოკვა</string>
<string name="take_picture">კამერის გაშვება</string>
<string name="presenter_pointer">კურსორი</string>
<string name="trusted_networks">სანდო ქსელები</string>
<string name="add_trusted_network">%1s-ის დაყენება</string>

View File

@@ -266,9 +266,7 @@
<string name="notification_channel_default">기타 알림</string>
<string name="notification_channel_persistent">항상 표시된 표시기</string>
<string name="notification_channel_media_control">미디어 제어</string>
<string name="notification_channel_filetransfer">파일 전송</string>
<string name="notification_channel_high_priority">높은 우선 순위</string>
<string name="notification_channel_sms_mms">새 메시지</string>
<string name="mpris_stop">현재 재생기 정지</string>
<string name="copy_url_to_clipboard">클립보드로 URL 복사</string>
<string name="clipboard_toast">클립보드에 복사됨</string>
@@ -297,8 +295,6 @@
<string name="block_contents">알림 내용 숨기기</string>
<string name="block_images">알림 이미지 숨기기</string>
<string name="notification_channel_receivenotification">다른 장치의 알림</string>
<string name="take_picture">카메라 실행</string>
<string name="plugin_photo_desc">카메라 앱을 실행하여 쉽게 사진을 찍고 전송</string>
<string name="no_app_for_opening">이 파일을 열 수 있는 앱을 찾을 수 없음</string>
<string name="remote_keyboard_service">KDE Connect 원격 키보드</string>
<string name="presenter_pointer">포인터</string>

View File

@@ -279,9 +279,7 @@
<string name="notification_channel_default">Kiti pranešimai</string>
<string name="notification_channel_persistent">Pastovus indikatorius</string>
<string name="notification_channel_media_control">Įvairialypės terpės valdymas</string>
<string name="notification_channel_filetransfer">Failų persiuntimas</string>
<string name="notification_channel_high_priority">Didelė pirmenybė</string>
<string name="notification_channel_sms_mms">Nauja žinutė</string>
<string name="mpris_stop">Stabdyti dabartinę leistuvę</string>
<string name="copy_url_to_clipboard">Kopijuoti URL į iškarpinę</string>
<string name="clipboard_toast">Nukopijuota į iškarpinę</string>
@@ -310,8 +308,6 @@
<string name="block_contents">Blokuoti pranešimų turinį</string>
<string name="block_images">Blokuoti pranešimuose paveiksliukus</string>
<string name="notification_channel_receivenotification">Pranešimai iš kitų įrenginių</string>
<string name="take_picture">Paleisti kamerą</string>
<string name="plugin_photo_desc">Paleisti kameros programėlę, kad būtų palengvintas nuotraukų darymas ir persiuntimas</string>
<string name="no_app_for_opening">Šio failo atvėrimui nerasta jokios tinkamos programėlės</string>
<string name="remote_keyboard_service">KDE Connect nuotolinė klaviatūra</string>
<string name="presenter_pointer">Rodyklė</string>

View File

@@ -183,6 +183,7 @@
<item>1 minuut</item>
<item>2 minuten</item>
</string-array>
<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>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">U moet toestemming geven om alle functies in te schakelen</string>
<string name="plugins_need_optional_permission">Sommige plug-ins hebben functies uitgeschakeld vanwege ontbrekende toestemming (tik voor meer informatie):</string>
<string name="share_optional_permission_explanation">Om bestanden te ontvangen die u nodig hebt voor toegang tot opslag</string>
<string name="share_notifications_explanation">Om de voortgang te zien bij verzenden en ontvangen van bestanden moet u meldingen toestaan</string>
<string name="telepathy_permission_explanation">Om een SMS te lezen of te schrijven vanaf uw bureaublad moet u toestemming geven tot SMS</string>
<string name="telephony_permission_explanation">Om telefoonoproepen te zien op het bureaublad moet u toestemming geven tot telefoonoproeplogs en telefoonstatus</string>
<string name="telephony_optional_permission_explanation">Om een naam van een contactpersoon te zien in plaats van een telefoonnummer moet u toegang geven tot de contacten in uw telefoon</string>
@@ -274,9 +276,10 @@
<string name="notification_channel_default">Overige meldingen</string>
<string name="notification_channel_persistent">Blijvende indicator</string>
<string name="notification_channel_media_control">Besturing van media</string>
<string name="notification_channel_filetransfer">Bestandsoverdracht</string>
<string name="notification_channel_filetransfer">Inkomende bestandsoverdracht</string>
<string name="notification_channel_filetransfer_upload">Uitgaande bestandsoverdracht</string>
<string name="notification_channel_filetransfer_error">Bestandsoverdrachtfout</string>
<string name="notification_channel_high_priority">Hoge prioriteit</string>
<string name="notification_channel_sms_mms">Nieuw bericht</string>
<string name="mpris_stop">Stop de huidige speler</string>
<string name="copy_url_to_clipboard">URL-adres kopiëren naar klembord</string>
<string name="clipboard_toast">Gekopieerd naar klembord</string>
@@ -305,8 +308,6 @@
<string name="block_contents">Inhoud van meldingen blokkeren</string>
<string name="block_images">Afbeeldingen in meldingen blokkeren</string>
<string name="notification_channel_receivenotification">Meldingen van andere apparaten</string>
<string name="take_picture">Start camera</string>
<string name="plugin_photo_desc">Start de camera-app om nemen en overdragen van afbeeldingen te vergemakkelijken</string>
<string name="no_app_for_opening">Geen geschikte toepassing gevonden om dit bestand te openen</string>
<string name="remote_keyboard_service">KDE Connect Toetsenbord op afstand</string>
<string name="presenter_pointer">Aanwijzer</string>
@@ -397,4 +398,8 @@
<string name="send_clipboard">Klembord verzenden</string>
<string name="tap_to_execute">Tik om uit te voeren</string>
<string name="plugin_stats">Plug-in-statistieken</string>
<string name="enable_udp_broadcast">Ontdekken van UDP-apparaat inschakelen</string>
<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>
</resources>

View File

@@ -274,9 +274,7 @@
<string name="notification_channel_default">Andre varslingar</string>
<string name="notification_channel_persistent">Evigvarande varsling</string>
<string name="notification_channel_media_control">Mediestyring</string>
<string name="notification_channel_filetransfer">Filoverføring</string>
<string name="notification_channel_high_priority">Høg prioritet</string>
<string name="notification_channel_sms_mms">Ny melding</string>
<string name="mpris_stop">Stopp gjeldande avspelar</string>
<string name="copy_url_to_clipboard">Kopier adresse til utklippstavla</string>
<string name="clipboard_toast">Kopiert til utklippstavla</string>
@@ -305,8 +303,6 @@
<string name="block_contents">Blokker varslingsinnhald</string>
<string name="block_images">Blokker bilete i varslingar</string>
<string name="notification_channel_receivenotification">Varslingar frå andre einingar</string>
<string name="take_picture">Opna kamera</string>
<string name="plugin_photo_desc">Opna kamera-appen for å gjera det lettare å ta og overføra bilete</string>
<string name="no_app_for_opening">Fann ikkje nokon app som kan opna denne fila</string>
<string name="remote_keyboard_service">KDE Connect fjerntastatur</string>
<string name="presenter_pointer">Peikar</string>

View File

@@ -288,9 +288,7 @@
<string name="notification_channel_default">Inne powiadomienia</string>
<string name="notification_channel_persistent">Nieznikający wskaźnik</string>
<string name="notification_channel_media_control">Sterowanie multimediami</string>
<string name="notification_channel_filetransfer">Przesyłanie plików</string>
<string name="notification_channel_high_priority">Wysoki priorytet</string>
<string name="notification_channel_sms_mms">Nowa wiadomość</string>
<string name="mpris_stop">Zatrzymaj bieżący odtwarzacz</string>
<string name="copy_url_to_clipboard">Skopiuj adres URL do schowka</string>
<string name="clipboard_toast">Skopiowano do schowka</string>
@@ -319,8 +317,6 @@
<string name="block_contents">Blokuj treści w powiadomieniach</string>
<string name="block_images">Blokuj obrazy w powiadomieniach</string>
<string name="notification_channel_receivenotification">Powiadomienia z innych urządzeń</string>
<string name="take_picture">Uruchamianie aparatu</string>
<string name="plugin_photo_desc">Zezwala na uruchamianie aparatu, aby ułatwić robienie i przesyłanie zdjęć</string>
<string name="no_app_for_opening">Nie znaleziono aplikacji do otwarcia tego pliku</string>
<string name="remote_keyboard_service">Zdalna klawiatura KDE Connect</string>
<string name="presenter_pointer">Wskaźnik</string>

View File

@@ -274,9 +274,7 @@
<string name="notification_channel_default">Outras notificações</string>
<string name="notification_channel_persistent">Indicador persistente</string>
<string name="notification_channel_media_control">Controle multimídia</string>
<string name="notification_channel_filetransfer">Transferência de arquivo</string>
<string name="notification_channel_high_priority">Prioridade alta</string>
<string name="notification_channel_sms_mms">Nova mensagem</string>
<string name="mpris_stop">Parar o reprodutor atual</string>
<string name="copy_url_to_clipboard">Copiar URL para a área de transferência</string>
<string name="clipboard_toast">Copiado para a área de transferência</string>
@@ -305,8 +303,6 @@
<string name="block_contents">Bloquear o conteúdo das notificações</string>
<string name="block_images">Bloquear as imagens das notificações</string>
<string name="notification_channel_receivenotification">Notificações dos outros dispositivos</string>
<string name="take_picture">Iniciar câmera</string>
<string name="plugin_photo_desc">Iniciar o aplicativo da câmera para facilitar a captura e transferência de fotos</string>
<string name="no_app_for_opening">Não foi encontrado nenhum aplicativo adequado para abrir este arquivo</string>
<string name="remote_keyboard_service">Teclado Remoto do KDE Connect</string>
<string name="presenter_pointer">Ponteiro</string>

View File

@@ -273,9 +273,7 @@
<string name="notification_channel_default">Outras notificações</string>
<string name="notification_channel_persistent">Indicador persistente</string>
<string name="notification_channel_media_control">Comando multimédia</string>
<string name="notification_channel_filetransfer">Transferência de ficheiros</string>
<string name="notification_channel_high_priority">Alta prioridade</string>
<string name="notification_channel_sms_mms">Nova Mensagem</string>
<string name="mpris_stop">Parar o leitor actual</string>
<string name="copy_url_to_clipboard">Copiar o URL para a área de transferência</string>
<string name="clipboard_toast">Copiado para a área de transferência</string>
@@ -304,8 +302,6 @@
<string name="block_contents">Bloquear o conteúdo das notificações</string>
<string name="block_images">Bloquear as imagens das notificações</string>
<string name="notification_channel_receivenotification">Notificações dos outros dispositivos</string>
<string name="take_picture">Lançar a câmara</string>
<string name="plugin_photo_desc">Lança a aplicação da câmara para facilitar a tirada de fotografias e sua transferência</string>
<string name="no_app_for_opening">Não existe nenhuma aplicação adequada para abrir este ficheiro</string>
<string name="remote_keyboard_service">Teclado Remoto do KDE Connect</string>
<string name="presenter_pointer">Cursor</string>

View File

@@ -269,9 +269,7 @@
<string name="pref_plugin_mprisreceiver_desc">Controlați programele multimedia din telefon de pe alt dispozitiv</string>
<string name="notification_channel_default">Alte notificări</string>
<string name="notification_channel_media_control">Control multimedia</string>
<string name="notification_channel_filetransfer">Transfer de fișiere</string>
<string name="notification_channel_high_priority">Prioritate ridicată</string>
<string name="notification_channel_sms_mms">Mesaj nou</string>
<string name="mpris_stop">Oprește lectorul actual</string>
<string name="copy_url_to_clipboard">Copiază URL în clipboard</string>
<string name="clipboard_toast">Copiat în clipboard</string>
@@ -300,8 +298,6 @@
<string name="block_contents">Blochează conținutul notificărilor</string>
<string name="block_images">Blochează imaginile din notificări</string>
<string name="notification_channel_receivenotification">Notificări de pe alte dispozitive</string>
<string name="take_picture">Lansează aparatul foto</string>
<string name="plugin_photo_desc">Lansează aplicația de aparat foto pentru a facilita obținerea și transferul pozelor</string>
<string name="no_app_for_opening">Nu a fost găsită nicio aplicație care să deschidă acest fișier</string>
<string name="remote_keyboard_service">Tastatura de la distanță KDE Connect</string>
<string name="presenter_pointer">Indicator</string>

File diff suppressed because one or more lines are too long

View File

@@ -260,9 +260,7 @@
<string name="pref_plugin_mprisreceiver_desc">Ovláda multimediálne prehrávače vášho telefónu z iného zariadenia</string>
<string name="notification_channel_default">Ostatné upozornenia</string>
<string name="notification_channel_media_control">Multimediálny ovládač</string>
<string name="notification_channel_filetransfer">Prenos súborov</string>
<string name="notification_channel_high_priority">Vysoká priorita</string>
<string name="notification_channel_sms_mms">Nová správa</string>
<string name="mpris_stop">Zastaviť aktuálny prehrávač</string>
<string name="copy_url_to_clipboard">Kopírovať URL do schránky</string>
<string name="clipboard_toast">Uložené do schránky</string>
@@ -291,8 +289,6 @@
<string name="block_contents">Blokovať obsah upozornení</string>
<string name="block_images">Blokovať obrázky v upozorneniach</string>
<string name="notification_channel_receivenotification">Upozornenia z iných zariadení</string>
<string name="take_picture">Spustenie fotoaparátu</string>
<string name="plugin_photo_desc">Spustí aplikáciu fotoaparátu na uľahčenie zachytenia a prenosu obrázkov</string>
<string name="no_app_for_opening">Nenašla sa vhodná aplikácia na otvorenie tohto súboru</string>
<string name="remote_keyboard_service">KDE Connect Vzdialená Klávesnica</string>
<string name="presenter_pointer">Ukazovateľ</string>

View File

@@ -199,6 +199,7 @@
<item>1 minuta</item>
<item>2 minuti</item>
</string-array>
<string name="mpris_notifications_explanation">Dovoljenje za obvestila je potrebno za prikaz oddaljenih medijev v predalu za obvestila</string>
<string name="mpris_notification_settings_title">Pokaži obvestilo o nadzoru medija</string>
<string name="mpris_notification_settings_summary">Dovoli nadzor nad predvajalniki medijev, ne da bi odprli KDE Connect</string>
<string name="share_to">Deli z…</string>
@@ -268,6 +269,7 @@
<string name="optional_permission_explanation">Če želite omogočiti vse funkcije, morate podeliti dodatna dovoljenja</string>
<string name="plugins_need_optional_permission">Nekateri vtičniki imajo funkcije onemogočene zaradi pomanjkanja dovoljenj (tapnite za več informacij):</string>
<string name="share_optional_permission_explanation">Če želite prejemati datoteke, morate dovoliti dostop do hrambe</string>
<string name="share_notifications_explanation">Če želite videti napredek pri pošiljanju in prejemanju datotek, morate omogočiti obvestila</string>
<string name="telepathy_permission_explanation">Če želite brati in pisati SMS z namizja, morate izdati dovoljenje za SMS</string>
<string name="telephony_permission_explanation">Če želite videti telefonske klice na namizju, morate dati dovoljenje za dnevnike klicev in stanje telefona</string>
<string name="telephony_optional_permission_explanation">Če želite namesto telefonske številke videti ime stika, morate omogočiti dostop do stikov telefona</string>
@@ -290,9 +292,10 @@
<string name="notification_channel_default">Ostala obvestila</string>
<string name="notification_channel_persistent">Trajni indikator</string>
<string name="notification_channel_media_control">Nadzor medija</string>
<string name="notification_channel_filetransfer">Prenos datotek</string>
<string name="notification_channel_filetransfer">Prenos datotek sem</string>
<string name="notification_channel_filetransfer_upload">Prenos datotek tja</string>
<string name="notification_channel_filetransfer_error">Napaka pri prenosu datoteke</string>
<string name="notification_channel_high_priority">Visoka prednost</string>
<string name="notification_channel_sms_mms">Novo sporočilo</string>
<string name="mpris_stop">Ustavi trenutni predvajalnik</string>
<string name="copy_url_to_clipboard">Kopiraj spletni naslov na odložišče</string>
<string name="clipboard_toast">Kopirano na odložišče</string>
@@ -321,8 +324,6 @@
<string name="block_contents">Blokiraj vsebine obvestil</string>
<string name="block_images">Blokiraj slike v obvestilih</string>
<string name="notification_channel_receivenotification">Obvestila ostalih naprav</string>
<string name="take_picture">Zaženi kamero</string>
<string name="plugin_photo_desc">Zaženite aplikacijo za kamero, da olajšate fotografiranje in prenos fotografij</string>
<string name="no_app_for_opening">Ni primerne aplikacije za odpiranje te datoteke</string>
<string name="remote_keyboard_service">Oddaljena tipkovnica KDE Connect</string>
<string name="presenter_pointer">Kazalec</string>
@@ -413,4 +414,8 @@
<string name="send_clipboard">Pošlji odložišče</string>
<string name="tap_to_execute">Tapkajte za izvedbo</string>
<string name="plugin_stats">Stanje vtičnikov</string>
<string name="enable_udp_broadcast">Omogoči odkrivanje naprav UDP</string>
<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>
</resources>

View File

@@ -183,6 +183,7 @@
<item>1 minut</item>
<item>2 minuter</item>
</string-array>
<string name="mpris_notifications_explanation">Underrättelserättigheter krävs för att visa fjärrmedia i underrättelselådan</string>
<string name="mpris_notification_settings_title">Visa underrättelser om mediastyrning</string>
<string name="mpris_notification_settings_summary">Tillåt att styra mediaspelare utan att KDE-anslut öppnas</string>
<string name="share_to">Dela med…</string>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">Du måste ge extra rättigheter för att aktivera alla funktioner</string>
<string name="plugins_need_optional_permission">Vissa insticksprogram har inaktiverade funktioner på grund av att rättigheter saknas (rör för mer information):</string>
<string name="share_optional_permission_explanation">För att ta emot filer måste du tillåta lagringsåtkomst</string>
<string name="share_notifications_explanation">För att se förlopp när filer skickas och tas emot måste underrättelser tillåtas</string>
<string name="telepathy_permission_explanation">För att läsa och skriva SMS från skrivbordet måste du ge rättigheter för SMS</string>
<string name="telephony_permission_explanation">För att se telefonsamtal på skrivbordet måste du ge rättigheter för telefonsamtalsloggar och telefontillstånd</string>
<string name="telephony_optional_permission_explanation">För att se ett kontaktnamn istället för ett telefonnummer måste du ge tillgång till telefonens kontakter</string>
@@ -274,9 +276,9 @@
<string name="notification_channel_default">Andra underrättelser</string>
<string name="notification_channel_persistent">Permanent indikering</string>
<string name="notification_channel_media_control">Kontroll av media</string>
<string name="notification_channel_filetransfer">Filöverföring</string>
<string name="notification_channel_filetransfer">Inkommande filöverföring</string>
<string name="notification_channel_filetransfer_upload">Utgående filöverföring</string>
<string name="notification_channel_high_priority">Hög prioritet</string>
<string name="notification_channel_sms_mms">Nytt meddelande</string>
<string name="mpris_stop">Stoppa aktuell spelare</string>
<string name="copy_url_to_clipboard">Kopiera webbadress till klippbordet</string>
<string name="clipboard_toast">Kopierad till klippbordet</string>
@@ -305,8 +307,6 @@
<string name="block_contents">Blockera underrättelsernas innehåll</string>
<string name="block_images">Blockera bilder i underrättelser</string>
<string name="notification_channel_receivenotification">Underrättelser från andra apparater</string>
<string name="take_picture">Starta kamera</string>
<string name="plugin_photo_desc">Starta kameraprogrammet för att förenkla att ta och överföra bilder</string>
<string name="no_app_for_opening">Inget lämpligt program hittades för att öppna filen</string>
<string name="remote_keyboard_service">KDE-anslut fjärrtangentbord</string>
<string name="presenter_pointer">Pekare</string>
@@ -397,4 +397,8 @@
<string name="send_clipboard">Skicka klippbord</string>
<string name="tap_to_execute">Rör för att köra</string>
<string name="plugin_stats">Insticksprogramstatistik</string>
<string name="enable_udp_broadcast">Aktivera UDP-enhetsupptäckt</string>
<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>
</resources>

View File

@@ -183,6 +183,7 @@
<item>1 நிமிடம்</item>
<item>2 நிமிடங்கள்</item>
</string-array>
<string name="mpris_notifications_explanation">தொலை ஊடக இயக்கிகளை அறிவிப்புகளில் காட்டுவதற்கு அறிவிப்புகள் அனுமதி தேவை</string>
<string name="mpris_notification_settings_title">ஊடக கட்டுப்பாடு அறிவிப்பைக் காட்டு</string>
<string name="mpris_notification_settings_summary">கே.டீ.யீ. கனெக்டைத் திறக்காமல் ஊடக இயக்கிகளைக் கட்டுப்படுத்த உதவும்</string>
<string name="share_to">இதற்கு பகிர்...</string>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">எல்லா செயல்பாடுகளையும் இயக்க நீங்கள் கூடுதல் அனுமதிகளை வழங்க வேண்டும்</string>
<string name="plugins_need_optional_permission">அனுமதி இல்லாததால் சில செருகுநிரல்களின் அம்சங்கள் முடங்கியுள்ளன (மேலும் விவரங்களுக்கு தட்டவும்):</string>
<string name="share_optional_permission_explanation">கோப்புகளை பெற சேமிப்பக அனுமதி தேவைப்படலாம்</string>
<string name="share_notifications_explanation">கோப்புகளை அனுப்பும்போதும் பெறும்போதும் முன்னேற்ற நிலையைக் காண அறிவிப்புகளை அனுமதிக்க வேண்டும்</string>
<string name="telepathy_permission_explanation">உங்கள் மேசைக்கணினியிலிருந்து SMS எழுத மற்றும் படிக்க நீங்கள் SMS அனுமதியைத் தர வேண்டும்</string>
<string name="telephony_permission_explanation">மேசைக்கணினியிலிருந்து அழைப்புகளைக் காண நீங்கள் அழைப்பு வரலாறு மற்றும் தொலைபேசி நிலைக்கான அனுமதியைத் தர வேண்டும்</string>
<string name="telephony_optional_permission_explanation">தொலைபேசி எண்ணுக்குப் பதிலாக நபரின் பெயரைக் காண நீங்கள் தொடர்புகளை அணுகும் அனுமதியைத் தர வேண்டும்</string>
@@ -274,9 +276,7 @@
<string name="notification_channel_default">பிற அறிவிப்புகள்</string>
<string name="notification_channel_persistent">விடாப்பிடி அறிவிப்பு</string>
<string name="notification_channel_media_control">ஊடக கட்டுப்பாடு</string>
<string name="notification_channel_filetransfer">கோப்பு இடமாற்றம்</string>
<string name="notification_channel_high_priority">அதிக முன்னுரிமை</string>
<string name="notification_channel_sms_mms">புதிய தகவல்</string>
<string name="mpris_stop">தற்போதைய இயக்கியை நிறுத்து</string>
<string name="copy_url_to_clipboard">முகவரியை பிடிப்புப்பலகையில் நகலெடு</string>
<string name="clipboard_toast">பிடிப்புப்பலகையில் நகலெடுக்கப்பட்டது</string>
@@ -305,8 +305,6 @@
<string name="block_contents">அறிவிப்புகளின் உள்ளடக்கத்தை காட்டாதே</string>
<string name="block_images">அறிவிப்புகளில் படங்களை காட்டாதே</string>
<string name="notification_channel_receivenotification">மற்ற சாதனங்களிலிருந்து அறிவிப்புகள்</string>
<string name="take_picture">புகைப்பட செயலியை திற</string>
<string name="plugin_photo_desc">புகைப்படங்களை எளிதாக எடுக்கவும் மாற்றவும் படக்கருவி செயலியை திறக்கும்</string>
<string name="no_app_for_opening">இக்கோப்பை திறப்பதற்குகந்த செயலி ஏதுமில்லை</string>
<string name="remote_keyboard_service">கே.டீ.யீ. கனெக்ட் தொலை விசைப்பலகை</string>
<string name="presenter_pointer">சுட்டி</string>
@@ -394,4 +392,8 @@
<string name="send_clipboard">பிடிப்புப்பலகையை அனுப்பு</string>
<string name="tap_to_execute">இயக்க தட்டவும்</string>
<string name="plugin_stats">செருகுநிரல் புள்ளிவிவரங்கள்</string>
<string name="enable_udp_broadcast">UDP சாதன கண்டுபிடிப்பை இயக்கு</string>
<string name="receive_notifications_permission_explanation">மற்ற சாதனங்களில் அறிவிப்புகளைப் பெறுவதற்கு அறிவிப்புகள் அனுமதி தேவை</string>
<string name="findmyphone_notifications_explanation">செயலி செயலில் இல்லாதபோதும் தொலைபேசியை இசைக்கச்செய்ய அறிவிப்புகள் அனுமதி தேவை</string>
<string name="no_notifications">அறிவிப்புகள் முடக்கப்பட்டுள்ளன. உள்வரும் இணைப்புக்கோரிக்கைகளை பெறமாட்டீர்.</string>
</resources>

View File

@@ -183,6 +183,7 @@
<item>1 dakika</item>
<item>2 dakika</item>
</string-array>
<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>
@@ -252,6 +253,7 @@
<string name="optional_permission_explanation">Tüm işlevleri etkinleştirmek için daha fazla yetkiye gereksiniminiz var</string>
<string name="plugins_need_optional_permission">Bazı eklentilerin özellikleri, izin yetersizliğinden kapalı gelmektedir (daha fazla bilgi için dokunun):</string>
<string name="share_optional_permission_explanation">Dosyalar almak için depolama erişimini etkinleştirmelisiniz</string>
<string name="share_notifications_explanation">Dosyalar alırken ve gönderirken ilerlemeyi görmek için bildirimlere izin vermeniz gerekir</string>
<string name="telepathy_permission_explanation">Masaüstünde SMS yazma ve okuma yapmak için SMS izni gereklidir</string>
<string name="telephony_permission_explanation">Masaüstünde telefon görüşmelerini görmek için telefon görüşmesi kayıtlarına ve telefon durumuna izin vermeniz gerekir</string>
<string name="telephony_optional_permission_explanation">Telefon numarası yerine kişi adı görebilmek için telefonun kişilerine erişim gereklidir</string>
@@ -269,14 +271,14 @@
<string name="addcommand_explanation">Kayıtlı komut yok</string>
<string name="addcommand_explanation2">KDE Bağlan Sistem Ayarlarında yeni komutlar ekleyebilirsiniz</string>
<string name="add_command_description">Masaüstüne komut ekleyebilirsiniz</string>
<string name="pref_plugin_mprisreceiver">Ortam Oynatıcı Denetimi</string>
<string name="pref_plugin_mprisreceiver">Ortam Oynatıcısı Denetimi</string>
<string name="pref_plugin_mprisreceiver_desc">Telefonunuzun ortam oynatıcılarını başka bir aygıttan denetleyin</string>
<string name="notification_channel_default">Diğer bildirimler</string>
<string name="notification_channel_persistent">Kalıcı gösterge</string>
<string name="notification_channel_media_control">Ortam denetimi</string>
<string name="notification_channel_filetransfer">Dosya aktarımı</string>
<string name="notification_channel_filetransfer">Gelen dosya aktarımı</string>
<string name="notification_channel_filetransfer_upload">Giden dosya aktarımı</string>
<string name="notification_channel_high_priority">Yüksek öncelik</string>
<string name="notification_channel_sms_mms">Yeni İleti</string>
<string name="mpris_stop">Geçerli oynatıcıyı durdur</string>
<string name="copy_url_to_clipboard">URL\'yi panoya kopyala</string>
<string name="clipboard_toast">Panoya kopyalandı</string>
@@ -305,8 +307,6 @@
<string name="block_contents">Bildirimlerin içeriğini engelle</string>
<string name="block_images">Bildirimlerde görüntüleri engelle</string>
<string name="notification_channel_receivenotification">Diğer aygıtlardan gelen bildirimler</string>
<string name="take_picture">Kamerayı başlat</string>
<string name="plugin_photo_desc">Fotoğraf çekmeyi ve aktarmayı kolaylaştırmak için kamera uygulamasını başlatın</string>
<string name="no_app_for_opening">Bu dosyayı açmak için uygun bir uygulama bulunamadı</string>
<string name="remote_keyboard_service">KDE Bağlan Uzaktan Klavye</string>
<string name="presenter_pointer">İşaretçi</string>
@@ -397,4 +397,8 @@
<string name="send_clipboard">Pano gönder</string>
<string name="tap_to_execute">Yürütmek için dokun</string>
<string name="plugin_stats">Eklenti istatistikleri</string>
<string name="enable_udp_broadcast">UDP aygıt keşfini etkinleştir</string>
<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>
</resources>

View File

@@ -199,6 +199,7 @@
<item>1 хвилина</item>
<item>2 хвилини</item>
</string-array>
<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>
@@ -268,6 +269,7 @@
<string name="optional_permission_explanation">Щоб уможливити використання усіх функцій, вам слід надати програмі додаткові права доступу</string>
<string name="plugins_need_optional_permission">Можливості деяких додатків вимкнено, оскільки програмі не вистачає прав доступу (натисніть, щоб дізнатися більше):</string>
<string name="share_optional_permission_explanation">Для отримання файлів вам слід дозволити доступ до сховища даних</string>
<string name="share_notifications_explanation">Для перегляду поступу надсилання та отримання файлів вам слід уможливити показ сповіщень</string>
<string name="telepathy_permission_explanation">Щоб читати і писати SMS з вашого робочого комп’ютера, вам слід надати програмі доступ до SMS</string>
<string name="telephony_permission_explanation">Щоб переглядати дзвінки з робочого комп’ютера, вам слід надати програмі доступ до журналу дзвінків та стану телефону</string>
<string name="telephony_optional_permission_explanation">Щоб бачити ім’я контакту замість номеру телефону, вам слід надати програмі доступ до записів контактів на телефоні</string>
@@ -290,9 +292,10 @@
<string name="notification_channel_default">Інші сповіщення</string>
<string name="notification_channel_persistent">Постійний індикатор</string>
<string name="notification_channel_media_control">Керування відтворенням</string>
<string name="notification_channel_filetransfer">Передавання файлів</string>
<string name="notification_channel_filetransfer">Вхідне перенесення файла</string>
<string name="notification_channel_filetransfer_upload">Вихідне перенесення файла</string>
<string name="notification_channel_filetransfer_error">Помилка передавання файлів</string>
<string name="notification_channel_high_priority">Високий пріоритет</string>
<string name="notification_channel_sms_mms">Нове повідомлення</string>
<string name="mpris_stop">Зупинити відтворення у поточному програвачі</string>
<string name="copy_url_to_clipboard">Скопіювати адресу до буфера</string>
<string name="clipboard_toast">Скопійовано до буфера</string>
@@ -321,8 +324,6 @@
<string name="block_contents">Блокувати вміст сповіщень</string>
<string name="block_images">Блокувати зображення у сповіщеннях</string>
<string name="notification_channel_receivenotification">Сповіщення з інших пристроїв</string>
<string name="take_picture">Запустити камеру</string>
<string name="plugin_photo_desc">Запустити додаток камери для спрощення знімання та передавання фотографій</string>
<string name="no_app_for_opening">Не знайдено відповідної програми для відкриття цього файла</string>
<string name="remote_keyboard_service">Віддалена клавіатура KDE Connect</string>
<string name="presenter_pointer">Указка</string>
@@ -413,4 +414,8 @@
<string name="send_clipboard">Надіслати вміст буфера</string>
<string name="tap_to_execute">Торкніться, щоб виконати</string>
<string name="plugin_stats">Статистика щодо додатків</string>
<string name="enable_udp_broadcast">Увімкнути виявлення пристроїв UDP</string>
<string name="receive_notifications_permission_explanation">Для отримання сповіщень з інших пристроїв має бути уможливлено показ сповіщень</string>
<string name="findmyphone_notifications_explanation">Для уможливлення дзвінків, коли програма перебуває у фоновому режимі, потрібні права доступу до сповіщень</string>
<string name="no_notifications">Показ сповіщень вимкнено, ви не отримуватимете сповіщень щодо вхідних запитів на пов\'язування пристроїв.</string>
</resources>

View File

@@ -65,7 +65,7 @@
<string-array name="mousepad_tap_entries">
<item>左键点击</item>
<item>右键点击</item>
<item>键点击</item>
<item>中键点击</item>
<item>无操作</item>
</string-array>
<string-array name="mousepad_sensitivity_entries">
@@ -175,6 +175,7 @@
<item>1 分钟</item>
<item>2 分钟</item>
</string-array>
<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>
@@ -244,6 +245,7 @@
<string name="optional_permission_explanation">您需要授予额外权限以启用全部功能</string>
<string name="plugins_need_optional_permission">因缺少权限,某些插件的一些功能已禁用(点击以查看更多信息):</string>
<string name="share_optional_permission_explanation">要接收文件,您必须允许存储访问权限</string>
<string name="share_notifications_explanation">要查看发送和接收文件时的进度,您需要允许通知</string>
<string name="telepathy_permission_explanation">从计算机桌面读取、写入短消息需要向应用程序授予 SMS 权限</string>
<string name="telephony_permission_explanation">要桌面上查看手机通话记录,您需要授予访问通话记录和手机状态的权限</string>
<string name="telephony_optional_permission_explanation">要查看联系人姓名而非电话号码,您需要授予访问手机通讯录的权限</string>
@@ -266,9 +268,9 @@
<string name="notification_channel_default">其他通知</string>
<string name="notification_channel_persistent">持久性通知</string>
<string name="notification_channel_media_control">媒体控制</string>
<string name="notification_channel_filetransfer">文件传</string>
<string name="notification_channel_filetransfer">正在传入的文件传</string>
<string name="notification_channel_filetransfer_upload">正在传出的文件传输</string>
<string name="notification_channel_high_priority">高优先级</string>
<string name="notification_channel_sms_mms">新建消息</string>
<string name="mpris_stop">停止但前播放器</string>
<string name="copy_url_to_clipboard">复制 URL 到剪贴板</string>
<string name="clipboard_toast">已复制到剪贴板</string>
@@ -297,8 +299,6 @@
<string name="block_contents">阻止通知内容</string>
<string name="block_images">阻止通知图像</string>
<string name="notification_channel_receivenotification">来自其他设备的通知</string>
<string name="take_picture">启动相机</string>
<string name="plugin_photo_desc">启动相机应用程序以方便拍摄和转移图片</string>
<string name="no_app_for_opening">没有找到合适的应用程序打开此文件</string>
<string name="remote_keyboard_service">KDE Connect 远程键盘</string>
<string name="presenter_pointer">指针</string>
@@ -389,4 +389,8 @@
<string name="send_clipboard">发送剪贴板</string>
<string name="tap_to_execute">轻触执行</string>
<string name="plugin_stats">插件状态</string>
<string name="enable_udp_broadcast">启用 UPnP 设备发现</string>
<string name="receive_notifications_permission_explanation">需要允许通知才能从其他设备接收通知</string>
<string name="findmyphone_notifications_explanation">需要通知权限,这样当应用程序处于后台时手机可以发出铃声</string>
<string name="no_notifications">通知已禁用,您将不会收到传入的配对通知。</string>
</resources>

View File

@@ -223,7 +223,6 @@
<string name="pref_plugin_mprisreceiver_desc">從另外一個裝置操控您手機的媒體播放器</string>
<string name="notification_channel_default">其他通知</string>
<string name="notification_channel_media_control">多媒體控制</string>
<string name="notification_channel_filetransfer">檔案傳輸</string>
<string name="notification_channel_high_priority">高優先度</string>
<string name="mpris_stop">停止目前播放器</string>
<string name="copy_url_to_clipboard">複製 URL 至剪貼簿</string>
@@ -253,8 +252,6 @@
<string name="block_contents">阻擋通知內容</string>
<string name="block_images">阻擋通知中的圖片</string>
<string name="notification_channel_receivenotification">其他裝置上的通知</string>
<string name="take_picture">啟動相機</string>
<string name="plugin_photo_desc">開啟相機應用程式以輕鬆拍攝並傳輸相片</string>
<string name="no_app_for_opening">找不到適合用來開啟此檔案的應用程式</string>
<string name="remote_keyboard_service">KDE 連線遠端鍵盤</string>
<string name="presenter_pointer">指標裝置</string>

View File

@@ -252,6 +252,7 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<item>60000000</item>
<item>120000000</item>
</string-array>
<string name="mpris_notifications_explanation">The notifications permission is needed to show remote media in the notifications drawer</string>
<string name="mpris_notification_settings_title">Show media control notification</string>
<string name="mpris_notification_settings_summary">Allow controlling your media players without opening KDE Connect</string>
<string name="mpris_notification_key" translatable="false">mpris_notification_enabled</string>
@@ -331,10 +332,13 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<string name="optional_permission_explanation">You need to grant extra permissions to enable all functions</string>
<string name="plugins_need_optional_permission">Some plugins have features disabled because of lack of permission (tap for more info):</string>
<string name="share_optional_permission_explanation">To receive files you need to allow storage access</string>
<string name="share_notifications_explanation">To see the progress when sending and receiving files you need to allow notifications</string>
<string name="telepathy_permission_explanation">To read and write SMS from your desktop you need to give permission to SMS</string>
<string name="telephony_permission_explanation">To see phone calls on the desktop you need to give permission to phone call logs and phone state</string>
<string name="telephony_optional_permission_explanation">To see a contact name instead of a phone number you need to give access to the phone\'s contacts</string>
<string name="contacts_permission_explanation">To share your contacts book with the desktop, you need to give contacts permission</string>
<string name="contacts_per_device_confirmation">Your phone contacts will be copied over to this device, so they can be used by the KDE Connect SMS app and other apps.</string>
<string name="select_ringtone">Select a ringtone</string>
<string name="telephony_pref_blocked_title">Blocked numbers</string>
<string name="telephony_pref_blocked_dialog_desc">Don\'t show calls and SMS from these numbers. Please specify one number per line</string>
@@ -356,9 +360,10 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<string name="notification_channel_default">Other notifications</string>
<string name="notification_channel_persistent">Persistent indicator</string>
<string name="notification_channel_media_control">Media control</string>
<string name="notification_channel_filetransfer">File transfer</string>
<string name="notification_channel_filetransfer">Incoming file transfer</string>
<string name="notification_channel_filetransfer_upload">Outgoing file transfer</string>
<string name="notification_channel_filetransfer_error">File transfer error</string>
<string name="notification_channel_high_priority">High priority</string>
<string name="notification_channel_sms_mms">New Message</string>
<string name="mpris_stop">Stop the current player</string>
<string name="copy_url_to_clipboard">Copy URL to clipboard</string>
@@ -392,8 +397,6 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<string name="block_contents">Block contents of notifications</string>
<string name="block_images">Block images in notifications</string>
<string name="notification_channel_receivenotification">Notifications from other devices</string>
<string name="take_picture">Launch camera</string>
<string name="plugin_photo_desc">Launch the camera app to ease taking and transferring pictures</string>
<string name="findmyphone_preference_key_ringtone" translatable="false">findmyphone_ringtone</string>
@@ -547,4 +550,10 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
<string name="plugin_stats">Plugin stats</string>
<string name="enable_udp_broadcast">Enable UDP device discovery</string>
<string name="receive_notifications_permission_explanation">Notifications need to be allowed to receive them from other devices</string>
<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>
</resources>

View File

@@ -6,7 +6,10 @@
package org.kde.kdeconnect.Backends;
import android.net.Network;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -49,7 +52,7 @@ public abstract class BaseLinkProvider {
public abstract void onStart();
public abstract void onStop();
public abstract void onNetworkChange();
public abstract void onNetworkChange(@Nullable Network network);
public abstract String getName();
}

View File

@@ -14,10 +14,13 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Network;
import android.os.Parcelable;
import android.util.Base64;
import android.util.Log;
import androidx.annotation.Nullable;
import org.apache.commons.io.IOUtils;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Device;
@@ -107,7 +110,7 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
}
@Override
public void onNetworkChange() {
public void onNetworkChange(@Nullable Network network) {
onStop();
onStart();
}

View File

@@ -8,9 +8,12 @@ package org.kde.kdeconnect.Backends.LanBackend;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Network;
import android.os.Build;
import android.preference.PreferenceManager;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.json.JSONException;
@@ -25,6 +28,7 @@ import org.kde.kdeconnect.Helpers.TrustedNetworkHelper;
import org.kde.kdeconnect.KdeConnect;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.UserInterface.CustomDevicesActivity;
import org.kde.kdeconnect.UserInterface.SettingsFragment;
import java.io.BufferedReader;
import java.io.IOException;
@@ -58,9 +62,9 @@ import kotlin.text.Charsets;
*/
public class LanLinkProvider extends BaseLinkProvider {
private final static int UDP_PORT = 1716;
private final static int MIN_PORT = 1716;
private final static int MAX_PORT = 1764;
final static int UDP_PORT = 1716;
final static int MIN_PORT = 1716;
final static int MAX_PORT = 1764;
final static int PAYLOAD_TRANSFER_MIN_PORT = 1739;
final static int MAX_UDP_PACKET_SIZE = 1024 * 512;
@@ -69,13 +73,15 @@ public class LanLinkProvider extends BaseLinkProvider {
private final Context context;
private final HashMap<String, LanLink> visibleDevices = new HashMap<>(); //Links by device id
final HashMap<String, LanLink> visibleDevices = new HashMap<>(); // Links by device id
final ConcurrentHashMap<String, Long> lastConnectionTime = new ConcurrentHashMap<>();
private ServerSocket tcpServer;
private DatagramSocket udpServer;
private MdnsDiscovery mdnsDiscovery;
private long lastBroadcast = 0;
private final static long delayBetweenBroadcasts = 200;
@@ -265,6 +271,7 @@ public class LanLinkProvider extends BaseLinkProvider {
public LanLinkProvider(Context context) {
this.context = context;
this.mdnsDiscovery = new MdnsDiscovery(context, this);
}
private void setupUdpListener() {
@@ -297,7 +304,7 @@ public class LanLinkProvider extends BaseLinkProvider {
});
} catch (IOException e) {
Log.e("LanLinkProvider", "UdpReceive exception", e);
onNetworkChange(); // Trigger a UDP broadcast to try to get them to connect to us instead
onNetworkChange(null); // Trigger a UDP broadcast to try to get them to connect to us instead
}
}
Log.w("UdpListener", "Stopping UDP listener");
@@ -351,12 +358,12 @@ public class LanLinkProvider extends BaseLinkProvider {
throw new RuntimeException("This should not be reachable");
}
private void broadcastUdpIdentityPacket() {
if (System.currentTimeMillis() < lastBroadcast + delayBetweenBroadcasts) {
Log.i("LanLinkProvider", "broadcastUdpPacket: relax cowboy");
private void broadcastUdpIdentityPacket(@Nullable Network network) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (!preferences.getBoolean(SettingsFragment.KEY_UDP_BROADCAST_ENABLED, true)) {
Log.i("LanLinkProvider", "UDP broadcast is disabled in settings. Skipping.");
return;
}
lastBroadcast = System.currentTimeMillis();
ThreadHelper.execute(() -> {
List<String> ipStringList = CustomDevicesActivity
@@ -381,12 +388,12 @@ public class LanLinkProvider extends BaseLinkProvider {
return;
}
sendUdpIdentityPacket(ipList);
sendUdpIdentityPacket(ipList, network);
});
}
@WorkerThread
public void sendUdpIdentityPacket(List<InetAddress> ipList) {
public void sendUdpIdentityPacket(List<InetAddress> ipList, @Nullable Network network) {
if (tcpServer == null || !tcpServer.isBound()) {
Log.i("LanLinkProvider", "Won't broadcast UDP packet if TCP socket is not ready yet");
return;
@@ -407,6 +414,14 @@ public class LanLinkProvider extends BaseLinkProvider {
DatagramSocket socket;
try {
socket = new DatagramSocket();
if (network != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
try {
network.bindSocket(socket);
} catch (IOException e) {
Log.w("LanLinkProvider", "Couldn't bind socket to the network");
e.printStackTrace();
}
}
socket.setReuseAddress(true);
socket.setBroadcast(true);
} catch (SocketException e) {
@@ -436,19 +451,32 @@ public class LanLinkProvider extends BaseLinkProvider {
setupUdpListener();
setupTcpListener();
broadcastUdpIdentityPacket();
mdnsDiscovery.startDiscovering();
mdnsDiscovery.startAnnouncing();
broadcastUdpIdentityPacket(null);
}
}
@Override
public void onNetworkChange() {
broadcastUdpIdentityPacket();
public void onNetworkChange(@Nullable Network network) {
if (System.currentTimeMillis() < lastBroadcast + delayBetweenBroadcasts) {
Log.i("LanLinkProvider", "onNetworkChange: relax cowboy");
return;
}
lastBroadcast = System.currentTimeMillis();
broadcastUdpIdentityPacket(network);
mdnsDiscovery.stopDiscovering();
mdnsDiscovery.startDiscovering();
}
@Override
public void onStop() {
//Log.i("KDE/LanLinkProvider", "onStop");
listening = false;
mdnsDiscovery.stopAnnouncing();
mdnsDiscovery.stopDiscovering();
try {
tcpServer.close();
} catch (Exception e) {

View File

@@ -0,0 +1,224 @@
/*
* 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.Backends.LanBackend;
import android.content.Context;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import java.net.InetAddress;
import java.util.Collections;
public class MdnsDiscovery {
static final String LOG_TAG = "MdnsDiscovery";
static final String SERVICE_TYPE = "_kdeconnect._udp";
private final Context context;
private final LanLinkProvider lanLinkProvider;
private final NsdManager mNsdManager;
private NsdManager.RegistrationListener registrationListener;
private NsdManager.DiscoveryListener discoveryListener;
private WifiManager.MulticastLock multicastLock;
private NsdResolveQueue mNsdResolveQueue;
public MdnsDiscovery(Context context, LanLinkProvider lanLinkProvider) {
this.context = context;
this.lanLinkProvider = lanLinkProvider;
this.mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
this.mNsdResolveQueue = new NsdResolveQueue(this.mNsdManager);
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
multicastLock = wifiManager.createMulticastLock("kdeConnectMdnsMulticastLock");
}
void startDiscovering() {
if (discoveryListener == null) {
multicastLock.acquire();
discoveryListener = createDiscoveryListener();
mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener);
}
}
void stopDiscovering() {
try {
if (discoveryListener != null) {
mNsdManager.stopServiceDiscovery(discoveryListener);
multicastLock.release();
}
} catch(IllegalArgumentException e) {
// Ignore "listener not registered" exception
}
discoveryListener = null;
}
void stopAnnouncing() {
try {
if (registrationListener != null) {
mNsdManager.unregisterService(registrationListener);
}
} catch(IllegalArgumentException e) {
// Ignore "listener not registered" exception
}
registrationListener = null;
}
void startAnnouncing() {
if (registrationListener == null) {
NsdServiceInfo serviceInfo;
try {
serviceInfo = createNsdServiceInfo();
} catch (IllegalAccessException e) {
Log.w(LOG_TAG, "Couldn't start announcing via MDNS: " + e.getMessage());
return;
}
registrationListener = createRegistrationListener();
mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener);
}
}
NsdManager.RegistrationListener createRegistrationListener() {
return new NsdManager.RegistrationListener() {
@Override
public void onServiceRegistered(NsdServiceInfo serviceInfo) {
// If Android changed the service name to avoid conflicts, here we can read it.
Log.i(LOG_TAG, "Registered " + serviceInfo.getServiceName());
}
@Override
public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.e(LOG_TAG, "Registration failed with: " + errorCode);
}
@Override
public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
Log.d(LOG_TAG, "Service unregistered: " + serviceInfo);
}
@Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.e(LOG_TAG, "Unregister of " + serviceInfo + " failed with: " + errorCode);
}
};
}
public NsdServiceInfo createNsdServiceInfo() throws IllegalAccessException {
NsdServiceInfo serviceInfo = new NsdServiceInfo();
String deviceId = DeviceHelper.getDeviceId(context);
// Without resolving the DNS, the service name is the only info we have so it must be sufficient to identify a device.
// Also, it must be unique, otherwise it will be automatically renamed. For these reasons we use the deviceId.
serviceInfo.setServiceName(deviceId);
serviceInfo.setServiceType(SERVICE_TYPE);
serviceInfo.setPort(LanLinkProvider.UDP_PORT);
// The following fields aren't really used for anything, since we can't include enough info
// for it to be useful (namely: we can't include the device certificate).
// Each field (key + value) needs to be < 255 bytes. All the fields combined need to be < 1300 bytes.
// Also, on Android Lollipop those fields aren't resolved.
String deviceName = DeviceHelper.getDeviceName(context);
String deviceType = DeviceHelper.getDeviceType(context).toString();
String protocolVersion = Integer.toString(DeviceHelper.ProtocolVersion);
serviceInfo.setAttribute("id", deviceId);
serviceInfo.setAttribute("name", deviceName);
serviceInfo.setAttribute("type", deviceType);
serviceInfo.setAttribute("protocol", protocolVersion);
Log.i(LOG_TAG, "My MDNS info: " + serviceInfo);
return serviceInfo;
}
NsdManager.DiscoveryListener createDiscoveryListener() {
return new NsdManager.DiscoveryListener() {
final String myId = DeviceHelper.getDeviceId(context);
@Override
public void onDiscoveryStarted(String serviceType) {
Log.i(LOG_TAG, "Service discovery started: " + serviceType);
}
@Override
public void onServiceFound(NsdServiceInfo serviceInfo) {
Log.d(LOG_TAG, "Service discovered: " + serviceInfo);
String deviceId = serviceInfo.getServiceName();
if (myId.equals(deviceId)) {
Log.d(LOG_TAG, "Discovered myself, ignoring.");
return;
}
if (lanLinkProvider.visibleDevices.containsKey(deviceId)) {
Log.i(LOG_TAG, "MDNS discovered " + deviceId + " to which I'm already connected to. Ignoring.");
return;
}
// We use a queue because only one service can be resolved at
// a time, otherwise we get error 3 (already active) in onResolveFailed.
mNsdResolveQueue.resolveOrEnqueue(serviceInfo, createResolveListener());
}
@Override
public void onServiceLost(NsdServiceInfo serviceInfo) {
Log.w(LOG_TAG, "Service lost: " + serviceInfo);
// We can't see this device via mdns. This probably means it's not reachable anymore
// but we do nothing here since we have other ways to do detect unreachable devices
// that hopefully will also trigger.
}
@Override
public void onDiscoveryStopped(String serviceType) {
Log.i(LOG_TAG, "MDNS discovery stopped: " + serviceType);
}
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(LOG_TAG, "MDNS discovery start failed: " + errorCode);
}
@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(LOG_TAG, "MDNS discovery stop failed: " + errorCode);
}
};
}
/**
* Returns a new listener instance since NsdManager wants a different listener each time you call resolveService
*/
NsdManager.ResolveListener createResolveListener() {
return new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.w(LOG_TAG, "MDNS error " + errorCode + " resolving service: " + serviceInfo);
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
Log.i(LOG_TAG, "MDNS successfully resolved " + serviceInfo);
// Let the LanLinkProvider handle the connection
InetAddress remoteAddress = serviceInfo.getHost();
lanLinkProvider.sendUdpIdentityPacket(Collections.singletonList(remoteAddress), null);
}
};
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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.Backends.LanBackend;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.util.Log;
import androidx.annotation.NonNull;
import java.util.LinkedList;
public class NsdResolveQueue {
static final String LOG_TAG = "NsdResolveQueue";
final @NonNull NsdManager mNsdManager;
private final Object mLock = new Object();
private final LinkedList<PendingResolve> mResolveRequests = new LinkedList<>();
public NsdResolveQueue(NsdManager nsdManager) {
this.mNsdManager = nsdManager;
}
private static class PendingResolve {
final @NonNull NsdServiceInfo serviceInfo;
final @NonNull NsdManager.ResolveListener listener;
private PendingResolve(@NonNull NsdServiceInfo serviceInfo, @NonNull NsdManager.ResolveListener listener) {
this.serviceInfo = serviceInfo;
this.listener = listener;
}
}
public void resolveOrEnqueue(@NonNull NsdServiceInfo serviceInfo, @NonNull NsdManager.ResolveListener listener) {
synchronized (mLock) {
for (PendingResolve existing : mResolveRequests) {
if (serviceInfo.getServiceName().equals(existing.serviceInfo.getServiceName())) {
Log.i(LOG_TAG, "Not enqueuing a new resolve request for the same service: " + serviceInfo.getServiceName());
return;
}
}
mResolveRequests.addLast(new PendingResolve(serviceInfo, new ListenerWrapper(listener)));
if (mResolveRequests.size() == 1) {
resolveNextRequest();
}
}
}
private class ListenerWrapper implements NsdManager.ResolveListener {
private final @NonNull NsdManager.ResolveListener mListener;
private ListenerWrapper(@NonNull NsdManager.ResolveListener listener) {
mListener = listener;
}
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
mListener.onResolveFailed(serviceInfo, errorCode);
synchronized (mLock) {
mResolveRequests.pop();
resolveNextRequest();
}
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
mListener.onServiceResolved(serviceInfo);
synchronized (mLock) {
mResolveRequests.pop();
resolveNextRequest();
}
}
}
private void resolveNextRequest() {
if (!mResolveRequests.isEmpty()) {
PendingResolve request = mResolveRequests.getFirst();
mNsdManager.resolveService(request.serviceInfo, request.listener);
}
}
}

View File

@@ -7,6 +7,9 @@
package org.kde.kdeconnect.Backends.LoopbackBackend;
import android.content.Context;
import android.net.Network;
import androidx.annotation.Nullable;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
@@ -20,7 +23,7 @@ public class LoopbackLinkProvider extends BaseLinkProvider {
@Override
public void onStart() {
onNetworkChange();
onNetworkChange(null);
}
@Override
@@ -28,7 +31,7 @@ public class LoopbackLinkProvider extends BaseLinkProvider {
}
@Override
public void onNetworkChange() {
public void onNetworkChange(@Nullable Network network) {
LoopbackLink link = new LoopbackLink(context, this);
onConnectionReceived(link);
}

View File

@@ -25,6 +25,7 @@ import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LiveData;
@@ -84,14 +85,14 @@ public class BackgroundService extends Service {
// linkProviders.add(new BluetoothLinkProvider(this));
}
public void onNetworkChange() {
public void onNetworkChange(@Nullable Network network) {
if (!initialized) {
Log.d("KDE/BackgroundService", "ignoring onNetworkChange called before the service is initialized");
return;
}
Log.d("KDE/BackgroundService", "onNetworkChange");
for (BaseLinkProvider a : linkProviders) {
a.onNetworkChange();
a.onNetworkChange(network);
}
}
@@ -130,11 +131,13 @@ public class BackgroundService extends Service {
cm.registerNetworkCallback(networkRequestBuilder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
Log.i("BackgroundService", "Valid network available");
connectedToNonCellularNetwork.postValue(true);
onNetworkChange();
onNetworkChange(network);
}
@Override
public void onLost(Network network) {
Log.i("BackgroundService", "Valid network lost");
connectedToNonCellularNetwork.postValue(false);
}
});
@@ -275,7 +278,7 @@ public class BackgroundService extends Service {
}
}
if (intent != null && intent.getBooleanExtra("refresh", false)) {
onNetworkChange();
onNetworkChange(null);
}
return Service.START_STICKY;
}

View File

@@ -102,13 +102,14 @@ class DeviceInfo(
}
enum class DeviceType {
PHONE, TABLET, COMPUTER, TV;
PHONE, TABLET, DESKTOP, LAPTOP, TV;
override fun toString() =
when (this) {
TABLET -> "tablet"
PHONE -> "phone"
TV -> "tv"
LAPTOP -> "laptop"
else -> "desktop"
}
@@ -120,7 +121,8 @@ enum class DeviceType {
PHONE -> R.drawable.ic_device_phone_32dp
TABLET -> R.drawable.ic_device_tablet_32dp
TV -> R.drawable.ic_device_tv_32dp
else -> R.drawable.ic_device_laptop_32dp
LAPTOP -> R.drawable.ic_device_laptop_32dp
else -> R.drawable.ic_device_desktop_32dp
}
companion object {
@@ -130,7 +132,8 @@ enum class DeviceType {
"phone" -> PHONE
"tablet" -> TABLET
"tv" -> TV
else -> COMPUTER
"laptop" -> LAPTOP
else -> DESKTOP
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.Helpers
import java.net.Inet4Address
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.SocketException
object NetworkHelper {
//Prefer IPv4 over IPv6, because sshfs doesn't seem to like IPv6
// Anything with rmnet is related to cellular connections or USB
// tethering mechanisms. See:
//
// https://android.googlesource.com/kernel/msm/+/android-msm-flo-3.4-kitkat-mr1/Documentation/usb/gadget_rmnet.txt
//
// If we run across an interface that has this, we can safely
// ignore it. In fact, it's much safer to do. If we don't, we
// might get invalid IP adddresses out of it.
@JvmStatic
val localIpAddress: InetAddress?
get() {
var ip6: InetAddress? = null
try {
for (intf in NetworkInterface.getNetworkInterfaces()) {
// Anything with rmnet is related to cellular connections or USB
// tethering mechanisms. See:
//
// https://android.googlesource.com/kernel/msm/+/android-msm-flo-3.4-kitkat-mr1/Documentation/usb/gadget_rmnet.txt
//
// If we run across an interface that has this, we can safely
// ignore it. In fact, it's much safer to do. If we don't, we
// might get invalid IP adddresses out of it.
if (intf.displayName.contains("rmnet")) {
continue
}
val enumIpAddr = intf.inetAddresses
while (enumIpAddr.hasMoreElements()) {
val inetAddress = enumIpAddr.nextElement()
if (!inetAddress.isLoopbackAddress) {
ip6 =
if (inetAddress is Inet4Address) { //Prefer IPv4 over IPv6, because sshfs doesn't seem to like IPv6
return inetAddress
} else {
inetAddress
}
}
}
}
} catch (ignored: SocketException) {
}
return ip6
}
}

View File

@@ -20,6 +20,7 @@ import org.kde.kdeconnect_tp.R;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class NotificationHelper {
@@ -27,8 +28,11 @@ public class NotificationHelper {
public final static String PERSISTENT = "persistent";
public final static String DEFAULT = "default";
public final static String MEDIA_CONTROL = "media_control";
public final static String FILETRANSFER = "filetransfer";
public final static String SMS_MMS = "sms_mms";
public final static String FILETRANSFER_DOWNLOAD = "filetransfer";
public final static String FILETRANSFER_UPLOAD = "filetransfer_upload";
public final static String FILETRANSFER_ERROR = "filetransfer_error";
public final static String RECEIVENOTIFICATION = "receive";
public final static String HIGHPRIORITY = "highpriority";
}
@@ -64,28 +68,42 @@ public class NotificationHelper {
.Builder(Channels.MEDIA_CONTROL, NotificationManagerCompat.IMPORTANCE_LOW)
.setName(context.getString(R.string.notification_channel_media_control))
.build();
final NotificationChannelCompat fileTransferChannel = new NotificationChannelCompat
.Builder(Channels.FILETRANSFER, NotificationManagerCompat.IMPORTANCE_LOW)
final NotificationChannelCompat fileTransferDownloadChannel = new NotificationChannelCompat
.Builder(Channels.FILETRANSFER_DOWNLOAD, NotificationManagerCompat.IMPORTANCE_LOW)
.setName(context.getString(R.string.notification_channel_filetransfer))
.setVibrationEnabled(false)
.build();
final NotificationChannelCompat fileTransferUploadChannel = new NotificationChannelCompat
.Builder(Channels.FILETRANSFER_UPLOAD, NotificationManagerCompat.IMPORTANCE_LOW)
.setName(context.getString(R.string.notification_channel_filetransfer_upload))
.setVibrationEnabled(false)
.build();
final NotificationChannelCompat fileTransferErrorChannel = new NotificationChannelCompat
.Builder(Channels.FILETRANSFER_ERROR, NotificationManagerCompat.IMPORTANCE_HIGH)
.setName(context.getString(R.string.notification_channel_filetransfer_error))
.setVibrationEnabled(false)
.build();
final NotificationChannelCompat receiveNotificationChannel = new NotificationChannelCompat
.Builder(Channels.RECEIVENOTIFICATION, NotificationManagerCompat.IMPORTANCE_DEFAULT)
.setName(context.getString(R.string.notification_channel_receivenotification))
.build();
final NotificationChannelCompat smsMmsChannel = new NotificationChannelCompat
.Builder(Channels.SMS_MMS, NotificationManagerCompat.IMPORTANCE_DEFAULT)
.setName(context.getString(R.string.notification_channel_sms_mms))
.build();
final NotificationChannelCompat highPriorityChannel = new NotificationChannelCompat
.Builder(Channels.HIGHPRIORITY, NotificationManagerCompat.IMPORTANCE_HIGH)
.setName(context.getString(R.string.notification_channel_high_priority))
.build();
final List<NotificationChannelCompat> channels = Arrays.asList(persistentChannel,
defaultChannel, mediaChannel, fileTransferChannel, receiveNotificationChannel,
smsMmsChannel, highPriorityChannel);
defaultChannel, mediaChannel, fileTransferDownloadChannel, fileTransferUploadChannel,
fileTransferErrorChannel, receiveNotificationChannel, highPriorityChannel);
NotificationManagerCompat.from(context).createNotificationChannelsCompat(channels);
// Delete any notification channels which weren't added.
// Use this to deprecate old channels.
NotificationManagerCompat.from(context).deleteUnlistedNotificationChannels(
channels.stream()
.map(notificationChannelCompat -> notificationChannelCompat.getId())
.collect(Collectors.toList()));
}
public static void setPersistentNotificationEnabled(Context context, boolean enabled) {

View File

@@ -8,7 +8,9 @@ package org.kde.kdeconnect.Helpers.SecurityHelpers;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import android.security.keystore.KeyProperties;
import android.util.Base64;
import android.util.Log;
@@ -18,6 +20,7 @@ import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
@@ -29,10 +32,20 @@ public class RsaHelper {
if (!settings.contains("publicKey") || !settings.contains("privateKey")) {
KeyPair keyPair;
String keyAlgorithm;
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
keyPair = keyGen.genKeyPair();
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);
}
keyPair = keyGen.generateKeyPair();
} catch (Exception e) {
Log.e("KDE/initializeRsaKeys", "Exception", e);
return;
@@ -44,6 +57,7 @@ public class RsaHelper {
SharedPreferences.Editor edit = settings.edit();
edit.putString("publicKey", Base64.encodeToString(publicKey, 0).trim() + "\n");
edit.putString("privateKey", Base64.encodeToString(privateKey, 0));
edit.putString("keyAlgorithm", keyAlgorithm);
edit.apply();
}
@@ -53,13 +67,17 @@ public class RsaHelper {
public static PublicKey getPublicKey(Context context) throws GeneralSecurityException {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
byte[] publicKeyBytes = Base64.decode(settings.getString("publicKey", ""), 0);
return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
// For backwards compat: if no keyAlgorithm setting is set, it means it was generated using RSA
String keyAlgorithm = settings.getString("keyAlgorithm", "RSA");
return KeyFactory.getInstance(keyAlgorithm).generatePublic(new X509EncodedKeySpec(publicKeyBytes));
}
public static PrivateKey getPrivateKey(Context context) throws GeneralSecurityException {
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
byte[] privateKeyBytes = Base64.decode(globalSettings.getString("privateKey", ""), 0);
return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
byte[] privateKeyBytes = Base64.decode(settings.getString("privateKey", ""), 0);
// For backwards compat: if no keyAlgorithm setting is set, it means it was generated using RSA
String keyAlgorithm = settings.getString("keyAlgorithm", "RSA");
return KeyFactory.getInstance(keyAlgorithm).generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
}

View File

@@ -98,6 +98,8 @@ public class SslHelper {
return;
}
Log.i("SslHelper", "Key algorithm: " + publicKey.getAlgorithm());
String deviceId = DeviceHelper.getDeviceId(context);
boolean needsToGenerateCertificate = false;
@@ -147,7 +149,9 @@ public class SslHelper {
nameBuilder.build(),
publicKey
);
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
String keyAlgorithm = privateKey.getAlgorithm();
String signatureAlgorithm = "RSA".equals(keyAlgorithm)? "SHA512withRSA" : "SHA512withECDSA";
ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).build(privateKey);
byte[] certificateBytes = certificateBuilder.build(contentSigner).getEncoded();
certificate = parseCertificate(certificateBytes);

View File

@@ -42,7 +42,12 @@ public class KdeConnectBroadcastReceiver extends BroadcastReceiver {
BackgroundService.ForceRefreshConnections(context);
break;
case Intent.ACTION_SCREEN_ON:
BackgroundService.ForceRefreshConnections(context);
try {
BackgroundService.ForceRefreshConnections(context);
} catch (IllegalStateException e) { // To catch ForegroundServiceStartNotAllowedException
Log.w("BroadcastReceiver", "Couldn't start the foreground service.");
e.printStackTrace();
}
break;
default:
Log.i("BroadcastReceiver", "Ignoring broadcast event: " + intent.getAction());

View File

@@ -67,8 +67,6 @@ public class BigscreenActivity extends AppCompatActivity {
new PermissionsAlertDialogFragment.Builder()
.setTitle(plugin.getDisplayName())
.setMessage(R.string.bigscreen_optional_permission_explanation)
.setPositiveButton(R.string.ok)
.setNegativeButton(R.string.cancel)
.setPermissions(new String[]{Manifest.permission.RECORD_AUDIO})
.setRequestCode(MainActivity.RESULT_NEEDS_RELOAD)
.create().show(getSupportFragmentManager(), null);

View File

@@ -13,6 +13,7 @@ import android.Manifest;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import org.kde.kdeconnect.Helpers.ContactsHelper;
import org.kde.kdeconnect.Helpers.ContactsHelper.ContactNotFoundException;
@@ -21,6 +22,7 @@ import org.kde.kdeconnect.Helpers.ContactsHelper.uID;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.UserInterface.AlertDialogFragment;
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
@@ -109,6 +111,39 @@ public class ContactsPlugin extends Plugin {
// One day maybe we will also support WRITE_CONTACTS, but not yet
}
@Override
public boolean checkRequiredPermissions() {
if (!arePermissionsGranted(getRequiredPermissions())) {
return false;
}
return preferences.getBoolean("acceptedToTransferContacts", false);
}
@Override
public boolean supportsDeviceSpecificSettings() {
return true;
}
public @NonNull DialogFragment getPermissionExplanationDialog() {
if (!arePermissionsGranted(getRequiredPermissions())) {
return super.getPermissionExplanationDialog();
}
AlertDialogFragment dialog = new AlertDialogFragment.Builder()
.setTitle(getDisplayName())
.setMessage(R.string.contacts_per_device_confirmation)
.setPositiveButton(R.string.ok)
.setNegativeButton(R.string.cancel)
.create();
dialog.setCallback(new AlertDialogFragment.Callback() {
@Override
public void onPositiveButtonClicked() {
preferences.edit().putBoolean("acceptedToTransferContacts", true).apply();
device.reloadPluginsFromSettings();
}
});
return dialog;
}
/**
* Add custom fields to the vcard to keep track of KDE Connect-specific fields
* <p>

View File

@@ -6,6 +6,7 @@
package org.kde.kdeconnect.Plugins.FindMyPhonePlugin;
import android.Manifest;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -120,6 +121,9 @@ public class FindMyPhonePlugin extends Plugin {
intent.putExtra(FindMyPhoneActivity.EXTRA_DEVICE_ID, device.getDeviceId());
context.startActivity(intent);
} else {
if (!checkOptionalPermissions()) {
return false;
}
if (powerManager.isInteractive()) {
startPlaying();
showBroadcastNotification();
@@ -127,7 +131,6 @@ public class FindMyPhonePlugin extends Plugin {
showActivityNotification();
}
}
return true;
}
@@ -219,4 +222,19 @@ public class FindMyPhonePlugin extends Plugin {
public PluginSettingsFragment getSettingsFragment(Activity activity) {
return FindMyPhoneSettingsFragment.newInstance(getPluginKey(), R.xml.findmyphoneplugin_preferences);
}
@NonNull
@Override
protected String[] getRequiredPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return new String[]{Manifest.permission.POST_NOTIFICATIONS};
} else {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
}
@Override
protected int getPermissionExplanation() {
return R.string.findmyphone_notifications_explanation;
}
}

View File

@@ -6,11 +6,13 @@
package org.kde.kdeconnect.Plugins.MprisPlugin;
import android.Manifest;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.os.Build;
@@ -257,6 +259,14 @@ public class MprisMediaSession implements
*/
private void updateMediaNotification() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
int permissionResult = ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
closeMediaNotification();
return;
}
}
//If the user disabled the media notification, do not show it
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if (!prefs.getBoolean(context.getString(R.string.mpris_notification_key), true)) {

View File

@@ -6,15 +6,18 @@
package org.kde.kdeconnect.Plugins.MprisPlugin;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build;
import android.util.Log;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import org.apache.commons.lang3.ArrayUtils;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
@@ -521,4 +524,19 @@ public class MprisPlugin extends Plugin {
}
return false;
}
@NonNull
@Override
protected String[] getOptionalPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return new String[]{Manifest.permission.POST_NOTIFICATIONS};
} else {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
}
@Override
protected int getOptionalPermissionExplanation() {
return R.string.mpris_notifications_explanation;
}
}

View File

@@ -1,80 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019 Nicolas Fella <nicolas.fella@gmx.de>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
package org.kde.kdeconnect.Plugins.PhotoPlugin;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import org.kde.kdeconnect.KdeConnect;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class PhotoActivity extends AppCompatActivity {
private Uri photoURI;
@Override
protected void onStart() {
super.onStart();
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ignored) {
}
// Continue only if the File was successfully created
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(this,
"org.kde.kdeconnect_tp.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, 1);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss").format(LocalDateTime.now());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
return File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String deviceId = getIntent().getStringExtra("deviceId");
PhotoPlugin plugin = KdeConnect.getInstance().getDevicePlugin(deviceId, PhotoPlugin.class);
if (plugin == null) {
finish();
return;
}
if (resultCode == -1) {
plugin.sendPhoto(photoURI);
} else {
plugin.sendCancel();
}
finish();
}
}

View File

@@ -1,73 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019 Nicolas Fella <nicolas.fella@gmx.de>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
package org.kde.kdeconnect.Plugins.PhotoPlugin;
import android.content.Intent;
import android.net.Uri;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import org.kde.kdeconnect.Helpers.FilesHelper;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect_tp.R;
@PluginFactory.LoadablePlugin
public class PhotoPlugin extends Plugin {
private final static String PACKET_TYPE_PHOTO = "kdeconnect.photo";
private final static String PACKET_TYPE_PHOTO_REQUEST = "kdeconnect.photo.request";
@Override
public @NonNull String getDisplayName() {
return context.getResources().getString(R.string.take_picture);
}
@Override
public @NonNull String getDescription() {
return context.getResources().getString(R.string.plugin_photo_desc);
}
@Override
public boolean onPacketReceived(@NonNull NetworkPacket np) {
Intent intent = new Intent(context, PhotoActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("deviceId", device.getDeviceId());
context.startActivity(intent);
return true;
}
void sendPhoto(Uri uri) {
NetworkPacket np = FilesHelper.uriToNetworkPacket(context, uri, PACKET_TYPE_PHOTO);
if (np != null) {
device.sendPacket(np);
}
}
@Override
public @NonNull String[] getSupportedPacketTypes() {
return new String[]{PACKET_TYPE_PHOTO_REQUEST};
}
@Override
public @NonNull String[] getOutgoingPacketTypes() {
return new String[]{PACKET_TYPE_PHOTO};
}
@Override
public @DrawableRes int getIcon() {
return R.drawable.ic_camera;
}
void sendCancel() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_PHOTO);
np.set("cancel", true);
device.sendPacket(np);
}
}

View File

@@ -6,12 +6,18 @@
package org.kde.kdeconnect.Plugins.PingPlugin;
import android.Manifest;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
@@ -66,6 +72,15 @@ public class PingPlugin extends Plugin {
id = 42; //A unique id to create only one notification
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
int permissionResult = ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
// If notifications are not allowed, show a toast instead of a notification
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, message, Toast.LENGTH_LONG).show());
return true;
}
}
NotificationManager notificationManager = ContextCompat.getSystemService(context, NotificationManager.class);
Notification noti = new NotificationCompat.Builder(context, NotificationHelper.Channels.DEFAULT)

View File

@@ -265,7 +265,7 @@ public abstract class Plugin {
return (result == PackageManager.PERMISSION_GRANTED);
}
private boolean arePermissionsGranted(@NonNull String[] permissions) {
protected boolean arePermissionsGranted(@NonNull String[] permissions) {
for (String permission : permissions) {
if (!isPermissionGranted(permission)) {
return false;
@@ -278,8 +278,6 @@ public abstract class Plugin {
return new PermissionsAlertDialogFragment.Builder()
.setTitle(getDisplayName())
.setMessage(reason)
.setPositiveButton(R.string.ok)
.setNegativeButton(R.string.cancel)
.setPermissions(permissions)
.setRequestCode(MainActivity.RESULT_NEEDS_RELOAD)
.create();

View File

@@ -6,18 +6,21 @@
package org.kde.kdeconnect.Plugins.ReceiveNotificationsPlugin;
import android.Manifest;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import org.apache.commons.lang3.ArrayUtils;
import org.kde.kdeconnect.Helpers.NotificationHelper;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
@@ -122,4 +125,19 @@ public class ReceiveNotificationsPlugin extends Plugin {
public @NonNull String[] getOutgoingPacketTypes() {
return new String[]{PACKET_TYPE_NOTIFICATION_REQUEST};
}
@NonNull
@Override
protected String[] getRequiredPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return new String[]{Manifest.permission.POST_NOTIFICATIONS};
} else {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
}
@Override
protected int getPermissionExplanation() {
return R.string.receive_notifications_permission_explanation;
}
}

View File

@@ -22,6 +22,7 @@ import org.kde.kdeconnect.Device
import org.kde.kdeconnect.KdeConnect
import org.kde.kdeconnect_tp.R
import org.kde.kdeconnect_tp.databinding.WidgetRemoteCommandPluginDialogBinding
import java.util.stream.Collectors
import kotlin.streams.toList
class RunCommandWidgetConfigActivity : AppCompatActivity() {
@@ -44,7 +45,7 @@ class RunCommandWidgetConfigActivity : AppCompatActivity() {
val binding = WidgetRemoteCommandPluginDialogBinding.inflate(layoutInflater)
setContentView(binding.root)
val pairedDevices = KdeConnect.getInstance().devices.values.stream().filter(Device::isPaired).toList()
val pairedDevices = KdeConnect.getInstance().devices.values.stream().filter(Device::isPaired).collect(Collectors.toList());
binding.runCommandsDeviceList.adapter = object : ArrayAdapter<Device>(this, 0, pairedDevices) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {

View File

@@ -20,6 +20,7 @@ import androidx.annotation.NonNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.kde.kdeconnect.Helpers.NetworkHelper;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
@@ -147,7 +148,7 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
NetworkPacket np2 = new NetworkPacket(PACKET_TYPE_SFTP);
np2.set("ip", server.getLocalIpAddress()); // for backwards compatibility
np2.set("ip", NetworkHelper.getLocalIpAddress().getHostAddress());
np2.set("port", server.getPort());
np2.set("user", SimpleSftpServer.USER);
np2.set("password", server.getPassword());

View File

@@ -26,17 +26,12 @@ import org.kde.kdeconnect.Helpers.RandomHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
class SimpleSftpServer {
@@ -145,39 +140,6 @@ class SimpleSftpServer {
return port;
}
String getLocalIpAddress() {
String ip6 = null;
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
// Anything with rmnet is related to cellular connections or USB
// tethering mechanisms. See:
//
// https://android.googlesource.com/kernel/msm/+/android-msm-flo-3.4-kitkat-mr1/Documentation/usb/gadget_rmnet.txt
//
// If we run across an interface that has this, we can safely
// ignore it. In fact, it's much safer to do. If we don't, we
// might get invalid IP adddresses out of it.
if (intf.getDisplayName().contains("rmnet")) continue;
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
String address = inetAddress.getHostAddress();
if (inetAddress instanceof Inet4Address) { //Prefer IPv4 over IPv6, because sshfs doesn't seem to like IPv6
return address;
} else {
ip6 = address;
}
}
}
}
} catch (SocketException ignored) {
}
return ip6;
}
public boolean isInitialized() {
return initialized;
}

View File

@@ -241,7 +241,7 @@ public class CompositeReceiveFileJob extends BackgroundJob<Device, Void> {
failedFiles = (totalNumFiles - currentFileNum + 1);
}
receiveNotification.setFinished(getDevice().getContext().getResources().getQuantityString(R.plurals.received_files_fail_title, failedFiles, getDevice().getName(), failedFiles, totalNumFiles));
receiveNotification.setFailed(getDevice().getContext().getResources().getQuantityString(R.plurals.received_files_fail_title, failedFiles, getDevice().getName(), failedFiles, totalNumFiles));
receiveNotification.show();
reportError(e);
} finally {

View File

@@ -127,7 +127,7 @@ public class CompositeUploadFileJob extends BackgroundJob<Device, Void> {
int failedFiles;
synchronized (lock) {
failedFiles = (totalNumFiles - currentFileNum + 1);
uploadNotification.setFinished(getDevice().getContext().getResources()
uploadNotification.setFailed(getDevice().getContext().getResources()
.getQuantityString(R.plurals.send_files_fail_title, failedFiles, getDevice().getName(),
failedFiles, totalNumFiles));
}
@@ -229,7 +229,7 @@ public class CompositeUploadFileJob extends BackgroundJob<Device, Void> {
@Override
public void onFailure(Throwable e) {
//Ignored
// Handled in the run() function when sendPacketBlocking returns false
}
}
}

View File

@@ -46,7 +46,7 @@ class ReceiveNotification {
this.jobId = jobId;
notificationId = (int) System.currentTimeMillis();
notificationManager = ContextCompat.getSystemService(device.getContext(), NotificationManager.class);
builder = new NotificationCompat.Builder(device.getContext(), NotificationHelper.Channels.FILETRANSFER)
builder = new NotificationCompat.Builder(device.getContext(), NotificationHelper.Channels.FILETRANSFER_DOWNLOAD)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setAutoCancel(true)
.setOngoing(true)
@@ -86,7 +86,7 @@ class ReceiveNotification {
}
public void setFinished(String message) {
builder = new NotificationCompat.Builder(device.getContext(), NotificationHelper.Channels.FILETRANSFER);
builder = new NotificationCompat.Builder(device.getContext(), NotificationHelper.Channels.FILETRANSFER_DOWNLOAD);
builder.setContentTitle(message)
.setTicker(message)
.setSmallIcon(android.R.drawable.stat_sys_download_done)
@@ -99,6 +99,13 @@ class ReceiveNotification {
}
}
public void setFailed(String message) {
setFinished(message);
builder.setSmallIcon(android.R.drawable.stat_notify_error)
.setChannelId(NotificationHelper.Channels.FILETRANSFER_ERROR);
}
public void setURI(Uri destinationUri, String mimeType, String filename) {
/*
* We only support file URIs (because sending a content uri to another app does not work for security reasons).

View File

@@ -75,7 +75,11 @@ public class SharePlugin extends Plugin {
@Override
protected int getOptionalPermissionExplanation() {
return R.string.share_optional_permission_explanation;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return R.string.share_notifications_explanation;
} else {
return R.string.share_optional_permission_explanation;
}
}
@Override
@@ -290,7 +294,9 @@ public class SharePlugin extends Plugin {
@Override
public @NonNull String[] getOptionalPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return new String[]{Manifest.permission.POST_NOTIFICATIONS};
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return ArrayUtils.EMPTY_STRING_ARRAY;
} else {
return new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};

View File

@@ -33,7 +33,7 @@ class UploadNotification {
notificationId = (int) System.currentTimeMillis();
notificationManager = ContextCompat.getSystemService(device.getContext(), NotificationManager.class);
builder = new NotificationCompat.Builder(device.getContext(), NotificationHelper.Channels.FILETRANSFER)
builder = new NotificationCompat.Builder(device.getContext(), NotificationHelper.Channels.FILETRANSFER_UPLOAD)
.setSmallIcon(android.R.drawable.stat_sys_upload)
.setAutoCancel(true)
.setOngoing(true)
@@ -64,7 +64,7 @@ class UploadNotification {
}
public void setFinished(String message) {
builder = new NotificationCompat.Builder(device.getContext(), NotificationHelper.Channels.FILETRANSFER);
builder = new NotificationCompat.Builder(device.getContext(), NotificationHelper.Channels.FILETRANSFER_UPLOAD);
builder.setContentTitle(message)
.setTicker(message)
.setSmallIcon(android.R.drawable.stat_sys_upload_done)
@@ -79,7 +79,8 @@ class UploadNotification {
public void setFailed(String message) {
setFinished(message);
builder.setSmallIcon(android.R.drawable.stat_notify_error);
builder.setSmallIcon(android.R.drawable.stat_notify_error)
.setChannelId(NotificationHelper.Channels.FILETRANSFER_ERROR);
}
public void cancel() {

View File

@@ -83,7 +83,7 @@ class EasterEggActivity : AppCompatActivity(), SensorEventListener {
R.drawable.ic_baseline_info_24, R.drawable.ic_baseline_web_24,
R.drawable.ic_baseline_send_24, R.drawable.ic_baseline_sms_24,
R.drawable.ic_accept_pairing_24dp, R.drawable.ic_share_white,
R.drawable.ic_camera, R.drawable.ic_delete,
R.drawable.ic_delete,
R.drawable.ic_device_laptop_32dp, R.drawable.ic_device_phone_32dp,
R.drawable.ic_device_tablet_32dp, R.drawable.ic_device_tv_32dp,
R.drawable.ic_delete, R.drawable.ic_warning,
@@ -164,4 +164,4 @@ class EasterEggActivity : AppCompatActivity(), SensorEventListener {
animator.start()
}
}
}
}

View File

@@ -30,6 +30,8 @@ public class SectionItem implements ListAdapter.Item {
//Make it not selectable
binding.getRoot().setOnClickListener(null);
binding.getRoot().setOnLongClickListener(null);
binding.getRoot().setFocusable(false);
binding.getRoot().setClickable(false);
binding.listItemCategoryText.setText(title);

View File

@@ -22,6 +22,8 @@ import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
@@ -192,6 +194,15 @@ class MainActivity : AppCompatActivity(), OnSharedPreferenceChangeListener {
else -> setContentFragment(PairingFragment())
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val permissionResult = ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.POST_NOTIFICATIONS)) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), RESULT_NOTIFICATIONS_ENABLED)
}
}
}
}
override fun onDestroy() {
@@ -318,37 +329,45 @@ class MainActivity : AppCompatActivity(), OnSharedPreferenceChangeListener {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when {
requestCode == RESULT_NEEDS_RELOAD -> {
KdeConnect.getInstance().getDevice(mCurrentDevice)?.reloadPluginsFromSettings()
KdeConnect.getInstance().devices.values.forEach(Device::reloadPluginsFromSettings)
}
requestCode == STORAGE_LOCATION_CONFIGURED && resultCode == RESULT_OK && data != null -> {
val uri = data.data
ShareSettingsFragment.saveStorageLocationPreference(this, uri)
}
else -> super.onActivityResult(requestCode, resultCode, data)
}
}
fun isPermissionGranted(permissions: Array<String>, grantResults: IntArray, permission : String) : Boolean {
val index = ArrayUtils.indexOf(permissions, permission)
return index != ArrayUtils.INDEX_NOT_FOUND && grantResults[index] == PackageManager.PERMISSION_GRANTED
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
val permissionsGranted = ArrayUtils.contains(grantResults, PackageManager.PERMISSION_GRANTED)
if (permissionsGranted) {
val i = ArrayUtils.indexOf(permissions, Manifest.permission.WRITE_EXTERNAL_STORAGE)
val writeStoragePermissionGranted = i != ArrayUtils.INDEX_NOT_FOUND &&
grantResults[i] == PackageManager.PERMISSION_GRANTED
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && writeStoragePermissionGranted) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && isPermissionGranted(permissions, grantResults, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// To get a writeable path manually on Android 10 and later for Share and Receive Plugin.
// Otherwise, Receiving files will keep failing until the user chooses a path manually to receive files.
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
startActivityForResult(intent, STORAGE_LOCATION_CONFIGURED)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && isPermissionGranted(permissions, grantResults, Manifest.permission.POST_NOTIFICATIONS)) {
// If PairingFragment is active, reload it
if (mCurrentDevice == null) {
setContentFragment(PairingFragment())
}
}
//New permission granted, reload plugins
KdeConnect.getInstance().getDevice(mCurrentDevice)?.reloadPluginsFromSettings()
KdeConnect.getInstance().devices.values.forEach(Device::reloadPluginsFromSettings)
}
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) {
if (DeviceHelper.KEY_DEVICE_NAME_PREFERENCE == key) {
mNavViewDeviceName.text = DeviceHelper.getDeviceName(this)
BackgroundService.ForceRefreshConnections(this) //Re-send our identity packet
@@ -370,6 +389,7 @@ class MainActivity : AppCompatActivity(), OnSharedPreferenceChangeListener {
const val PAIRING_REJECTED = "rejected"
const val PAIRING_PENDING = "pending"
const val RESULT_NEEDS_RELOAD = RESULT_FIRST_USER
const val RESULT_NOTIFICATIONS_ENABLED = RESULT_FIRST_USER+1
const val FLAG_FORCE_OVERVIEW = "forceOverview"
}

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