2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-09-01 14:45:08 +00:00

Compare commits

...

56 Commits

Author SHA1 Message Date
Albert Vaca Cintora
b64b27bcae Release 1.24.0 2023-04-05 19:04:41 +02:00
Albert Vaca Cintora
98ffff5844 Revert "Switch desugaring lib to desugar_jdk_libs_nio"
This reverts commit 7efb1f81b5.

For some weird reason, mina-sshd works fine without desugaring NIO on
Android 5 but fails with `java.lang.NoClassDefFoundError: Failed resolution
of: Ljava/nio/channels/AsynchronousChannelGroup;` before reverting this
2023-04-05 18:56:01 +02:00
Albert Vaca Cintora
711065a8e6 Refactor share function to handle null URIs
BUG: 458278
2023-04-05 10:16:23 +00:00
Albert Vaca Cintora
5250fde0b1 Remove copyright and app description from About 2023-04-04 22:49:05 +00:00
Albert Vaca Cintora
f9ea5f0e77 Send preexisting notifications as silent
This avoids creating a popup for every existing notification after the
device connects.
2023-04-04 22:44:44 +00:00
Albert Vaca Cintora
a26e5fbb9c Add note so people add themselves to the author list 2023-04-05 00:38:02 +02:00
Isira Seneviratne
7efb1f81b5 Switch desugaring lib to desugar_jdk_libs_nio
Enables desugaring of the `Files` class, which is otherwise only available on API 26+.
2023-04-04 22:27:56 +00:00
Isira Seneviratne
d4378ffe3e Remove multidex library. 2023-04-04 22:21:00 +00:00
l10n daemon script
76f5005219 GIT_SILENT made messages (after extraction) 2023-04-04 00:46:47 +00:00
l10n daemon script
53638577f9 GIT_SILENT made messages (after extraction) 2023-04-03 00:45:41 +00:00
l10n daemon script
e5f221f891 GIT_SILENT made messages (after extraction) 2023-04-02 00:47:00 +00:00
Dmitry Yudin
ef902348bb More Material3 styling
Apply Material3 to dialogs, image buttons, switches and preferences.
Merge the landscape and portrait layouts for the MPRIS controls.
Move setting theme to application start instead of applying to every activity.
2023-04-01 21:33:03 +00:00
Albert Vaca Cintora
a1d7e822e7 Don't show any message if battery information is not available
BUG: 447498
2023-04-01 19:18:38 +00:00
Albert Vaca Cintora
4b775cff88 Prettier RunCommand widget & add preview
Co-authored-by: Maxim Leshchenko <cnmaks90@gmail.com>
2023-04-01 21:14:14 +02:00
l10n daemon script
3d2667a803 GIT_SILENT made messages (after extraction) 2023-04-01 00:50:50 +00:00
Albert Vaca Cintora
5dd9b48f74 Remove redundant check for permissions 2023-03-31 21:08:59 +02:00
l10n daemon script
1d794dae6a GIT_SILENT made messages (after extraction) 2023-03-31 00:46:49 +00:00
Dmitry Yudin
0ed11d2036 Show enabled plugins as cards 2023-03-29 18:22:27 +00:00
Albert Vaca Cintora
aef5af30ed Also in FindMyPhone activity 2023-03-29 20:07:58 +02:00
Albert Vaca Cintora
85d5b9e08f Use AppCompatButton to avoid the round borders of M3 buttons
Which are quite ugly when the buttons are very big.
2023-03-29 20:04:41 +02:00
Albert Vaca Cintora
a0e963c893 Revert "Use AppCompatButton to avoid the round borders of M3 buttons"
This reverts commit ca71ddef34.
2023-03-29 20:04:05 +02:00
Albert Vaca Cintora
ca71ddef34 Use AppCompatButton to avoid the round borders of M3 buttons
Which are quite ugly when the buttons are very big.
2023-03-29 19:43:15 +02:00
Manuel Jesús de la Fuente
6defead2ce Use M3 theme, switch to Material Dialogs
- Add Monet dynamic colors on the app's `onCreate()`
- Set parent in styles.xml to `Theme.Material3.DayNight.NoActionBar`
- Use `MaterialAlertDialogBuilder`
- In the About and About KDE fragments, it uses the M3 elevated style instead of outlines
- In `edit_text_alert_dialog_view.xml`, it uses the default theme style instead of specifying the one from MaterialComponents
- Added a todo in the settings fragment: Preference dialogs don't yet use the M3 style.

It complements https://invent.kde.org/network/kdeconnect-android/-/merge_requests/273, though the way that merge request accomplishes color theming is the one from before the onCreate dynamics color method
2023-03-29 17:39:25 +00:00
Albert Vaca Cintora
fd3c6f07da Changes from code review
Fix potential race condition and lower log level
2023-03-29 17:09:21 +00:00
Albert Vaca Cintora
aff2de8ebb Fix UUID containing characters that can't be dbus-exported
This broke pairing with the desktop app
2023-03-29 17:09:21 +00:00
Albert Vaca Cintora
cbc0749997 Do not use the ANDROID_ID as device ID
Since Android 8, this ID is stable across reinstalls of the app. This
causes other devices that already were paired with us to find a cert
mismatch and refuse to communicate with us after a reinstall or data wipe.
2023-03-29 17:09:21 +00:00
Albert Vaca Cintora
554769e1ef Fix plugins without permissions showing a generic explanation
This was because we only overrote the explanation in onCreate, which wasn't
called for plugins without permissions.
2023-03-29 19:01:57 +02:00
Albert Vaca Cintora
63718d5a58 Flip isIncompatible -> isCompatible 2023-03-29 18:51:32 +02:00
Albert Vaca Cintora
7670810155 Code review fixes 2023-03-29 16:32:40 +00:00
Albert Vaca Cintora
66a649313c Consolidate network listeners in BackgroundService
* Remove usage of deprecated WiFi ConnectivityManager
* Only listen for non-cellular network changes (where we can find devices)
* Do not listen for network changes also from PairingFragment
2023-03-29 16:32:40 +00:00
l10n daemon script
855ad36642 GIT_SILENT Sync po/docbooks with svn 2023-03-29 01:55:19 +00:00
l10n daemon script
0d1e358067 GIT_SILENT made messages (after extraction) 2023-03-29 00:47:12 +00:00
l10n daemon script
9b662776e8 GIT_SILENT Sync po/docbooks with svn 2023-03-28 02:17:52 +00:00
Mhammad Alloush
e60c134d78 MousePadPlugin: Add gyro mouse
## Summary

This MR adds gyro mouse capability, which allows you to move the cursor of a connected device by simply moving the connected phone. It uses standard Android gyroscope sensors. Mainly aimed at usage with computers attached to very large screens (e.g. TV's), as using the touchpad as-is can feel somewhat unnatural.

While it does attempt pretty much the same thing as !285, this MR attempts to reduce redundancy as much as possible by simply extending the existing MousePadPlugin instead.

Tested on a Xiaomi Redmi Note 11, on a Samsung A71, and on a laptop running Arch Linux and KDE Plasma 5.27.3

## Test Plan

1. Make sure the 'Remote Input' plugin is enabled on the Android device.
2. Make sure the 'Virtual Input' plugin is enabled on the target device.
3. Open Plugin Settings -> Remote Input for the target device.
2. Enable the toggle for Gyro mouse.
3. Exit settings and go to the Remote Input activity for the target device.
4. Try moving the device around in 3D space.
5. Confirm that the mouse pointer moves predictably.
2023-03-27 20:58:48 +00:00
l10n daemon script
092b207aec GIT_SILENT Sync po/docbooks with svn 2023-03-27 02:40:27 +00:00
l10n daemon script
425011fadc GIT_SILENT made messages (after extraction) 2023-03-27 00:49:00 +00:00
l10n daemon script
738f60d671 GIT_SILENT made messages (after extraction) 2023-03-26 00:47:53 +00:00
Albert Vaca Cintora
118e045990 Replace Handlers by lightweight callbacks 2023-03-25 23:46:41 +00:00
Mihir Patel
b8cbd2b382 Adding support for per-app language preferences on Android 13 and later
Android 13 added the ability to select languages on a per-app basis. Supporting this feature simply requires us to provide a listing of all of the locales supported by the app: https://developer.android.com/guide/topics/resources/app-languages

This change adds a locales_config.xml file to list the locales and references this file in the application manifest
2023-03-25 19:25:39 +00:00
l10n daemon script
eb301341a5 GIT_SILENT made messages (after extraction) 2023-03-23 00:46:51 +00:00
Albert Vaca Cintora
58cbd49278 Use ConcurrentHashMap to fix ConcurrentModificationException 2023-03-22 20:12:27 +01:00
Albert Vaca Cintora
7bf2a40180 Rename updateComputerList -> updateDeviceList 2023-03-22 18:17:31 +01:00
l10n daemon script
e2a35fb97f GIT_SILENT made messages (after extraction) 2023-03-22 00:47:34 +00:00
l10n daemon script
a524fb8486 GIT_SILENT made messages (after extraction) 2023-03-21 00:47:36 +00:00
Nicolas Fella
d54f155b24 Add CI for debug PR builds
Add a debug and test CI. As the test coverage today is not much to get excited about, this is mostly a check that the app still builds, as well as a convenient way to download the prebuilt app for testing.
2023-03-21 00:00:03 +00:00
l10n daemon script
252e38cc07 GIT_SILENT made messages (after extraction) 2023-03-20 00:49:43 +00:00
Albert Vaca Cintora
25be43d88d Remove outdated comment 2023-03-20 00:06:16 +01:00
Albert Vaca Cintora
0933f6bb5f Bump Apache CommonsIO version
And the desugaring library as well. ThreadLocal.withInitial can now be
desugared, so we can use newer versions of CommonsIO.
2023-03-20 00:04:56 +01:00
Albert Vaca Cintora
33e8e0407b Upgrade from SpongyCastle 1.58 to BouncyCastle 1.70
SpongyCastle was a fork of BouncyCastle needed before Android 3.0 because
of a conflict with Android's own version of BC. It's no longer needed and
rarely receives updates anymore [1]. Furthermore the version we were using
was from 2015 and had security issues (although I'm not sure we were
affected by them since we only use it to generate certificates).

With this change we now also use Java's standard library to read the certs
from a byte[] since the standard CertificateFactory can already do that.


[1] https://github.com/rtyley/spongycastle/issues/34
2023-03-19 23:00:25 +00:00
Albert Vaca Cintora
51dfa2dd8c Delay initialization of sftp server 2023-03-19 20:26:09 +00:00
Albert Vaca Cintora
1ba9e59872 SftpPlugin: use MANAGE_EXTERNAL_STORAGE instead of SAF in Android 11+
https://developer.android.com/training/data-storage/manage-all-files

BUG: 447636
BUG: 464431
2023-03-19 20:26:09 +00:00
Albert Vaca Cintora
76c3cc4c57 Prevent spam of "Invalid packet" when using remote mouse 2023-03-19 11:57:35 +01:00
l10n daemon script
79275c51cf GIT_SILENT made messages (after extraction) 2023-03-19 00:47:28 +00:00
Albert Vaca Cintora
83b0c04d51 Release 1.23.2 2023-03-18 21:54:30 +01:00
Albert Vaca Cintora
3aba448bea Rollback android-device-names to 1.x
Was bumped in f2f1930cec but it was crashing
with "database disk image is malformed" and not returning a human name
2023-03-18 20:40:51 +01:00
l10n daemon script
5633183d57 GIT_SILENT made messages (after extraction) 2023-03-18 00:58:31 +00:00
129 changed files with 1541 additions and 1102 deletions

66
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,66 @@
# SPDX-FileCopyrightText: 2023 Nicolas Fella <nicolas.fella@gmx.de>
# SPDX-FileCopyrightText: 2023 Simon Redman <simon@ergotech.com>
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#
# Test this pipeline locally by:
# - Set up Docker on your machine, if not already set up
# - Set up gitlab-runner, as described here: https://stackoverflow.com/a/52724374
# - Run `gitlab-runner exec docker --docker-privileged assembleDebug`
image: openjdk:11-jdk
variables:
ANDROID_COMPILE_SDK: "31"
ANDROID_BUILD_TOOLS: "30.0.3"
ANDROID_SDK_TOOLS: "6609375"
before_script:
- apt-get --quiet update --yes
- apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1
- wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip
- unzip -d cmdline-tools android-sdk.zip
- echo y | cmdline-tools/tools/bin/sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" >/dev/null
- echo y | cmdline-tools/tools/bin/sdkmanager "platform-tools" >/dev/null
- echo y | cmdline-tools/tools/bin/sdkmanager "patcher;v4" >/dev/null
- echo y | cmdline-tools/tools/bin/sdkmanager "emulator" >/dev/null
- echo y | cmdline-tools/tools/bin/sdkmanager "platform-tools" >/dev/null
- echo y | cmdline-tools/tools/bin/sdkmanager "tools" >/dev/null
- echo y | cmdline-tools/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" >/dev/null
- export ANDROID_HOME=$PWD/cmdline-tools
- export PATH=$PATH:$PWD/cmdline-tools/platform-tools/
- chmod +x ./gradlew
# temporarily disable checking for EPIPE error and use yes to accept all licenses
- set +o pipefail
- yes | cmdline-tools/tools/bin/sdkmanager --licenses
# Gradle will automatically download parts of the SDK if they are missing,
# assuming the licenses are accepted. Even if you don't need it to download
# anything, it will fail if it detects the liceses are not accepted.
# https://developer.android.com/studio/intro/update.html#download-with-gradle
# Unfortunately, it looks for the license acceptances in a different location than
# the sdkmanager creates them!
# Copy them to the location Gradle expects to find them to make everything run smoothly.
- cp -ap "${PWD}/licenses" "${PWD}/cmdline-tools/licenses"
- set -o pipefail
stages:
- build
- test
lintDebug:
stage: build
script:
- ./gradlew generateLicenseReport
- ./gradlew -Pci --console=plain lintDebug -PbuildDir=lint
assembleDebug:
stage: build
script:
- ./gradlew assembleDebug
artifacts:
paths:
- build/outputs/
debugTests:
stage: test
script:
- ./gradlew -Pci --console=plain testDebug

View File

@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.kde.kdeconnect_tp"
android:versionCode="12301"
android:versionName="1.23.1">
android:versionCode="12400"
android:versionName="1.24.0">
<supports-screens
android:anyDensity="true"
@@ -47,6 +47,7 @@
<uses-permission android:name="android.permission.READ_LOGS" tools:ignore="ProtectedPermissions" />
<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" />
<application
android:icon="@mipmap/ic_launcher"
@@ -56,6 +57,7 @@
android:allowBackup="false"
android:dataExtractionRules="@xml/data_extraction_rules"
android:networkSecurityConfig="@xml/network_security_config"
android:localeConfig="@xml/locales_config"
android:theme="@style/KdeConnectTheme.NoActionBar"
android:name="org.kde.kdeconnect.MyApplication">

View File

@@ -22,6 +22,30 @@ function import_po_files # First parameter will be a path that will contain seve
# https://github.com/python-babel/babel/issues/566
find "$podir" -name '*.po' -exec msgattrib --no-obsolete -o {} {} \;
ANSI_COLORS_DISABLED=1 a2po import --ignore-fuzzy --android res/ --gettext $podir
# Generate the locales_config.xml
pushd res
echo '<?xml version="1.0" encoding="utf-8"?>' > xml/locales_config.xml
echo '<locale-config xmlns:android="http://schemas.android.com/apk/res/android">' >> xml/locales_config.xml
transform_locale_regex='(\w+)-r(\w+)'
# Add en-US as the first locale so that is the fallback, and also because it won't be handled in the following loop
echo -e '\t<locale android:name="en-US"/>' >> xml/locales_config.xml
for i in values-*; do
if [ -d "${i}" ]; then
if [ -e "${i}/strings.xml" ]; then
locale="${i:7}"
if [[ "${locale}" =~ $transform_locale_regex ]]; then
# Special case to turn locales like "en-rUS", "en-rGB" into "en-US" and "en-GB"
transformed_locale="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}"
echo -e "\t<locale android:name=\"${transformed_locale}\"/>" >> xml/locales_config.xml
else
echo -e "\t<locale android:name=\"${locale}\"/>" >> xml/locales_config.xml
fi
fi
fi
done
echo "</locale-config>" >> xml/locales_config.xml
popd
}

View File

@@ -136,8 +136,7 @@ ext {
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8'
implementation 'androidx.multidex:multidex:2.0.1'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2'
implementation 'androidx.media:media:1.6.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
@@ -153,13 +152,13 @@ dependencies {
implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'com.google.android.material:material:1.8.0'
implementation 'com.jakewharton:disklrucache:2.0.2' //For caching album art bitmaps
implementation 'com.jaredrummler:android-device-names:2.1.1' //To get a human-friendly device name
implementation 'com.jaredrummler:android-device-names:1.1.9' //To get a human-friendly device name
implementation 'org.apache.sshd:sshd-core:0.14.0'
implementation 'org.apache.mina:mina-core:2.0.19' //For some reason, makes sshd-core:0.14.0 work without NIO, which isn't available until Android 8 (api 26)
//implementation('com.github.bright:slf4android:0.1.6') { transitive = true } // For org.apache.sshd debugging
implementation 'com.madgag.spongycastle:bcpkix-jdk15on:1.58.0.0' //For SSL certificate generation
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70' //For SSL certificate generation
implementation 'org.atteo.classindex:classindex:3.13'
annotationProcessor 'org.atteo.classindex:classindex:3.13'
@@ -172,7 +171,7 @@ dependencies {
implementation 'org.kde.invent.sredman:android-smsmms:kdeconnect-1-21-0'
implementation 'com.klinkerapps:logger:1.0.3'
implementation 'commons-io:commons-io:2.8.0' // newer versions don't work on Android 7: https://stackoverflow.com/questions/73604534/no-static-method-threadlocal-withinitial-commons-io-dependency
implementation 'commons-io:commons-io:2.11.0'
implementation 'org.apache.commons:commons-collections4:4.4'
implementation 'org.apache.commons:commons-lang3:3.12.0'

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: kdeorg\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2019-06-30 11:38+0200\n"
"PO-Revision-Date: 2023-03-11 04:52\n"
"PO-Revision-Date: 2023-03-27 11:59\n"
"Last-Translator: Albert Vaca Cintora <albertvaka@gmail.com>\n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingHorizontal="@dimen/activity_horizontal_margin"
android:paddingVertical="@dimen/activity_vertical_margin">
<ImageView
android:id="@+id/album_art"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="25dp"
android:layout_weight="1"
android:contentDescription="@string/mpris_coverart_description"
android:scaleType="fitCenter" />
<include
android:id="@+id/mpris_control"
layout="@layout/mpris_control"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>

View File

@@ -42,9 +42,7 @@
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
card_view:cardBackgroundColor="@color/card_stroke_color"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">
<TextView
@@ -65,9 +63,7 @@
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
card_view:cardBackgroundColor="@color/card_stroke_color"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">
<TextView
@@ -88,9 +84,7 @@
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
card_view:cardBackgroundColor="@color/card_stroke_color"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">
<TextView
@@ -111,9 +105,7 @@
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
card_view:cardBackgroundColor="@color/card_stroke_color"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">
<TextView

View File

@@ -16,74 +16,74 @@
grid:useDefaultMargins="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/home_button"
grid:layout_column="0"
grid:layout_row="0"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
android:contentDescription="@string/bigscreen_home"
android:src="@drawable/ic_home_black_24dp"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_home_black_24dp"
style="@style/KdeConnectButton.IconButton" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/up_button"
grid:layout_column="1"
grid:layout_row="0"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
android:contentDescription="@string/bigscreen_up"
android:src="@drawable/ic_arrow_upward_black_24dp"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_arrow_upward_black_24dp"
style="@style/KdeConnectButton.IconButton" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/mic_button"
grid:layout_column="2"
grid:layout_columnWeight="1"
grid:layout_row="0"
grid:layout_rowWeight="1"
android:contentDescription="@string/bigscreen_mic"
android:src="@drawable/ic_mic_black"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_mic_black"
style="@style/KdeConnectButton.IconButton" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/left_button"
grid:layout_column="0"
grid:layout_row="1"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
android:contentDescription="@string/bigscreen_left"
android:src="@drawable/ic_arrow_back_black_24dp"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_arrow_back_black_24dp"
style="@style/KdeConnectButton.IconButton" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/select_button"
grid:layout_column="1"
grid:layout_row="1"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
android:contentDescription="@string/bigscreen_select"
android:src="@drawable/ic_keyboard_return_black_24dp"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_keyboard_return_black_24dp"
style="@style/KdeConnectButton.IconButton" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/right_button"
grid:layout_column="2"
grid:layout_row="1"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
android:contentDescription="@string/bigscreen_right"
android:src="@drawable/ic_arrow_forward_black_24dp"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_arrow_forward_black_24dp"
style="@style/KdeConnectButton.IconButton" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/down_button"
grid:layout_column="1"
grid:layout_row="2"
grid:layout_columnWeight="1"
grid:layout_rowWeight="1"
android:contentDescription="@string/bigscreen_down"
android:src="@drawable/ic_arrow_downward_black_24dp"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_arrow_downward_black_24dp"
style="@style/KdeConnectButton.IconButton" />
</androidx.gridlayout.widget.GridLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:orientation="@integer/activity_device_orientation"
tools:context="org.kde.kdeconnect.UserInterface.DeviceFragment">
<!-- Layout shown when device is reachable but not yet paired -->
@@ -18,51 +18,27 @@
layout="@layout/view_pair_error"
tools:visibility="gone"/>
<!-- Layout shown when device is paired and reachable -->
<!-- Layouts shown when device is paired and reachable -->
<GridView
android:id="@+id/plugins_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="@integer/plugins_list_weight"
android:numColumns="@integer/plugins_columns"
android:horizontalSpacing="8dp"
android:verticalSpacing="8dp"
android:layout_margin="@dimen/activity_vertical_margin"
tools:listitem="@layout/list_plugin_entry"
tools:layout_height="300dp" />
<ListView
android:id="@+id/buttons_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:fillViewport="true"
android:layout_height="wrap_content"
android:layout_weight="@integer/buttons_list_weight"
android:divider="@null"
android:dividerHeight="0dp"
tools:context=".DeviceActivity"
tools:listitem="@layout/list_item_with_icon_entry"
android:layout_weight=".8"
android:divider="@null"
android:dividerHeight="0dp" />
<!-- Extra information about the current device -->
<RelativeLayout
android:id="@+id/view_status_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp"
android:padding="8dp"
android:visibility="gone"
tools:visibility="visible"
tools:ignore="UnusedAttribute">
<TextView
android:id="@+id/view_status_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:padding="4dp"
android:text="@string/view_status_title"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
/>
<CheckedTextView
android:id="@+id/view_battery_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/view_status_title"
android:checkMark="@null"
android:clickable="false"
android:padding="4dp"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:text="@string/battery_status_unknown"
tools:text="100%"
/>
</RelativeLayout>
</LinearLayout>
tools:layout_height="300dp" />
</LinearLayout>

View File

@@ -19,7 +19,7 @@
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/bFindMyPhone"
android:layout_width="fill_parent"
android:layout_height="fill_parent"

View File

@@ -16,7 +16,7 @@
tools:context="org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationFilterActivity"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.switchmaterial.SwitchMaterial
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/smScreenOffNotification"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -35,30 +35,30 @@
android:orientation="horizontal"
android:layout_weight="1">
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/previous_button"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:contentDescription="@string/mpris_rew"
android:layout_weight="0.25"
android:layout_marginEnd="3dp"
android:src="@drawable/ic_previous_black"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_previous_black"
style="@style/KdeConnectButton.IconButton" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/next_button"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_marginStart="3dp"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_ff"
android:src="@drawable/ic_next_black"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_next_black"
style="@style/KdeConnectButton.IconButton" />
</LinearLayout>
<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/pointer_button"
android:layout_width="match_parent"
android:layout_marginBottom="6dp"
@@ -66,7 +66,8 @@
android:layout_weight="0.30"
android:visibility="gone"
android:text="@string/presenter_pointer"
android:theme="@style/DisableableButton" />
style="@style/KdeConnectButton.IconButton.Secondary"
tools:visibility="visible" />
</LinearLayout>

View File

@@ -30,8 +30,7 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_action_image_edit_24dp"
app:backgroundTint="@color/primary"
app:srcCompat="@drawable/ic_action_image_edit_24dp"
app:layout_anchor="@id/run_commands_list"
app:layout_anchorGravity="bottom|end" />

View File

@@ -3,7 +3,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/refresh_list_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin">
<ListView
android:id="@+id/devices_list"
@@ -11,8 +12,9 @@
android:layout_height="match_parent"
android:addStatesFromChildren="true"
android:divider="@null"
android:dividerHeight="0dp"
android:dividerHeight="12dp"
android:orientation="vertical"
tools:listitem="@layout/list_plugin_entry"
tools:context=".MainActivity" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@@ -15,8 +15,7 @@
android:id="@+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintEnabled="false"
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox">
app:hintEnabled="false">
<!-- inputType="text" is needed, without it lines and maxLines is ignored https://issuetracker.google.com/issues/37118772 -->
<com.google.android.material.textfield.TextInputEditText
@@ -25,8 +24,7 @@
android:layout_height="wrap_content"
android:lines="1"
android:maxLines="1"
android:inputType="text"
style="@style/Widget.MaterialComponents.TextInputEditText.FilledBox"/>
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>
</FrameLayout>

View File

@@ -19,9 +19,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
card_view:cardBackgroundColor="@color/card_stroke_color"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">
<LinearLayout
@@ -66,13 +63,6 @@
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/app_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:layout_margin="12dp"
tools:text="Application Description" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
@@ -151,9 +141,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
card_view:cardBackgroundColor="@color/card_stroke_color"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="5dp"
style="@style/Widget.Material3.CardView.Elevated"
card_view:cardUseCompatPadding="true">
<LinearLayout

View File

@@ -20,7 +20,7 @@
android:fadingEdge="horizontal"
android:singleLine="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/list_item_entry_summary"

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/KdeConnectCardStyle.Filled"
app:contentPadding="12dp"
tools:layout_width="240dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:gravity="center_vertical"
android:layout_marginTop="8dp"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/list_item_entry_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:contentDescription="@string/device_icon_description"
android:src="@drawable/ic_device_laptop_32dp"
android:layout_marginBottom="12dp"
app:tint="?attr/colorOnSurface" />
<TextView
android:id="@+id/list_item_entry_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:lines="2"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?attr/colorOnSurface"
tools:maxLength="30"
tools:text="@tools:sample/lorem/random" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@@ -42,7 +42,7 @@
android:layout_gravity="center"
android:orientation="horizontal">
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/loop_button"
android:layout_width="0dp"
android:layout_height="match_parent"
@@ -51,13 +51,13 @@
android:baselineAlignBottom="true"
android:clickable="false"
android:contentDescription="@string/mpris_loop"
android:src="@drawable/ic_loop_none_black"
android:theme="@style/DisableableButton"
app:icon="@drawable/ic_loop_none_black"
style="@style/KdeConnectButton.IconButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.20" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/play_button"
android:layout_width="0dp"
android:layout_height="match_parent"
@@ -66,13 +66,13 @@
android:baselineAlignBottom="true"
android:clickable="false"
android:contentDescription="@string/mpris_play"
android:src="@drawable/ic_play_black"
android:theme="@style/DisableableButton"
app:icon="@drawable/ic_play_black"
style="@style/KdeConnectButton.IconButton"
app:layout_constraintEnd_toStartOf="@id/shuffle_button"
app:layout_constraintStart_toEndOf="@id/loop_button"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/shuffle_button"
android:layout_width="0dp"
android:layout_height="match_parent"
@@ -81,8 +81,8 @@
android:baselineAlignBottom="true"
android:clickable="false"
android:contentDescription="@string/mpris_shuffle"
android:src="@drawable/ic_shuffle_off_black"
android:theme="@style/DisableableButton"
app:icon="@drawable/ic_shuffle_off_black"
style="@style/KdeConnectButton.IconButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintWidth_percent="0.20" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -93,51 +93,51 @@
android:layout_gravity="center"
android:orientation="horizontal">
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/prev_button"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_previous"
android:src="@drawable/ic_previous_black"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_previous_black"
style="@style/KdeConnectButton.IconButton.Secondary" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/rew_button"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_rew"
android:src="@drawable/ic_rewind_black"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_rewind_black"
style="@style/KdeConnectButton.IconButton.Secondary" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/stop_button"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_stop"
android:src="@drawable/ic_stop"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_stop"
style="@style/KdeConnectButton.IconButton.Secondary" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/ff_button"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_ff"
android:src="@drawable/ic_fast_forward_black"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_fast_forward_black"
style="@style/KdeConnectButton.IconButton.Secondary" />
<ImageButton
<com.google.android.material.button.MaterialButton
android:id="@+id/next_button"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_next"
android:src="@drawable/ic_next_black"
android:theme="@style/DisableableButton" />
app:icon="@drawable/ic_next_black"
style="@style/KdeConnectButton.IconButton.Secondary" />
</LinearLayout>
<LinearLayout

View File

@@ -2,23 +2,24 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:orientation="@integer/mpris_now_playing_orientation"
android:paddingHorizontal="@dimen/activity_horizontal_margin"
android:paddingVertical="@dimen/activity_vertical_margin">
<ImageView
android:id="@+id/album_art"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="25dp"
android:layout_weight="4"
android:layout_width="@dimen/mpris_now_playing_album_width"
android:layout_height="@dimen/mpris_now_playing_album_height"
android:layout_margin="25dp"
android:layout_weight="@integer/mpris_now_playing_album_weight"
android:contentDescription="@string/mpris_coverart_description"
android:scaleType="fitCenter" />
<include
android:id="@+id/mpris_control"
layout="@layout/mpris_control"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_width="@dimen/mpris_now_playing_controls_width"
android:layout_height="@dimen/mpris_now_playing_controls_height"
android:layout_weight="@integer/mpris_now_playing_controls_weight" />
</LinearLayout>

View File

@@ -0,0 +1,10 @@
<com.google.android.material.materialswitch.MaterialSwitch
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/switch_widget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:clickable="false"
android:background="@null"
tools:targetApi="n" />

View File

@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:orientation="vertical"
android:background="@color/on_secondary"
android:theme="@style/KdeConnectTheme"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:id="@+id/runcommandWidgetTitleHeader"
android:background="@color/primary"
@@ -17,7 +18,7 @@
android:paddingBottom="6dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"
android:src="@drawable/ic_kde_48dp"
android:contentDescription="@string/device_icon_description"/>
<TextView
@@ -27,14 +28,13 @@
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge" />
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<ListView
android:id="@+id/run_commands_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:addStatesFromChildren="true"
android:visibility="gone"
android:orientation="vertical" />
@@ -46,7 +46,7 @@
android:drawablePadding="8dip"
android:gravity="center_vertical"
android:paddingStart="8dip"
android:text="@string/unreachable_description"
android:text="@string/runcommand_notreachable"
android:textAppearance="?android:attr/textAppearanceMedium"
app:drawableStartCompat="@drawable/ic_error_outline_48dp"/>
android:drawableStart="@drawable/ic_error_outline_48dp"/>
</LinearLayout>

View File

@@ -79,7 +79,6 @@
<string name="unknown_device">جهاز مجهول</string>
<string name="error_not_reachable">الجهاز غير قابل الوصول</string>
<string name="error_already_paired">الجهاز مقترن بالفعل</string>
<string name="error_could_not_send_package">تعذّر إرسال الحزمة</string>
<string name="error_timed_out">انتهت المهلة</string>
<string name="error_canceled_by_user">ألغاه المستخدم</string>
<string name="error_canceled_by_other_peer">ألغاه ندّ آخر</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Batareya: %d%%</string>
<string name="battery_status_low_format">Batareya: %d%% Zəif batareya</string>
<string name="battery_status_charging_format">Batareya: %d%% doldurulur</string>
<string name="battery_status_unknown">Batareya haqqında məlumat əlçatan deyil</string>
<string name="category_connected_devices">Qoşulmuş cihazlar</string>
<string name="category_not_paired_devices">Mövcud cihazlar</string>
<string name="category_remembered_devices">Yadda saxlanılan cihazlar</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Naməlum Cihaz</string>
<string name="error_not_reachable">Cihaz əlçatmazdır</string>
<string name="error_already_paired">Cihaz artıq qoşulub</string>
<string name="error_could_not_send_package">Paket göndərilə bilmədi</string>
<string name="error_timed_out">Vaxt bitdi</string>
<string name="error_canceled_by_user">İstifadəçi ləğv etdi</string>
<string name="error_canceled_by_other_peer">Digər istifadəçi ləğv etdi</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Батерия: %d%%</string>
<string name="battery_status_low_format">Батерия: %d%% Ниско ниво на батерията</string>
<string name="battery_status_charging_format">Батерия: %d%% зареждане</string>
<string name="battery_status_unknown">Информацията за батерията не е налична</string>
<string name="category_connected_devices">Свързани устройства</string>
<string name="category_not_paired_devices">Налични устройства</string>
<string name="category_remembered_devices">Запомнени устройства</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Неизвестно устройство</string>
<string name="error_not_reachable">Устройството е недостъпно</string>
<string name="error_already_paired">Устройството вече е сдвоено</string>
<string name="error_could_not_send_package">Пакетът не може да бъде изпратен</string>
<string name="error_timed_out">Просрочка</string>
<string name="error_canceled_by_user">Отхвърлена от потребителя</string>
<string name="error_canceled_by_other_peer">Отказана от другата страна</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Изтриване</string>
<string name="sftp_no_storage_locations_configured">Няма конфигурирани места за съхранение</string>
<string name="sftp_saf_permission_explanation">За да получите достъп до файлове от разстояние, трябва да конфигурирате местата за съхранение</string>
<string name="sftp_manage_storage_permission_explanation">За да разрешите отдалечен достъп до файловете на това устройство, трябва да разрешите KDE Connect да управлява хранилището.</string>
<string name="no_players_connected">Не са открити играчи</string>
<string name="send_files">Изпращане на файлове</string>
<string name="block_notification_contents">Блокиране на съдържанието в известията</string>
@@ -247,6 +246,7 @@
<string name="permission_explanation">Тази приставка се нуждае от разрешения, за да работи</string>
<string name="optional_permission_explanation">Трябва да предоставите допълнителни разрешения, за да активирате всички функции</string>
<string name="plugins_need_optional_permission">Някои плъгини имат деактивирани функции поради липса на разрешение (докоснете за повече информация):</string>
<string name="share_optional_permission_explanation">За да получавате файлове, трябва да разрешите достъпа до хранилището</string>
<string name="telepathy_permission_explanation">За да четете и записвате SMS от работния плот, трябва да дадете разрешение за SMS</string>
<string name="telephony_permission_explanation">За да виждате телефонни обаждания на работния плот, трябва да дадете разрешение за телефонни обаждания дневници и състояние на телефона</string>
<string name="telephony_optional_permission_explanation">За да видите име на контакт вместо телефонен номер, трябва да дадете достъп до контактите на телефона</string>

View File

@@ -42,7 +42,6 @@
<string name="unknown_device">Nepoznat uređaj</string>
<string name="error_not_reachable">Uređaj nije dostupan</string>
<string name="error_already_paired">Uređaj već uparen</string>
<string name="error_could_not_send_package">Nije moguće poslati paket</string>
<string name="error_timed_out">Isteklo</string>
<string name="error_canceled_by_user">Prekinuo korisnik</string>
<string name="error_canceled_by_other_peer">Prekinuo drugi korisnik</string>

View File

@@ -41,7 +41,7 @@
<string name="sad_ok">D\'acord :(</string>
<string name="cancel">Cancel·la</string>
<string name="open_settings">Obre l\'arranjament</string>
<string name="no_permissions">Us caldrà concedir permís per a accedir a les notificacions</string>
<string name="no_permissions">Us caldrà atorgar permís per a accedir a les notificacions</string>
<string name="no_permission_mprisreceiver">Per a poder controlar els reproductors multimèdia cal atorgar accés a les notificacions</string>
<string name="no_permissions_remotekeyboard">Per a rebre les pulsacions de tecles, haureu d\'activar el teclat remot del KDE Connect</string>
<string name="send_ping">Envia un ping</string>
@@ -99,7 +99,6 @@
<string name="battery_status_format">Bateria: %d%%</string>
<string name="battery_status_low_format">Bateria: %d%% bateria baixa</string>
<string name="battery_status_charging_format">Bateria: %d%% està carregant</string>
<string name="battery_status_unknown">La informació de la bateria no està disponible</string>
<string name="category_connected_devices">Dispositius connectats</string>
<string name="category_not_paired_devices">Dispositius disponibles</string>
<string name="category_remembered_devices">Dispositius recordats</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Dispositiu desconegut</string>
<string name="error_not_reachable">No es pot accedir al dispositiu</string>
<string name="error_already_paired">El dispositiu ja està aparellat</string>
<string name="error_could_not_send_package">No s\'ha pogut enviar el paquet</string>
<string name="error_timed_out">Ha excedit el temps</string>
<string name="error_canceled_by_user">Cancel·lat per l\'usuari</string>
<string name="error_canceled_by_other_peer">Cancel·lat per l\'altre parell</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Suprimeix</string>
<string name="sftp_no_storage_locations_configured">No s\'ha configurat cap ubicació d\'emmagatzematge</string>
<string name="sftp_saf_permission_explanation">Per a accedir remotament als fitxers cal configurar les ubicacions d\'emmagatzematge</string>
<string name="sftp_manage_storage_permission_explanation">Per a permetre l\'accés remot als fitxers d\'aquest dispositiu, haureu de permetre que el KDE Connect gestioni l\'emmagatzematge.</string>
<string name="no_players_connected">No s\'ha trobat cap reproductor</string>
<string name="send_files">Envia fitxers</string>
<string name="block_notification_contents">Bloca el contingut de les notificacions</string>
@@ -245,7 +244,8 @@
<string name="close">Tanca</string>
<string name="plugins_need_permission">Alguns connectors necessiten permisos per a funcionar (toqueu per a més informació):</string>
<string name="permission_explanation">Aquest connector necessita permisos per a funcionar</string>
<string name="optional_permission_explanation">Us caldrà concedir permisos extres per a accedir a totes les característiques</string>
<string name="all_permissions_granted">S\'han atorgat tots els permisos 🎉</string>
<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="telepathy_permission_explanation">Per a llegir i escriure SMS des de l\'escriptori, haureu de donar permís als SMS</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Baterie: %d%%</string>
<string name="battery_status_low_format">Baterie: %d%% Téměř vybitá baterie</string>
<string name="battery_status_charging_format">Battery: %d%% nabíjí se</string>
<string name="battery_status_unknown">Informace o baterii jsou nedostupné</string>
<string name="category_connected_devices">Připojená zařízení</string>
<string name="category_not_paired_devices">Dostupná zařízení</string>
<string name="category_remembered_devices">Zapamatovaná zařízení</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Neznámé zařízení</string>
<string name="error_not_reachable">Zařízení je nedostupné</string>
<string name="error_already_paired">Zařízení je již spárováno</string>
<string name="error_could_not_send_package">Balíček nelze poslat</string>
<string name="error_timed_out">Čas vypršel</string>
<string name="error_canceled_by_user">Přerušeno uživatelem</string>
<string name="error_canceled_by_other_peer">Přerušeno druhým uživatelem</string>
@@ -235,6 +233,7 @@
<string name="sftp_action_mode_menu_delete">Smazat</string>
<string name="sftp_no_storage_locations_configured">Nebyla nastavena umístění úložiště.</string>
<string name="sftp_saf_permission_explanation">Pro vzdálený přístup k souborům musíte nastavit umístění úložišť</string>
<string name="sftp_manage_storage_permission_explanation">Pro umožnění vzdáleného přístupu k souborům na tomto zařízení musíte povolit aplikaci KDE Connect spravovat úložiště.</string>
<string name="no_players_connected">Přehrávač nenalezen</string>
<string name="send_files">Odeslat soubory</string>
<string name="block_notification_contents">Blokovat obsah upozornění</string>
@@ -261,8 +260,10 @@
<string name="close">Zavřít</string>
<string name="plugins_need_permission">Některé moduly potřebují pro práci povolení (ťukněte pro více informací):</string>
<string name="permission_explanation">Tento modul potřebuje pro práci povolení</string>
<string name="all_permissions_granted">Veškerá oprávnění udělena 🎉</string>
<string name="optional_permission_explanation">Pro zpřístupnění všech funkcí potřebujete další oprávnění</string>
<string name="plugins_need_optional_permission">Některé moduly mají vypnuté vlastnosti, kvůli nedostatečným oprávněním (ťukněte pro více informací):</string>
<string name="share_optional_permission_explanation">Pro příjem souborů je potřeba povolit přístup k úložišti</string>
<string name="telepathy_permission_explanation">Pro čtení a psaní SMS z počítače musíte udělit oprávnění k SMS</string>
<string name="telephony_permission_explanation">Pro zobrazení telefonátů v počítači musíte udělit oprávnění k záznamům telefonování a stavu telefonu</string>
<string name="telephony_optional_permission_explanation">Pro zobrazení jména kontaktu u telefonního čísla je potřeba udělit oprávnění ke kontaktům v telefonu</string>

View File

@@ -63,7 +63,6 @@
<string name="unknown_device">Ukendt enhed</string>
<string name="error_not_reachable">Enheden kan ikke nås</string>
<string name="error_already_paired">Enhed allerede parret</string>
<string name="error_could_not_send_package">Kunne ikke sende pakke</string>
<string name="error_timed_out">Tidsudløb</string>
<string name="error_canceled_by_user">Annulleret af brugeren</string>
<string name="error_canceled_by_other_peer">Annulleret af modpart</string>

View File

@@ -89,7 +89,6 @@
<string name="unknown_device">Unbekanntes Gerät</string>
<string name="error_not_reachable">Das Gerät ist nicht erreichbar</string>
<string name="error_already_paired">Das Gerät ist bereits verbunden</string>
<string name="error_could_not_send_package">Das Paket kann nicht gesendet werden</string>
<string name="error_timed_out">Zeitüberschreitung</string>
<string name="error_canceled_by_user">Abbruch durch Benutzer</string>
<string name="error_canceled_by_other_peer">Abbruch durch Gegenstelle</string>

View File

@@ -90,7 +90,6 @@
<string name="battery_status_format">Μπαταρία: %d%%</string>
<string name="battery_status_low_format">Μπαταρία: %d%% Χαμηλή συάθμη</string>
<string name="battery_status_charging_format">Μπαταρία: %d%% φόρτιση</string>
<string name="battery_status_unknown">Πληροφορίες για τη μπαταρία δεν είναι διαθέσιμες</string>
<string name="category_connected_devices">Συνδεδεμένες συσκευές</string>
<string name="category_not_paired_devices">Διαθέσιμες συσκευές</string>
<string name="category_remembered_devices">Συσκευές στη μνήμη</string>
@@ -100,7 +99,6 @@
<string name="unknown_device">Άγνωστη συσκευή</string>
<string name="error_not_reachable">Η συσκευή δεν είναι προσβάσιμη</string>
<string name="error_already_paired">Η συσκευή ήδη συζεύχθηκε</string>
<string name="error_could_not_send_package">Αδυναμία αποστολής πακέτου</string>
<string name="error_timed_out">Τέλος χρονικού ορίου</string>
<string name="error_canceled_by_user">Ακυρώθηκε από τον χρήστη</string>
<string name="error_canceled_by_other_peer">Ακυρώθηκε από άλλον χρήστη</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Battery: %d%%</string>
<string name="battery_status_low_format">Battery: %d%% Low Battery</string>
<string name="battery_status_charging_format">Battery: %d%% charging</string>
<string name="battery_status_unknown">Battery information not available</string>
<string name="category_connected_devices">Connected devices</string>
<string name="category_not_paired_devices">Available devices</string>
<string name="category_remembered_devices">Remembered devices</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Unknown device</string>
<string name="error_not_reachable">Device not reachable</string>
<string name="error_already_paired">Device already paired</string>
<string name="error_could_not_send_package">Could not send package</string>
<string name="error_timed_out">Timed out</string>
<string name="error_canceled_by_user">Cancelled by user</string>
<string name="error_canceled_by_other_peer">Cancelled by other peer</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Delete</string>
<string name="sftp_no_storage_locations_configured">No storage locations configured</string>
<string name="sftp_saf_permission_explanation">To access files remotely you have to configure storage locations</string>
<string name="sftp_manage_storage_permission_explanation">To allow remote access to files on this device you need to allow KDE Connect to manage the storage.</string>
<string name="no_players_connected">No players found</string>
<string name="send_files">Send files</string>
<string name="block_notification_contents">Block notification contents</string>
@@ -245,8 +244,10 @@
<string name="close">Close</string>
<string name="plugins_need_permission">Some Plugins need permissions to work (tap for more info):</string>
<string name="permission_explanation">This plugin needs permissions to work</string>
<string name="all_permissions_granted">All permissions granted 🎉</string>
<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="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>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Batería: %d%%</string>
<string name="battery_status_low_format">Batería: %d%% Batería baja</string>
<string name="battery_status_charging_format">Batería: %d%% cargando</string>
<string name="battery_status_unknown">Información de batería no disponible</string>
<string name="category_connected_devices">Dispositivos conectados</string>
<string name="category_not_paired_devices">Dispositivos disponibles</string>
<string name="category_remembered_devices">Dispositivos recordados</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Dispositivo desconocido</string>
<string name="error_not_reachable">No se encuentra el dispositivo</string>
<string name="error_already_paired">Dispositivo ya vinculado</string>
<string name="error_could_not_send_package">No se puede enviar el paquete</string>
<string name="error_timed_out">Se ha agotado el tiempo</string>
<string name="error_canceled_by_user">Cancelado por el usuario</string>
<string name="error_canceled_by_other_peer">Cancelado por la otra parte</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Borrar</string>
<string name="sftp_no_storage_locations_configured">No hay configurada ninguna localización de almacenamiento</string>
<string name="sftp_saf_permission_explanation">Para acceder a los archivos remotamente debe configurar las localizaciones de almacenamiento</string>
<string name="sftp_manage_storage_permission_explanation">Para permitir el acceso remoto a archivos en este dispositivo necesita permitir a KDE Connect a administrar el almacenamiento.</string>
<string name="no_players_connected">Ningún reproductor encontrado</string>
<string name="send_files">Enviar archivos</string>
<string name="block_notification_contents">Bloquear los contenidos de las notificaciones</string>
@@ -245,8 +244,10 @@
<string name="close">Cerrar</string>
<string name="plugins_need_permission">Algunos complementos necesitan permisos para funcionar (pulse para más información):</string>
<string name="permission_explanation">Este complemento necesita permisos para funcionar</string>
<string name="all_permissions_granted">Se han garantizado todos los permisos 🎉</string>
<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="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>

View File

@@ -78,7 +78,6 @@
<string name="unknown_device">Tundmatu seade</string>
<string name="error_not_reachable">Seade pole saadaval</string>
<string name="error_already_paired">Seade on juba paaritatud</string>
<string name="error_could_not_send_package">Paketi saatmine nurjus</string>
<string name="error_timed_out">Ajaületus</string>
<string name="error_canceled_by_user">Kasutaja katkestas</string>
<string name="error_canceled_by_other_peer">Teine pool katkestas</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Bateria: %%%d</string>
<string name="battery_status_low_format">Bateria: %%%d bateria baxu</string>
<string name="battery_status_charging_format">Bateria: %%%d kargatzen</string>
<string name="battery_status_unknown">Bateriari buruzko informazioa ez dago erabilgarri</string>
<string name="category_connected_devices">Konektatutako gailuak</string>
<string name="category_not_paired_devices">Gailu eskuragarriak</string>
<string name="category_remembered_devices">Gogoratutako gailuak</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Gailu ezezaguna</string>
<string name="error_not_reachable">Gailua ez dago eskuragarri</string>
<string name="error_already_paired">Gailua dagoeneko parekatuta</string>
<string name="error_could_not_send_package">Ezin izan da paketea bidali</string>
<string name="error_timed_out">Denbora-muga agortu da</string>
<string name="error_canceled_by_user">Erabiltzaileak utzita</string>
<string name="error_canceled_by_other_peer">Beste kideak utzita</string>

View File

@@ -52,6 +52,7 @@
<string name="remotekeyboard_multiple_connections">Etänäppäimistöyhteyksiä on useampia: valitse asetettava laite</string>
<string name="open_mousepad">Kauko-ohjaus</string>
<string name="mousepad_info">Siirrä hiirikohdistinta liikuttamalla sormea näytöllä. Tee hiirenpainallus napauttamalla, ja käytä kahta tai kolmea sormea oikealle ja keskipainikkeelle. Vieritä kahdella sormella. Pitkällä painalluksella voit vetää ja pudottaa.</string>
<string name="mousepad_keyboard_input_not_supported">Paritettu laite ei tue näppäimistösyötettä</string>
<string name="mousepad_single_tap_settings_title">Aseta yhden sormen napautuksen toiminto</string>
<string name="mousepad_double_tap_settings_title">Aseta kahden sormen napautuksen toiminto</string>
<string name="mousepad_triple_tap_settings_title">Aseta kolmen sormen napautuksen toiminto</string>
@@ -98,7 +99,6 @@
<string name="battery_status_format">Varaus: %d %%</string>
<string name="battery_status_low_format">Varaus: %d %%, vähissä</string>
<string name="battery_status_charging_format">Varaus: %d %%, latautuu</string>
<string name="battery_status_unknown">Varaustietoa ei ole saatavilla</string>
<string name="category_connected_devices">Yhdistetyt laitteet</string>
<string name="category_not_paired_devices">Saatavilla olevat laitteet</string>
<string name="category_remembered_devices">Muistetut laitteet</string>
@@ -108,7 +108,6 @@
<string name="unknown_device">Tuntematon laite</string>
<string name="error_not_reachable">Laite tavoittamattomissa</string>
<string name="error_already_paired">Laite on jo kytketty pariksi</string>
<string name="error_could_not_send_package">Ei voitu lähettää pakettia</string>
<string name="error_timed_out">Aikakatkaisu</string>
<string name="error_canceled_by_user">Käyttäjä perui</string>
<string name="error_canceled_by_other_peer">Vertaiskäyttäjä perui</string>
@@ -218,8 +217,11 @@
<string name="sftp_action_mode_menu_delete">Poista</string>
<string name="sftp_no_storage_locations_configured">Tallennustiloja ei ole asetettu</string>
<string name="sftp_saf_permission_explanation">Tallennustilat on asetettava etätiedostojen käyttämiseksi</string>
<string name="sftp_manage_storage_permission_explanation">Tiedostojen etäkäytön sallimiseksi tällä laitteella KDE Connectin on annettava hallita talletustilaa.</string>
<string name="no_players_connected">Soittimia ei löytynyt</string>
<string name="send_files">Lähetä tiedostoja</string>
<string name="block_notification_contents">Estä ilmoitusten sisältö</string>
<string name="block_notification_images">Estä ilmoitusten kuvat</string>
<string name="pairing_title">KDE Connect -laitteet</string>
<string name="pairing_description">Muiden samassa verkossa olevien KDE Connectia käyttävien laitteiden pitäisi ilmestyä tähän.</string>
<string name="device_rename_title">Muuta laitteen nimeä</string>
@@ -244,6 +246,7 @@
<string name="permission_explanation">Liitännäinen tarvitsee toimiakseen lisäkäyttöoikeuksia</string>
<string name="optional_permission_explanation">Kaikkien toimintojen käyttämiseksi sinun on annettava lisäkäyttöoikeuksia</string>
<string name="plugins_need_optional_permission">Jotkin liitännäisten ominaisuudet eivät ole käytössä puuttuvien käyttöoikeuksien takia (lisätietoa napsauttamalla):</string>
<string name="share_optional_permission_explanation">Talletustilan käyttö on sallittava tiedostojen vastaanottamiseksi</string>
<string name="telepathy_permission_explanation">Lukeaksesi ja lähettääksesi tekstiviestejä työpöydältä sinun on annettava käyttöoikeudet tekstiviesteihin</string>
<string name="telephony_permission_explanation">Puhelujen näyttäminen työpöydällä vaatii käyttöoikeuden puhelulokiin ja puhelimen tilaan</string>
<string name="telephony_optional_permission_explanation">Puhelimen yhteystietoihin on annettava käyttöoikeudet, jotta voit nähdä yhteystiedoissa nimet puhelinnumerojen sijaan</string>
@@ -308,6 +311,7 @@
<string name="empty_trusted_networks_list_text">Luotettuja verkkoja ei ole vielä lisätty</string>
<string name="allow_all_networks_text">Salli kaikki</string>
<string name="location_permission_needed_title">Käyttöoikeus vaaditaan</string>
<string name="location_permission_needed_desc">KDE Connect tarvitsee taustasijaintioikeudet tietääkseen myös sovelluksen olleessa taustalla, mihin langattomaan verkkoon on kirjauduttu. Ympärilläsi olevien langattomien verkkojen nimiä voi käyttää sijaintisi selvittämiseen, vaikka KDE Connect ei tietoa siihen käytäkään.</string>
<string name="clipboard_android_x_incompat">Android 10 on poistanut kaikkien sovellusten leikepöytäkäytön. Liitännäinen poistetaan käytöstä.</string>
<string name="mpris_open_url">Jatka toistoa tästä</string>
<string name="cant_open_url">Verkko-osoitetta ei voi avata toiston jatkamiseksi</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Batterie : %d %%</string>
<string name="battery_status_low_format">Batterie : %d %% Batterie faible</string>
<string name="battery_status_charging_format">Batterie : %d%% en charge</string>
<string name="battery_status_unknown">Informations de batterie non disponibles</string>
<string name="category_connected_devices">Périphériques connectés</string>
<string name="category_not_paired_devices">Périphériques disponibles</string>
<string name="category_remembered_devices">Périphériques mémorisés</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Périphérique inconnu</string>
<string name="error_not_reachable">Périphérique inaccessible</string>
<string name="error_already_paired">Périphérique déjà associé</string>
<string name="error_could_not_send_package">Il est impossible d\'envoyer un paquet</string>
<string name="error_timed_out">Délai expiré</string>
<string name="error_canceled_by_user">Annulé par l\'utilisateur</string>
<string name="error_canceled_by_other_peer">Annulé par un autre homologue</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Supprimer</string>
<string name="sftp_no_storage_locations_configured">Aucun emplacement stockage n\'est configuré</string>
<string name="sftp_saf_permission_explanation">Vous devez configurer des emplacements de stockage pour accéder aux fichiers à distance</string>
<string name="sftp_manage_storage_permission_explanation">Pour permettre laccès à distance aux fichiers sur ce périphérique, vous devez autoriser KDE Connect à gérer l\'enregistrement.</string>
<string name="no_players_connected">Aucun lecteur trouvé</string>
<string name="send_files">Envoyer des fichiers</string>
<string name="block_notification_contents">Bloquer les contenus de notifications</string>
@@ -245,8 +244,10 @@
<string name="close">Fermer</string>
<string name="plugins_need_permission">Certains modules externes nécessitent des permissions pour fonctionner (tapez pour plus d\'informations) :</string>
<string name="permission_explanation">Ce module externe nécessite des permissions pour fonctionner</string>
<string name="all_permissions_granted">Tous les droits d\'accès ont été autorisés 🎉</string>
<string name="optional_permission_explanation">Vous devez accorder des permissions supplémentaires pour activer toutes les fonctionnalités</string>
<string name="plugins_need_optional_permission">Certaines fonctionnalités de modules externes sont désactivées faute de permissions suffisantes (tapez pour plus d\'informations) :</string>
<string name="share_optional_permission_explanation">Pour la réception de fichiers, vous devez autoriser un accès en écriture.</string>
<string name="telepathy_permission_explanation">Pour lire et écrire des SMS depuis votre ordinateur, veuillez permettre l\'accès aux SMS</string>
<string name="telephony_permission_explanation">Pour voir les appels depuis votre ordinateur, veuillez permettre l\'accès au journal des appels et à l\'état du téléphone</string>
<string name="telephony_optional_permission_explanation">Pour voir le nom du contact au lieu du numéro de téléphone, veuillez permettre l\'accès aux contacts du téléphone</string>

View File

@@ -1,16 +1,21 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="kde_connect">KDE Connect</string>
<string name="manifest_label_share">Enviar a un dispositivo</string>
<string name="foreground_notification_no_devices">Non conectado a ningún dispositivo</string>
<string name="foreground_notification_devices">Conectado a: %s</string>
<string name="foreground_notification_send_clipboard">Enviar o portapapeis</string>
<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_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>
<string name="pref_plugin_sftp_desc">Permite examinar o sistema de ficheiros do dispositivo remotamente.</string>
<string name="pref_plugin_clipboard">Sincronización do portapapeis</string>
<string name="pref_plugin_clipboard_desc">Comparta o contido do portapapeis.</string>
<string name="pref_plugin_clipboard_sent">Enviouse o portapapeis</string>
<string name="pref_plugin_mousepad">Entrada remota</string>
<string name="pref_plugin_mousepad_desc">Use o teléfono ou tableta como área táctil e teclado.</string>
<string name="pref_plugin_presenter">Mando da presentación</string>
@@ -33,6 +38,7 @@
<string name="pref_plugin_sharereceiver_desc">Comparta ficheiros e enderezos URL entre dispositivos</string>
<string name="device_list_empty">Non hai dispositivos.</string>
<string name="ok">Aceptar</string>
<string name="sad_ok">Vale :(</string>
<string name="cancel">Cancelar</string>
<string name="open_settings">Abrir a configuración</string>
<string name="no_permissions">Debe conceder permisos para acceder ás notificacións</string>
@@ -46,11 +52,19 @@
<string name="remotekeyboard_multiple_connections">Hai máis dunha conexión de teclado remoto, seleccione o dispositivo para configurar.</string>
<string name="open_mousepad">Entrada remota</string>
<string name="mousepad_info">Mova un dedo na pantalla para mover o cursor do rato. Toque para facer clic, e use dous ou tres dedos para os botóns secundario e central. Use dous dedos para desprazar. Prema durante un tempo para arrastrar e soltar.</string>
<string name="mousepad_keyboard_input_not_supported">O dispositivo emparellado non permite entrada de teclado</string>
<string name="mousepad_single_tap_settings_title">Definir a acción de tocar cun dedo</string>
<string name="mousepad_double_tap_settings_title">Definir a acción de tocar con dous dedos</string>
<string name="mousepad_triple_tap_settings_title">Definir a acción de tocar con tres dedos</string>
<string name="mousepad_sensitivity_settings_title">Definir a sensibilidade do punteiro táctil</string>
<string name="mousepad_acceleration_profile_settings_title">Definir a aceleración do punteiro</string>
<string name="mousepad_scroll_direction_title">Inverter a dirección de desprazamento</string>
<string-array name="mousepad_tap_entries">
<item>Clic esquerdo</item>
<item>Clic dereito</item>
<item>Clic central</item>
<item>Nada</item>
</string-array>
<string-array name="mousepad_sensitivity_entries">
<item>O máis lento</item>
<item>Lento</item>
@@ -66,6 +80,25 @@
<item>Máis forte</item>
<item>A máis forte</item>
</string-array>
<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_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>
<string name="sendkeystrokes_pref_enabled">Activar o envío de pulsacións de tecla</string>
<string name="sendkeystrokes_pref_enabled_summary">Escoitar en busca de datos de tipo MIME «text/x-keystrokes»</string>
<string name="sendkeystrokes_safe_text_enabled">Enviar os textos seguros inmediatamente</string>
<string name="sendkeystrokes_safe_text_enabled_summary">Enviar as cadeas numéricas curtas sen confirmación</string>
<string name="pref_plugin_mousepad_send_keystrokes">Enviar como pulsacións de tecla</string>
<string name="mouse_receiver_plugin_description">Recibir movementos de rato remotos</string>
<string name="mouse_receiver_plugin_name">Receptor de rato</string>
<string name="mouse_receiver_no_permissions">Ten que activar o servizo de accesibilidade</string>
<string name="view_status_title">Estado</string>
<string name="battery_status_format">Batería: %d%%</string>
<string name="battery_status_low_format">Batería: %d%% (baixa)</string>
<string name="battery_status_charging_format">Batería: %d%% (cargando)</string>
<string name="category_connected_devices">Dispositivos conectados</string>
<string name="category_not_paired_devices">Dispositivos dispoñíbeis</string>
<string name="category_remembered_devices">Dispositivos coñecidos</string>
@@ -75,12 +108,13 @@
<string name="unknown_device">Dispositivo descoñecido</string>
<string name="error_not_reachable">Dispositivo fóra do alcance</string>
<string name="error_already_paired">O dispositivo xa está emparellado.</string>
<string name="error_could_not_send_package">Non se puido enviar o paquete.</string>
<string name="error_timed_out">Esgotouse o tempo límite</string>
<string name="error_canceled_by_user">Cancelouno o usuario.</string>
<string name="error_canceled_by_other_peer">Cancelouse remotamente</string>
<string name="encryption_info_title">Información do cifrado</string>
<string name="encryption_info_msg_no_ssl">O outro dispositivo non usa unha versión recente de KDE Connect, usarase un método obsoleto de cifrado.</string>
<string name="my_device_fingerprint">A pegada SHA256 do certificado do seu dispositivo é:</string>
<string name="remote_device_fingerprint">A pegada SHA256 do certificado do dispositivo remoto é:</string>
<string name="pair_requested">Solicitude de emparellamento</string>
<string name="pairing_request_from">Solicitude de emparellamento de %1s.</string>
<plurals name="incoming_file_title">
@@ -115,6 +149,7 @@
<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>
</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="tap_to_answer">Toque para contestar</string>
@@ -132,6 +167,8 @@
<string name="mpris_rew">Retroceder</string>
<string name="mpris_ff">Cara a adiante</string>
<string name="mpris_next">Seguinte</string>
<string name="mpris_loop">Bucle</string>
<string name="mpris_shuffle">Desordenar</string>
<string name="mpris_volume">Volume</string>
<string name="mpris_time_settings_title">Botóns de avanzar e retroceder</string>
<string name="mpris_time_settings_summary">Axuste o tempo que avanzar ou retroceder ao premer</string>
@@ -165,6 +202,7 @@
<string name="share_received_file">Compartir «%s»</string>
<string name="title_activity_notification_filter">Filtro de notificacións</string>
<string name="filter_apps_info">As notificacións sincronizaranse para os seguintes aplicativos.</string>
<string name="show_notification_if_screen_off">Enviar notificacións só se a pantalla está apagada</string>
<string name="add_device_dialog_title">Engadir o dispositivo</string>
<string name="add_device_hint">Nome de máquina ou enderezo IP</string>
<string name="sftp_preference_configured_storage_locations">Lugares de almacenamento configurados</string>
@@ -179,8 +217,11 @@
<string name="sftp_action_mode_menu_delete">Eliminar</string>
<string name="sftp_no_storage_locations_configured">Non se configuraron localizacións de almacenamento</string>
<string name="sftp_saf_permission_explanation">Para acceder a ficheiro remotamente ten que configurar lugares de almacenamento</string>
<string name="sftp_manage_storage_permission_explanation">Para permitir o acceso remoto a ficheiros neste dispositivo ten que permitir a KDE Connect xestionar o seu almacenamento.</string>
<string name="no_players_connected">Non se atoparon reprodutores.</string>
<string name="send_files">Enviar ficheiros</string>
<string name="block_notification_contents">Bloquear o contido das notificacións</string>
<string name="block_notification_images">Bloquear as imaxes das notificacións</string>
<string name="pairing_title">Dispositivos con KDE Connect</string>
<string name="pairing_description">Outros dispositivos que estean a executar KDE Connect na mesma rede deberían aparecer aquí.</string>
<string name="device_rename_title">Renomear o dispositivo</string>
@@ -188,19 +229,25 @@
<string name="refresh">Actualizar</string>
<string name="unreachable_description">Este dispositivo emparellado está fóra do alcance. Asegúrese de que está conectado á mesma rede.</string>
<string name="no_wifi">Non ten conexión a unha rede Wi-Fi así que pode que non vexa ningún dispositivo. Prema aquí para activar a Wi-Fi.</string>
<string name="on_non_trusted_message">Non é unha rede de confianza: desactivouse o descubrimento automático.</string>
<string name="no_file_browser">Non hai navegadores de ficheiros instalados.</string>
<string name="pref_plugin_telepathy">Enviar unha mensaxe de texto</string>
<string name="pref_plugin_telepathy_desc">Enviar mensaxes de texto desde o seu escritorio</string>
<string name="pref_plugin_telepathy_mms">Enviar MMS</string>
<string name="pref_plugin_telepathy_mms_desc">Para poder enviar MMS desde KDE Connect ten que configuralo como a aplicación predeterminada de envío de SMS.</string>
<string name="findmyphone_title">Atopar o móbil</string>
<string name="findmyphone_title_tablet">Atopar a tableta</string>
<string name="findmyphone_title_tv">Atopar o meu televisor</string>
<string name="findmyphone_description">Reproduce un son de chamada no dispositivo para que poida atopalo.</string>
<string name="findmyphone_found">Atopeino</string>
<string name="open">Abrir</string>
<string name="close">Pechar</string>
<string name="plugins_need_permission">Algúns complementos necesitan permisos para funcionar (toque para máis información):</string>
<string name="permission_explanation">Este complemento necesita permisos para funcionar.</string>
<string name="all_permissions_granted">Garantíronse todos os permisos 🎉</string>
<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="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>
@@ -221,8 +268,11 @@
<string name="pref_plugin_mprisreceiver">Control do reprodutor de multimedia</string>
<string name="pref_plugin_mprisreceiver_desc">Controlar os reprodutores do seu móbil desde outro dispositivo</string>
<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_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>
@@ -256,21 +306,90 @@
<string name="no_app_for_opening">Non se atopou ningún aplicativo axeitado para abrir este ficheiro</string>
<string name="remote_keyboard_service">Teclado remoto de KDE Connect</string>
<string name="presenter_pointer">Punteiro</string>
<string name="trusted_networks">Redes de confianza</string>
<string name="trusted_networks_desc">Restrinxir o descubrimento automático a redes coñecidas</string>
<string name="add_trusted_network">Engadir %1s</string>
<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 darredor 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>
<string name="bigscreen_home">Inicio</string>
<string name="bigscreen_up">Subir</string>
<string name="bigscreen_left">Esquerda</string>
<string name="bigscreen_select">Seleccionar</string>
<string name="bigscreen_right">Dereita</string>
<string name="bigscreen_down">Baixar</string>
<string name="bigscreen_mic">Micrófono</string>
<string name="pref_plugin_bigscreen">Mando de Bigscreen</string>
<string name="pref_plugin_bigscreen_desc">Use o seu dispositivo como mando de Plasma Bigscreen</string>
<string name="bigscreen_optional_permission_explanation">Para compartir entrada de micrófono do seu teléfono ten que dar acceso á entrada de son do teléfono.</string>
<string name="bigscreen_speech_extra_prompt">Fala</string>
<string name="message_reply_label">RESPONDER</string>
<string name="mark_as_read_label">MARCAR COMO LIDO</string>
<string name="user_display_name">Vostede</string>
<string name="set_default_sms_app_title">Enviar MMS</string>
<string name="set_group_message_as_mms_title">Enviar MMS grupais</string>
<string name="set_long_text_as_mms_title">Enviar texto longo como MMS</string>
<string name="convert_to_mms_after_title">Converter en MMS</string>
<string-array name="convert_to_mms_after_entries">
<item>After one message</item>
<item>After two messages</item>
<item>After three messages</item>
<item>After four messages</item>
<item>After five messages</item>
<item>Tras unha mensaxe</item>
<item>Tras dúas mensaxes</item>
<item>Tras tres mensaxes</item>
<item>Tras catro mensaxes</item>
<item>Tras cinco mensaxes</item>
</string-array>
<string name="theme_dialog_title">Escoller un tema</string>
<string-array name="theme_list">
<item>Set by Battery Saver</item>
<item/>
<item>Dark</item>
<item>Definir polo aforrador de batería</item>
<item>Claro</item>
<item>Escuro</item>
</string-array>
<string-array name="theme_list_v28">
<item/>
<item/>
<item>Dark</item>
<item>Predeterminado do sistema</item>
<item>Claro</item>
<item>Escuro</item>
</string-array>
<string name="report_bug">Informar dun fallo</string>
<string name="donate">Doar</string>
<string name="source_code">Código fonte</string>
<string name="licenses">Licenzas</string>
<string name="website">Sitio web</string>
<string name="about">Sobre</string>
<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="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>
<string name="kde_be_free">KDE - Sexa libre!</string>
<string name="kde">KDE</string>
<string name="konqi">Konqi</string>
<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="send_compose">Enviar</string>
<string name="open_compose_send">Escribir texto</string>
<string name="app_description">Aplicación multi-plataforma que permite aos seus dispositivos comunicarse (p. ex. o seu teléfono e o seu computador)</string>
<string name="about_kde_about">"&lt;h1&gt;Sobre&lt;/h1&gt; &lt;p&gt;KDE é unha comunidade internacional de persoas adicadas á 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 ambiente 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_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 coñecementos de enxeñaría de 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, atopará 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="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>
<string name="bug_fixes_and_general_improvements">Correccións de fallos e melloras</string>
<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="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>
</resources>

View File

@@ -98,7 +98,6 @@
<string name="battery_status_format">Akku: %d%%</string>
<string name="battery_status_low_format">Akku: %d%% alacsony töltöttség</string>
<string name="battery_status_charging_format">Akku: %d%% töltés</string>
<string name="battery_status_unknown">Nem érhetők el akkuinformációk</string>
<string name="category_connected_devices">Csatlakoztatott eszközök</string>
<string name="category_not_paired_devices">Elérhető eszközök</string>
<string name="category_remembered_devices">Megjegyzett eszközök</string>
@@ -108,7 +107,6 @@
<string name="unknown_device">Ismeretlen eszköz</string>
<string name="error_not_reachable">Az eszköz nem érhető el</string>
<string name="error_already_paired">Az eszköz már párosítva van</string>
<string name="error_could_not_send_package">Nem sikerült elküldeni a csomagot</string>
<string name="error_timed_out">Időtúllépés</string>
<string name="error_canceled_by_user">Megszakítva a felhasználó által</string>
<string name="error_canceled_by_other_peer">A másik partner megszakította</string>

View File

@@ -26,6 +26,7 @@
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Cancella</string>
<string name="open_settings">Aperi Preferentias</string>
<string name="send_ping">Invia Ping</string>
<string name="open_mpris_controls">Controlo mutimedia</string>
<string name="open_mousepad">Entrata remote</string>
@@ -89,6 +90,7 @@
<item>1 minuta</item>
<item>2 minutas</item>
</string-array>
<string name="share_to">Comparti a…</string>
<string name="custom_device_fab_hint">Adde un dispositivo</string>
<string name="undo">Annulla</string>
<string name="share">Comparti</string>
@@ -99,6 +101,8 @@
<string name="sftp_storage_preference_display_name">Nomine de monstrar</string>
<string name="sftp_action_mode_menu_delete">Dele</string>
<string name="send_files">Invia files</string>
<string name="block_notification_contents">Bloca contentos de notification</string>
<string name="block_notification_images">Bloca imagines de notification</string>
<string name="device_rename_confirm">Renomina</string>
<string name="refresh">Refresca</string>
<string name="pref_plugin_telepathy">Invia SMS</string>

View File

@@ -98,7 +98,6 @@
<string name="battery_status_format">Baterai: %d%%</string>
<string name="battery_status_low_format">Baterai: %d%% Baterai Lemah</string>
<string name="battery_status_charging_format">Baterai %d%% mengisi</string>
<string name="battery_status_unknown">Informasi baterai tidak tersedia</string>
<string name="category_connected_devices">Perangkat terhubung</string>
<string name="category_not_paired_devices">Perangkat tersedia</string>
<string name="category_remembered_devices">Perangkat teringat</string>
@@ -108,7 +107,6 @@
<string name="unknown_device">Perangkat tak diketahui</string>
<string name="error_not_reachable">Peranti tidak dapat dicapai</string>
<string name="error_already_paired">Peranti sudah disandingkan</string>
<string name="error_could_not_send_package">Tidak dapat mengirim paket</string>
<string name="error_timed_out">Waktu habis</string>
<string name="error_canceled_by_user">Dibatalkan oleh pengguna</string>
<string name="error_canceled_by_other_peer">Dibatalkan oleh kawan lain</string>

View File

@@ -92,7 +92,6 @@
<string name="battery_status_format">Rafhlaða: %d%%</string>
<string name="battery_status_low_format">Rafhlaða: %d%% lítil hleðsla</string>
<string name="battery_status_charging_format">Rafhlaða: %d%% í hleðslu</string>
<string name="battery_status_unknown">Upplýsingar um rafhlöðu ekki tiltækar</string>
<string name="category_connected_devices">Tengd tæki</string>
<string name="category_not_paired_devices">Tiltæk tæki</string>
<string name="category_remembered_devices">Munuð tæki</string>
@@ -102,7 +101,6 @@
<string name="unknown_device">Óþekkt tæki</string>
<string name="error_not_reachable">Tæki er ekki aðgengilegt</string>
<string name="error_already_paired">Tæki er þegar parað</string>
<string name="error_could_not_send_package">Gat ekki sent pakka</string>
<string name="error_timed_out">Féll á tíma</string>
<string name="error_canceled_by_user">Hætt við af notanda</string>
<string name="error_canceled_by_other_peer">Hætt við af hinum notandanum</string>
@@ -207,6 +205,8 @@
<string name="sftp_no_storage_locations_configured">Engar geymslustaðsetningar stilltar</string>
<string name="no_players_connected">Engir spilarar fundust</string>
<string name="send_files">Senda skrár</string>
<string name="block_notification_contents">Loka á efni í tilkynningum</string>
<string name="block_notification_images">Loka á myndir í tilkynningum</string>
<string name="pairing_title">KDE Connect tæki</string>
<string name="device_rename_title">Endurnefna tæki</string>
<string name="device_rename_confirm">Endurnefna</string>
@@ -235,6 +235,7 @@
<string name="add_command_description">Þú getur bætt við skipunum á skjáborðinu</string>
<string name="pref_plugin_mprisreceiver">Margmiðlunarstýring</string>
<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>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Batteria: %d%%</string>
<string name="battery_status_low_format">Batteria: %d%% livello basso</string>
<string name="battery_status_charging_format">Batteria: %d%% in carica</string>
<string name="battery_status_unknown">Informazioni sulla batteria non disponibili</string>
<string name="category_connected_devices">Dispositivi connessi</string>
<string name="category_not_paired_devices">Dispositivi disponibili</string>
<string name="category_remembered_devices">Dispositivi memorizzati</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Dispositivo sconosciuto</string>
<string name="error_not_reachable">Dispositivo fuori portata</string>
<string name="error_already_paired">Dispositivo già associato</string>
<string name="error_could_not_send_package">Impossibile inviare i dati</string>
<string name="error_timed_out">Richiesta scaduta</string>
<string name="error_canceled_by_user">Annullata dall\'utente</string>
<string name="error_canceled_by_other_peer">Annullata dal dispositivo remoto</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Elimina</string>
<string name="sftp_no_storage_locations_configured">Nessuna posizione di archiviazione configurata</string>
<string name="sftp_saf_permission_explanation">Per accedere da remoto ai file, devi configurare posizioni di archiviazione</string>
<string name="sftp_manage_storage_permission_explanation">Per consentire l\'accesso remoto ai file su questo dispositivo devi consentire a KDE Connect di gestire l\'archiviazione.</string>
<string name="no_players_connected">Nessun lettore trovato</string>
<string name="send_files">Invia file</string>
<string name="block_notification_contents">Blocca i contenuti delle notifiche</string>
@@ -245,8 +244,10 @@
<string name="close">Chiudi</string>
<string name="plugins_need_permission">Alcune estensioni hanno bisogno di permessi per funzionare (tocca per maggiori informazioni):</string>
<string name="permission_explanation">Questa estensione ha bisogno di permessi per funzionare</string>
<string name="all_permissions_granted">Tutti i permessi accordati 🎉</string>
<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="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>

View File

@@ -63,7 +63,6 @@
<string name="unknown_device">התקן לא ידוע</string>
<string name="error_not_reachable">ההתקן לא זמין</string>
<string name="error_already_paired">ההתקן כבר מותאם</string>
<string name="error_could_not_send_package">לא יכול לשלוח חבילה</string>
<string name="error_timed_out">נגמר הזמן</string>
<string name="error_canceled_by_user">בוטל על ידי המשתמש</string>
<string name="error_canceled_by_other_peer">בוטל על ידי מישהו אחר</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">バッテリ: %d%%</string>
<string name="battery_status_low_format">バッテリ: %d%% 残量低下</string>
<string name="battery_status_charging_format">バッテリ: %d%% 充電中</string>
<string name="battery_status_unknown">バッテリ情報が利用できません</string>
<string name="category_connected_devices">接続済みのデバイス</string>
<string name="category_not_paired_devices">利用可能なデバイス</string>
<string name="category_remembered_devices">ペアリング済みのデバイス</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">不明なデバイス</string>
<string name="error_not_reachable">デバイスに到達できません</string>
<string name="error_already_paired">デバイスは既にペアリング済みです</string>
<string name="error_could_not_send_package">パッケージを送信できませんでした</string>
<string name="error_timed_out">タイムアウト</string>
<string name="error_canceled_by_user">ユーザにキャンセルされました</string>
<string name="error_canceled_by_other_peer">他のピアにキャンセルされました</string>

View File

@@ -73,7 +73,6 @@
<string name="battery_status_format">ელემენტი: %d%%</string>
<string name="battery_status_low_format">ელემენტი: %d%% ელემენტი დასატენია</string>
<string name="battery_status_charging_format">ელემენტი: %d%% იტენება</string>
<string name="battery_status_unknown">ელემენტის ინფორმაცია ხელმიუწვდომელია</string>
<string name="category_connected_devices">მიერთებული მოწყობილობები</string>
<string name="category_not_paired_devices">ხელმისაწვდომი მოწყობილობები</string>
<string name="category_remembered_devices">დამახსოვრებული მოწყობილობები</string>
@@ -83,7 +82,6 @@
<string name="unknown_device">უცნობი მოწყობილობა</string>
<string name="error_not_reachable">მოწყობილობა მიუწვდოელია</string>
<string name="error_already_paired">მოწყობილობა უკვე დაწყვილებულია</string>
<string name="error_could_not_send_package">პაკეტის გაგზავნა შეუძლებელია</string>
<string name="error_timed_out">ვადა გავიდა</string>
<string name="error_canceled_by_user">გაუქმებულია მომხმარებლის მიერ</string>
<string name="error_canceled_by_other_peer">გაუქმებულია პარტნიორის მიერ</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">배터리: %d%%</string>
<string name="battery_status_low_format">배터리: %d%% 배터리 부족</string>
<string name="battery_status_charging_format">배터리: %d%% 충전 중</string>
<string name="battery_status_unknown">배터리 정보를 사용할 수 없음</string>
<string name="category_connected_devices">연결된 장치</string>
<string name="category_not_paired_devices">사용 가능한 장치</string>
<string name="category_remembered_devices">기억하는 장치</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">알 수 없는 장치</string>
<string name="error_not_reachable">장치에 접근할 수 없음</string>
<string name="error_already_paired">장치가 이미 연결됨</string>
<string name="error_could_not_send_package">패키지를 보낼 수 없음</string>
<string name="error_timed_out">시간 초과됨</string>
<string name="error_canceled_by_user">사용자가 취소함</string>
<string name="error_canceled_by_other_peer">다른 쪽에서 취소함</string>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="activity_device_orientation">@integer/orientation_horizontal</integer>
<integer name="plugins_list_weight">4</integer>
<integer name="buttons_list_weight">6</integer>
<integer name="mpris_now_playing_orientation">@integer/orientation_horizontal</integer>
<integer name="mpris_now_playing_album_weight">1</integer>
<integer name="mpris_now_playing_controls_weight">1</integer>
<dimen name="mpris_now_playing_album_width">0dp</dimen>
<dimen name="mpris_now_playing_album_height">@dimen/layout_match_parent</dimen>
<dimen name="mpris_now_playing_controls_width">0dp</dimen>
<dimen name="mpris_now_playing_controls_height">@dimen/layout_match_parent</dimen>
</resources>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Akumuliatorius: %d%%</string>
<string name="battery_status_low_format">Akumuliatorius: %d%% baigia išsikrauti</string>
<string name="battery_status_charging_format">Akumuliatorius: %d%% įkraunamas</string>
<string name="battery_status_unknown">Informacija apie akumuliatorių neprieinama</string>
<string name="category_connected_devices">Prijungti įrenginiai</string>
<string name="category_not_paired_devices">Prieinami įrenginiai</string>
<string name="category_remembered_devices">Įsiminti įrenginiai</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Nežinomas įrenginys</string>
<string name="error_not_reachable">Įrenginys nepasiekiamas</string>
<string name="error_already_paired">Įrenginys jau suporuotas</string>
<string name="error_could_not_send_package">Nepavyko išsiųsti paketo</string>
<string name="error_timed_out">Pasibaigė skirtas laikas</string>
<string name="error_canceled_by_user">Naudotojas atsisakė</string>
<string name="error_canceled_by_other_peer">Lygiarangis atsisakė</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Batterij: %d%%</string>
<string name="battery_status_low_format">Batterij: %d%% lage batterij</string>
<string name="battery_status_charging_format">Batterij: %d%% opladen</string>
<string name="battery_status_unknown">Batterij-informatie niet beschikbaar</string>
<string name="category_connected_devices">Verbonden apparaten</string>
<string name="category_not_paired_devices">Beschikbare apparaten</string>
<string name="category_remembered_devices">Onthouden apparaten</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Onbekend apparaat</string>
<string name="error_not_reachable">Apparaat niet bereikbaar</string>
<string name="error_already_paired">Apparaat is al gepaard</string>
<string name="error_could_not_send_package">Kon pakket niet verzenden</string>
<string name="error_timed_out">Tijdslimiet overschreden</string>
<string name="error_canceled_by_user">Geannuleerd door gebruiker</string>
<string name="error_canceled_by_other_peer">Geannuleerd door andere kant</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Verwijderen</string>
<string name="sftp_no_storage_locations_configured">Geen opslaglocaties geconfigureerd</string>
<string name="sftp_saf_permission_explanation">Om toegang te hebben tot bestanden op afstand moet u opslaglocaties configureren</string>
<string name="sftp_manage_storage_permission_explanation">Om toegang tot bestanden op dit apparaat toe te staan moet u toestaan dat KDE Connect de opslag mag beheren.</string>
<string name="no_players_connected">Geen spelers gevonden</string>
<string name="send_files">Bestanden verzenden</string>
<string name="block_notification_contents">Inhoud van meldingen blokkeren</string>
@@ -245,6 +244,7 @@
<string name="close">Sluiten</string>
<string name="plugins_need_permission">Sommige plug-ins hebben toestemming nodig om te werken (tik voor meer informatie):</string>
<string name="permission_explanation">Deze plug-in heeft toestemming nodig om te werken</string>
<string name="all_permissions_granted">Alle toegangsrechten toegekend 🎉</string>
<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>

View File

@@ -109,7 +109,6 @@
<string name="unknown_device">Ukjend eining</string>
<string name="error_not_reachable">Får ikkje kontakt med eininga</string>
<string name="error_already_paired">Eininga er alt para</string>
<string name="error_could_not_send_package">Klarte ikkje senda pakke</string>
<string name="error_timed_out">Tidsavbrot</string>
<string name="error_canceled_by_user">Avbroten av brukar</string>
<string name="error_canceled_by_other_peer">Avbroten av den andre eininga</string>
@@ -219,6 +218,7 @@
<string name="sftp_action_mode_menu_delete">Slett</string>
<string name="sftp_no_storage_locations_configured">Ingen lagringsområde er sette opp</string>
<string name="sftp_saf_permission_explanation">For å få tilgang til filer over nettet må du setja opp lagringsområde.</string>
<string name="sftp_manage_storage_permission_explanation">For fjerntilgang til filer på denne eininga må du gje KDE Connect tilgangsløyve til lagringsområdet.</string>
<string name="no_players_connected">Fann ingen spelarar</string>
<string name="send_files">Send filer</string>
<string name="block_notification_contents">Blokker varslingsinnhald</string>
@@ -245,9 +245,10 @@
<string name="close">Lukk</string>
<string name="plugins_need_permission">Nokre av tillegga treng utvida løyva for å fungera (trykk på dei for meir informasjon):</string>
<string name="permission_explanation">Dette tillegget treng utvida løyve for å fungera</string>
<string name="all_permissions_granted">Alle tilgangsløyva er gjevne 🎉</string>
<string name="optional_permission_explanation">Du må gje utvida løyve for at alle funksjonane skal fungera</string>
<string name="plugins_need_optional_permission">På grunn av manglande løyve vil desse funksjonane ikkje verka (trykk på dei for meir informasjon):</string>
<string name="share_optional_permission_explanation">For å kunna ta imot delte filer må du velja ei målmappe</string>
<string name="share_optional_permission_explanation">For å kunna ta imot filer må du gje tilgangsløyve til lagringsområdet</string>
<string name="telepathy_permission_explanation">For å kunna lesa og skriva tekstmeldingar frå datamaskina må du gje appen tilgang til SMS</string>
<string name="telephony_permission_explanation">For å kunna sjå telefonsamtalar på datamaskina må du gje appen tilgang til samtaleloggar og telefonstatus</string>
<string name="telephony_optional_permission_explanation">For å kunna sjå namn på kontaktar i staden for berre telefonnummeret må du gje appen tilgang til kontaktlista di</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Bateria: %d%%</string>
<string name="battery_status_low_format">Bateria: %d%% niski poziom</string>
<string name="battery_status_charging_format">Bateria: %d%% ładowanie</string>
<string name="battery_status_unknown">Dane o baterii są niedostępne</string>
<string name="category_connected_devices">Podłączone urządzenia</string>
<string name="category_not_paired_devices">Dostępne urządzenia</string>
<string name="category_remembered_devices">Zapamiętane urządzenia</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Nieznane urządzenie</string>
<string name="error_not_reachable">Urządzenie nieosiągalne</string>
<string name="error_already_paired">Urządzenie już sparowano</string>
<string name="error_could_not_send_package">Nie można wysłać pakietu</string>
<string name="error_timed_out">Upłynął czas na odpowiedź</string>
<string name="error_canceled_by_user">Użytkownik zaniechał</string>
<string name="error_canceled_by_other_peer">Inny uczestnik zaniechał</string>

View File

@@ -94,7 +94,6 @@
<string name="battery_status_format">Bateria: %d%%</string>
<string name="battery_status_low_format">Bateria: %d%% bateria baixa</string>
<string name="battery_status_charging_format">Bateria: %d%% carregando</string>
<string name="battery_status_unknown">Informação de bateria não disponível</string>
<string name="category_connected_devices">Dispositivos conectados</string>
<string name="category_not_paired_devices">Dispositivos disponíveis</string>
<string name="category_remembered_devices">Dispositivos lembrados</string>
@@ -104,7 +103,6 @@
<string name="unknown_device">Dispositivo desconhecido</string>
<string name="error_not_reachable">Dispositivo inacessível</string>
<string name="error_already_paired">Dispositivo já emparelhado</string>
<string name="error_could_not_send_package">Não foi possível enviar o pacote</string>
<string name="error_timed_out">Tempo limite expirou</string>
<string name="error_canceled_by_user">Cancelado pelo usuário</string>
<string name="error_canceled_by_other_peer">Cancelado pelo outro dispositivo</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Bateria: %d%%</string>
<string name="battery_status_low_format">Bateria: %d%% Bateria Fraca</string>
<string name="battery_status_charging_format">Bateria: %d%% a carregar</string>
<string name="battery_status_unknown">A informação da bateria não está disponível</string>
<string name="category_connected_devices">Dispositivos ligados</string>
<string name="category_not_paired_devices">Dispositivos disponíveis</string>
<string name="category_remembered_devices">Dispositivos recordados</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Dispositivo desconhecido</string>
<string name="error_not_reachable">Dispositivo inacessível</string>
<string name="error_already_paired">O dispositivo já foi emparelhado</string>
<string name="error_could_not_send_package">Não foi possível enviar o pacote</string>
<string name="error_timed_out">Expirou o tempo-limite</string>
<string name="error_canceled_by_user">Cancelado pelo utilizador</string>
<string name="error_canceled_by_other_peer">Cancelado pela outra máquina</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Apagar</string>
<string name="sftp_no_storage_locations_configured">Não estão configurados locais de armazenamento</string>
<string name="sftp_saf_permission_explanation">Para aceder a ficheiros remotos, tem de configurar os locais de armazenamento</string>
<string name="sftp_manage_storage_permission_explanation">Para permitir o acesso remoto aos ficheiros neste dispositivo, precisa de autorizar o KDE Connect a gerir o armazenamento.</string>
<string name="no_players_connected">Não foram encontrados leitores</string>
<string name="send_files">Enviar os ficheiros</string>
<string name="block_notification_contents">Bloquear os conteúdos das notificações</string>
@@ -245,8 +244,10 @@
<string name="close">Fechar</string>
<string name="plugins_need_permission">Alguns \'plugins\' precisam de permissões para funcionar (toque para mais informações):</string>
<string name="permission_explanation">Este \'plugin\' precisa de permissões para funcionar</string>
<string name="all_permissions_granted">Todas as permissões concedidas 🎉</string>
<string name="optional_permission_explanation">Precisa de dar permissões extra para activar todas as funcionalidades</string>
<string name="plugins_need_optional_permission">Alguns \'plugins\' têm funcionalidades desactivadas devido à falta de permissões (toque para obter mais informações):</string>
<string name="share_optional_permission_explanation">Para receber os ficheiros, é preciso autorizar o acesso ao armazenamento</string>
<string name="telepathy_permission_explanation">Para ler e escrever SMS\'s a partir do seu ambiente de trabalho, precisa de dar permissões para os SMS\'s</string>
<string name="telephony_permission_explanation">Para ver as chamadas telefónicas a partir do seu ambiente de trabalho, precisa de dar permissões para o registo de chamadas telefónicas e do estado do telemóvel</string>
<string name="telephony_optional_permission_explanation">Para ver o nome de um contacto em vez do seu número de telefone, precisa de dar acesso aos contactos do telemóvel</string>

View File

@@ -98,7 +98,6 @@
<string name="battery_status_format">Acumulator: %d%%</string>
<string name="battery_status_low_format">Acumulator: %d%% Acumulator scăzut</string>
<string name="battery_status_charging_format">Acumulator: %d%% se încarcă</string>
<string name="battery_status_unknown">Nu sunt disponibile informații despre acumulator</string>
<string name="category_connected_devices">Dispozitive conectate</string>
<string name="category_not_paired_devices">Dispozitive disponibile</string>
<string name="category_remembered_devices">Dispozitive memorizate</string>
@@ -108,7 +107,6 @@
<string name="unknown_device">Dispozitiv necunoscut</string>
<string name="error_not_reachable">Dispozitivul nu e accesibil</string>
<string name="error_already_paired">Dispozitiv asociat deja</string>
<string name="error_could_not_send_package">Pachetul nu a putut fi trimis</string>
<string name="error_timed_out">A expirat</string>
<string name="error_canceled_by_user">Anulat de către utilizator</string>
<string name="error_canceled_by_other_peer">Anulat de către partener</string>

File diff suppressed because one or more lines are too long

View File

@@ -82,7 +82,6 @@
<string name="battery_status_format">Batéria: %d%%</string>
<string name="battery_status_low_format">Batéria: %d%% Nízka úroveň batérie</string>
<string name="battery_status_charging_format">Batéria: %d%% nabíja sa</string>
<string name="battery_status_unknown">Informácie o batérii nie sú dostupné</string>
<string name="category_connected_devices">Pripojené zariadenia</string>
<string name="category_not_paired_devices">Dostupné zariadenia</string>
<string name="category_remembered_devices">Zapamätané zariadenia</string>
@@ -92,7 +91,6 @@
<string name="unknown_device">Neznáme zariadenie</string>
<string name="error_not_reachable">Zariadenie nie je dosiahnuteľné</string>
<string name="error_already_paired">Zariadenie je už spárované</string>
<string name="error_could_not_send_package">Nepodarilo sa odoslať balík</string>
<string name="error_timed_out">Čas vypršal</string>
<string name="error_canceled_by_user">Zrušené používateľom</string>
<string name="error_canceled_by_other_peer">Zrušené druhým účastníkom</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Baterija: %d%%</string>
<string name="battery_status_low_format">Baterija: %d%% skoraj prazna</string>
<string name="battery_status_charging_format">Baterija: %d%% se polni</string>
<string name="battery_status_unknown">Ni podatkov o bateriji</string>
<string name="category_connected_devices">Povezane naprave</string>
<string name="category_not_paired_devices">Naprave na voljo</string>
<string name="category_remembered_devices">Naprave, ki so zapomnjene</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Neznana naprava</string>
<string name="error_not_reachable">Naprava ni dosegljiva</string>
<string name="error_already_paired">Naprava je že uparjena</string>
<string name="error_could_not_send_package">Ni bilo mogoče poslati paketa</string>
<string name="error_timed_out">Čas je potekel</string>
<string name="error_canceled_by_user">Preklical uporabnik</string>
<string name="error_canceled_by_other_peer">Preklican od drugega vrstnika</string>
@@ -235,6 +233,7 @@
<string name="sftp_action_mode_menu_delete">Briši</string>
<string name="sftp_no_storage_locations_configured">Lokacije shranjevanja niso nastavljene</string>
<string name="sftp_saf_permission_explanation">Za dostop do datotek na daljavo morate nastaviti lokacije za shranjevanje</string>
<string name="sftp_manage_storage_permission_explanation">Da bi dovolili oddaljeni dostop do datotek na tej napravi, morate dovoliti, da KDE Connect upravlja s hrambo.</string>
<string name="no_players_connected">Ni najdenih predvajalnikov</string>
<string name="send_files">Pošlji datoteke</string>
<string name="block_notification_contents">Blokiraj vsebine obvestil</string>
@@ -261,6 +260,7 @@
<string name="close">Zapri</string>
<string name="plugins_need_permission">Nekateri vtičniki potrebujejo dovoljenja za delovanje (tapnite za več informacij):</string>
<string name="permission_explanation">Ti vtičniki potrebujejo dovoljenja za delovanje</string>
<string name="all_permissions_granted">Podeljene vse pravice 🎉</string>
<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>

View File

@@ -98,7 +98,6 @@
<string name="battery_status_format">Batteri: %d %%</string>
<string name="battery_status_low_format">Batteri: %d %% låg laddning</string>
<string name="battery_status_charging_format">Batteri: %d %% laddas</string>
<string name="battery_status_unknown">Batteriinformation inte tillgänglig</string>
<string name="category_connected_devices">Anslutna apparater</string>
<string name="category_not_paired_devices">Tillgängliga apparater</string>
<string name="category_remembered_devices">Ihågkomna apparater</string>
@@ -108,7 +107,6 @@
<string name="unknown_device">Okänd apparat</string>
<string name="error_not_reachable">Apparaten kan inte nås</string>
<string name="error_already_paired">Apparat redan ihopparad</string>
<string name="error_could_not_send_package">Kunde inte skicka paket</string>
<string name="error_timed_out">Tidsgräns överskriden</string>
<string name="error_canceled_by_user">Avbruten av användaren</string>
<string name="error_canceled_by_other_peer">Avbruten av motparten</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">மின்கலம்: %d%%</string>
<string name="battery_status_low_format">மின்கலம்: %d%% குறைந்த மின்கலம்</string>
<string name="battery_status_charging_format">மின்கலம்: %d%% மின்னேறுகிறது</string>
<string name="battery_status_unknown">மின்கல விவரங்கள் கிடைக்கவில்லை</string>
<string name="category_connected_devices">இணைக்கப்பட்ட சாதனங்கள்</string>
<string name="category_not_paired_devices">கிட்டுகின்ற சாதனங்கள்</string>
<string name="category_remembered_devices">நினைவிலுள்ள சாதனங்கள்</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">தெரியாத சாதனம்</string>
<string name="error_not_reachable">சாதனத்தை கிட்ட முடியவில்லை</string>
<string name="error_already_paired">சாதனம் ஏற்கனவே இணைந்துள்ளது</string>
<string name="error_could_not_send_package">தொகுப்பை அனுப்ப முடியவில்லை</string>
<string name="error_timed_out">காலாவதி ஆகிவிட்டது</string>
<string name="error_canceled_by_user">பயனரால் ரத்து செய்யப்பட்டது</string>
<string name="error_canceled_by_other_peer">மறு சாதனத்தால் ரத்து செய்யப்பட்டது</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">அகற்று</string>
<string name="sftp_no_storage_locations_configured">தேக்கக இடங்கள் எதுவும் அமைக்கப்படவில்லை</string>
<string name="sftp_saf_permission_explanation">கோப்புகளை வேறு சாதனங்கலிருந்து அணுக நீங்கள் தேக்கக இடங்களை அமைக்க வேண்டும்</string>
<string name="sftp_manage_storage_permission_explanation">இச்சாதனத்திலுள்ள கோப்புகளை வேறு சாதனத்திலிருந்து அணுக, சேமிப்பகத்தை கையாளும் அனுமதியை நீங்கள் கே.டீ.யீ. கனெக்டுக்கு வழங்க வேண்டும்.</string>
<string name="no_players_connected">எந்த ஊடக இயக்கியும் கண்டுபிடிக்கப்படவில்லை</string>
<string name="send_files">கோப்புகளை அனுப்பு</string>
<string name="block_notification_contents">அறிவிப்புகளின் உள்ளடக்கத்தை காட்டாதே</string>
@@ -245,8 +244,10 @@
<string name="close">மூடு</string>
<string name="plugins_need_permission">சில செருகுநிரல்கள் இயங்க அனுமதிகள் தேவை (மேலும் விவரங்களுக்குத் தட்டவும்):</string>
<string name="permission_explanation">இச்செருகுநிரல் இயங்க அனுமதிகள் தேவை</string>
<string name="all_permissions_granted">அனைத்து அனுமதிகளும் வழங்கப்பட்டன</string>
<string name="optional_permission_explanation">எல்லா செயல்பாடுகளையும் இயக்க நீங்கள் கூடுதல் அனுமதிகளை வழங்க வேண்டும்</string>
<string name="plugins_need_optional_permission">அனுமதி இல்லாததால் சில செருகுநிரல்களின் அம்சங்கள் முடங்கியுள்ளன (மேலும் விவரங்களுக்கு தட்டவும்):</string>
<string name="share_optional_permission_explanation">கோப்புகளை பெற சேமிப்பக அனுமதி தேவைப்படலாம்</string>
<string name="telepathy_permission_explanation">உங்கள் மேசைக்கணினியிலிருந்து SMS எழுத மற்றும் படிக்க நீங்கள் SMS அனுமதியைத் தர வேண்டும்</string>
<string name="telephony_permission_explanation">மேசைக்கணினியிலிருந்து அழைப்புகளைக் காண நீங்கள் அழைப்பு வரலாறு மற்றும் தொலைபேசி நிலைக்கான அனுமதியைத் தர வேண்டும்</string>
<string name="telephony_optional_permission_explanation">தொலைபேசி எண்ணுக்குப் பதிலாக நபரின் பெயரைக் காண நீங்கள் தொடர்புகளை அணுகும் அனுமதியைத் தர வேண்டும்</string>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Pil: %d%%</string>
<string name="battery_status_low_format">Pil: %d%% Düşük pil</string>
<string name="battery_status_charging_format">Pil: %d%% Şarj oluyor</string>
<string name="battery_status_unknown">Pil bilgisi mevcut değil</string>
<string name="category_connected_devices">Bağlı aygıtlar</string>
<string name="category_not_paired_devices">Kullanılabilir aygıtlar</string>
<string name="category_remembered_devices">Hatırlanan aygıtlar</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Bİlinmeyen aygıt</string>
<string name="error_not_reachable">Aygıt ulaşılabilir değil</string>
<string name="error_already_paired">Aygıt zaten eşleşmiş</string>
<string name="error_could_not_send_package">Paket gönderilemedi</string>
<string name="error_timed_out">Zaman aşımı</string>
<string name="error_canceled_by_user">Kullanıcı tarafından iptal edildi</string>
<string name="error_canceled_by_other_peer">Diğer eş tarafından iptal edildi</string>
@@ -219,6 +217,7 @@
<string name="sftp_action_mode_menu_delete">Sil</string>
<string name="sftp_no_storage_locations_configured">Yapılandırılmış depolama yeri yok</string>
<string name="sftp_saf_permission_explanation">Dosyalara uzaktan erişmek için depolama konumlarını yapılandırmanız gerekir</string>
<string name="sftp_manage_storage_permission_explanation">Bu aygıttaki dosyalara uzak erişime izin vermek için KDE Bağlan\'a depolamayı yönetmesi için izin vermeniz gerekiyor.</string>
<string name="no_players_connected">Onatıcı bulunamadı</string>
<string name="send_files">Dosyaları gönder</string>
<string name="block_notification_contents">Bildirim içeriğini engelle</string>
@@ -245,6 +244,7 @@
<string name="close">Kapat</string>
<string name="plugins_need_permission">Bazı Eklentiler çalışmak için izne gereksinim duyar (daha fazla bilgi için dokunun):</string>
<string name="permission_explanation">Bu eklenti, çalışmak için izne gereksinim duyuyor</string>
<string name="all_permissions_granted">Tüm izinler verildi 🎉</string>
<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>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">Акумулятор: %d%%</string>
<string name="battery_status_low_format">Акумулятор: %d%%, низький заряд</string>
<string name="battery_status_charging_format">Акумулятор: %d%% (заряджається)</string>
<string name="battery_status_unknown">Дані щодо акумулятора недоступні</string>
<string name="category_connected_devices">З’єднані пристрої</string>
<string name="category_not_paired_devices">Доступні пристрої</string>
<string name="category_remembered_devices">Відомі пристрої</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">Невідомий пристрій</string>
<string name="error_not_reachable">Немає доступу до пристрою</string>
<string name="error_already_paired">Пристрій вже пов’язано</string>
<string name="error_could_not_send_package">Не вдалося надіслати пакунок</string>
<string name="error_timed_out">Час очікування вичерпано</string>
<string name="error_canceled_by_user">Скасовано користувачем</string>
<string name="error_canceled_by_other_peer">Скасовано з іншого вузла пов’язування</string>
@@ -235,6 +233,7 @@
<string name="sftp_action_mode_menu_delete">Вилучити</string>
<string name="sftp_no_storage_locations_configured">Не налаштовано розташувань сховищ</string>
<string name="sftp_saf_permission_explanation">Щоб отримувати віддалений доступ до файлів, вам слід налаштувати розташування сховищ</string>
<string name="sftp_manage_storage_permission_explanation">Щоб уможливити віддалений доступу до файлів на цьому пристрої, вам слід дозволити KDE Connect керувати сховищем даних.</string>
<string name="no_players_connected">Не знайдено програвачів</string>
<string name="send_files">Надіслати файли</string>
<string name="block_notification_contents">Блокувати вміст сповіщення</string>
@@ -261,6 +260,7 @@
<string name="close">Закрити</string>
<string name="plugins_need_permission">Для роботи деяких додатків потрібні додаткові права доступу (натисніть, щоб дізнатися більше):</string>
<string name="permission_explanation">Для роботи цього додатка потрібні додаткові права доступу</string>
<string name="all_permissions_granted">Надано усі права доступу 🎉</string>
<string name="optional_permission_explanation">Щоб уможливити використання усіх функцій, вам слід надати програмі додаткові права доступу</string>
<string name="plugins_need_optional_permission">Можливості деяких додатків вимкнено, оскільки програмі не вистачає прав доступу (натисніть, щоб дізнатися більше):</string>
<string name="share_optional_permission_explanation">Для отримання файлів вам слід дозволити доступ до сховища даних</string>

View File

@@ -7,4 +7,14 @@
</style>
<style name="KdeConnectTheme" parent="KdeConnectThemeBase.V27" />
<style name="PreferenceThemeOverlay" parent="BasePreferenceThemeOverlay">
<item name="preferenceCategoryTitleTextColor">?android:attr/colorAccent</item>
<!--Applying m3 style switch-->
<item name="switchPreferenceStyle">@style/Preference.SwitchPreferenceMaterial</item>
</style>
<style name="Preference.SwitchPreferenceMaterial" parent="Preference.SwitchPreference.Material">
<item name="android:widgetLayout">@layout/preference_widget_material_switch</item>
</style>
</resources>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="plugins_columns">3</integer>
</resources>

View File

@@ -99,7 +99,6 @@
<string name="battery_status_format">电池:%d%%</string>
<string name="battery_status_low_format">电池:%d%% 电量低</string>
<string name="battery_status_charging_format">电池:%d%% 正在充电</string>
<string name="battery_status_unknown">电池信息不可用</string>
<string name="category_connected_devices">已连接设备</string>
<string name="category_not_paired_devices">可用的设备</string>
<string name="category_remembered_devices">记住的设备</string>
@@ -109,7 +108,6 @@
<string name="unknown_device">未知设备</string>
<string name="error_not_reachable">设备不可及</string>
<string name="error_already_paired">设备已配对</string>
<string name="error_could_not_send_package">无法发送数据包</string>
<string name="error_timed_out">超时</string>
<string name="error_canceled_by_user">已被用户取消</string>
<string name="error_canceled_by_other_peer">已被其他对等点取消</string>
@@ -211,6 +209,7 @@
<string name="sftp_action_mode_menu_delete">删除</string>
<string name="sftp_no_storage_locations_configured">未配置存储位置</string>
<string name="sftp_saf_permission_explanation">要远程访问文件,您需要配置存储位置</string>
<string name="sftp_manage_storage_permission_explanation">要允许远程访问此设备上的文件,您必须允许 KDE Connect 管理它的存储。</string>
<string name="no_players_connected">未找到播放器</string>
<string name="send_files">发送文件</string>
<string name="block_notification_contents">屏蔽通知内容</string>
@@ -239,6 +238,7 @@
<string name="permission_explanation">这个插件需要权限才能工作</string>
<string name="optional_permission_explanation">您需要授予额外权限以启用全部功能</string>
<string name="plugins_need_optional_permission">因缺少权限,某些插件的一些功能已禁用(点击以查看更多信息):</string>
<string name="share_optional_permission_explanation">要接收文件,您必须允许存储访问权限</string>
<string name="telepathy_permission_explanation">从计算机桌面读取、写入短消息需要向应用程序授予 SMS 权限</string>
<string name="telephony_permission_explanation">要桌面上查看手机通话记录,您需要授予访问通话记录和手机状态的权限</string>
<string name="telephony_optional_permission_explanation">要查看联系人姓名而非电话号码,您需要授予访问手机通讯录的权限</string>

View File

@@ -83,7 +83,6 @@
<string name="unknown_device">不明的裝置</string>
<string name="error_not_reachable">裝置無法連結</string>
<string name="error_already_paired">裝置已經配對</string>
<string name="error_could_not_send_package">無法傳送封包</string>
<string name="error_timed_out">逾時</string>
<string name="error_canceled_by_user">使用者中斷</string>
<string name="error_canceled_by_other_peer">被其他同等功能應用中斷</string>

27
res/values/consts.xml Normal file
View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- https://developer.android.com/reference/android/R.attr.html#orientation -->
<integer name="orientation_horizontal">0</integer>
<integer name="orientation_vertical">1</integer>
<!-- https://developer.android.com/reference/android/view/ViewGroup.LayoutParams -->
<item name="layout_match_parent" type="dimen">-1</item>
<item name="layout_wrap_content" type="dimen">-2</item>
<!--used in activity_device-->
<integer name="activity_device_orientation">@integer/orientation_vertical</integer>
<integer name="plugins_list_weight">@null</integer>
<integer name="buttons_list_weight">@null</integer>
<integer name="plugins_columns">2</integer>
<!--used in mpris_now_playing-->
<integer name="mpris_now_playing_orientation">@integer/orientation_vertical</integer>
<integer name="mpris_now_playing_album_weight">4</integer>
<integer name="mpris_now_playing_controls_weight">@null</integer>
<dimen name="mpris_now_playing_album_width">@dimen/layout_match_parent</dimen>
<dimen name="mpris_now_playing_album_height">0dp</dimen>
<dimen name="mpris_now_playing_controls_width">@dimen/layout_match_parent</dimen>
<dimen name="mpris_now_playing_controls_height">@dimen/layout_wrap_content</dimen>
</resources>

View File

@@ -72,6 +72,7 @@
<string name="mousepad_acceleration_profile_key" translatable="false">mousepad_acceleration_profile_key</string>
<string name="mousepad_scroll_direction_title">Reverse Scrolling Direction</string>
<string name="mousepad_scroll_direction" translatable="false">mousepad_scroll_direction</string>
<string name="gyro_mouse_enabled" translatable="false">gyro_mouse_enabled</string>
<string-array name="mousepad_tap_entries">
<item>Left click</item>
<item>Right click</item>
@@ -147,7 +148,6 @@
<string name="battery_status_format">Battery: %d%%</string>
<string name="battery_status_low_format">Battery: %d%% Low Battery</string>
<string name="battery_status_charging_format">Battery: %d%% charging</string>
<string name="battery_status_unknown">Battery information not available</string>
<string name="category_connected_devices">Connected devices</string>
<string name="category_not_paired_devices">Available devices</string>
@@ -283,6 +283,7 @@
<string name="sftp_action_mode_menu_delete">Delete</string>
<string name="sftp_no_storage_locations_configured">No storage locations configured</string>
<string name="sftp_saf_permission_explanation">To access files remotely you have to configure storage locations</string>
<string name="sftp_manage_storage_permission_explanation">To allow remote access to files on this device you need to allow KDE Connect to manage the storage.</string>
<string name="no_players_connected">No players found</string>
<string name="send_files">Send files</string>
@@ -313,6 +314,7 @@
<string name="plugins_need_permission">Some Plugins need permissions to work (tap for more info):</string>
<string name="permission_explanation">This plugin needs permissions to work</string>
<string name="all_permissions_granted">All permissions granted 🎉</string>
<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>
@@ -464,8 +466,6 @@
<string name="website">Website</string>
<string name="website_url" translatable="false">https://kdeconnect.kde.org/</string>
<string name="copyright_statement" translatable="false">(С) 2013-2021 The KDE Connect Developers</string>
<string name="about">About</string>
<string name="authors">Authors</string>
<string name="thanks_to">Thanks To</string>
@@ -485,8 +485,6 @@
<string name="send_compose">Send</string>
<string name="open_compose_send">Compose text</string>
<string name="app_description">Multi-platform app that allows your devices to communicate (e.g., your phone and your computer)</string>
<string name="about_kde_about"><![CDATA[
<h1>About</h1>
<p>KDE is a world-wide community of software engineers, artists, writers, translators and creators who are committed to <a href="https://www.gnu.org/philosophy/free-sw.html">Free Software</a> development. KDE produces the Plasma desktop environment, hundreds of applications, and the many software libraries that support them.</p>

View File

@@ -1,6 +1,6 @@
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- NoActionBar because we use a Toolbar widget as ActionBar -->
<style name="KdeConnectThemeBase" parent="Theme.MaterialComponents.DayNight">
<style name="KdeConnectThemeBase" parent="Theme.Material3.DayNight.NoActionBar">
<!-- The main color attributes -->
<!-- The three colors used by system widgets, according to https://chris.banes.me/2014/10/17/appcompat-v21/ -->
<item name="colorPrimary">@color/primary</item>
@@ -26,6 +26,10 @@
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.DayNight</item>
<item name="materialCardViewStyle">@style/KdeConnectCardStyle</item>
<!-- https://github.com/material-components/material-components-android/issues/2732 -->
<item name="alertDialogTheme">@style/KdeConnectDialogStyle</item>
</style>
<style name="KdeConnectTheme" parent="KdeConnectThemeBase" />
@@ -41,6 +45,16 @@
<item name="android:background">@color/toolbar_color</item>
</style>
<style name="KdeConnectDialogStyle" parent="ThemeOverlay.Material3.MaterialAlertDialog">
<item name="android:layout" tools:ignore="PrivateResource">@layout/m3_alert_dialog</item>
<item name="dialogCornerRadius" tools:ignore="PrivateResource">@dimen/m3_alert_dialog_corner_size</item>
<item name="android:colorBackground">?colorSurface</item>
</style>
<style name="KdeConnectCardStyle" parent="@style/Widget.Material3.CardView.Elevated"/>
<style name="KdeConnectCardStyle.Filled" parent="@style/Widget.Material3.CardView.Filled"/>
<style name="MainNavigationView">
<item name="android:background">@drawable/state_list_drawer_background</item>
<item name="itemBackground">@drawable/state_list_drawer_background</item>
@@ -52,6 +66,16 @@
<item name="colorButtonNormal">@drawable/disableable_button</item>
</style>
<style name="KdeConnectButton.IconButton" parent="Widget.Material3.Button.IconButton.Filled">
<item name="iconGravity">textStart</item>
<item name="cornerRadius">24dp</item>
</style>
<style name="KdeConnectButton.IconButton.Secondary" parent="Widget.Material3.Button.IconButton.Filled.Tonal">
<item name="iconGravity">textStart</item>
<item name="cornerRadius">12dp</item>
</style>
<style name="ActionModeStyle" parent="Widget.AppCompat.ActionMode">
<item name="background">@color/primaryDark</item>
</style>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en-US"/>
<locale android:name="ar"/>
<locale android:name="ast"/>
<locale android:name="az"/>
<locale android:name="bg"/>
<locale android:name="bs"/>
<locale android:name="ca"/>
<locale android:name="cs"/>
<locale android:name="da"/>
<locale android:name="de"/>
<locale android:name="el"/>
<locale android:name="en-GB"/>
<locale android:name="es"/>
<locale android:name="et"/>
<locale android:name="eu"/>
<locale android:name="fi"/>
<locale android:name="fr"/>
<locale android:name="gl"/>
<locale android:name="he"/>
<locale android:name="hu"/>
<locale android:name="ia"/>
<locale android:name="id"/>
<locale android:name="in"/>
<locale android:name="is"/>
<locale android:name="it"/>
<locale android:name="iw"/>
<locale android:name="ja"/>
<locale android:name="ka"/>
<locale android:name="ko"/>
<locale android:name="lt"/>
<locale android:name="nl"/>
<locale android:name="nn"/>
<locale android:name="pl"/>
<locale android:name="pt"/>
<locale android:name="pt-BR"/>
<locale android:name="ro"/>
<locale android:name="ru"/>
<locale android:name="sk"/>
<locale android:name="sl"/>
<locale android:name="sr"/>
<locale android:name="sv"/>
<locale android:name="ta"/>
<locale android:name="tg"/>
<locale android:name="tr"/>
<locale android:name="uk"/>
<locale android:name="zh-CN"/>
<locale android:name="zh-TW"/>
</locale-config>

View File

@@ -50,19 +50,26 @@
android:summary="%s"
android:title="@string/mousepad_acceleration_profile_settings_title" />
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/mousepad_scroll_preference"
android:defaultValue="false"
android:key="@string/mousepad_scroll_direction"
android:title="@string/mousepad_scroll_direction_title" />
<SwitchPreference
android:id="@+id/gyro_mouse_enabled"
android:defaultValue="false"
android:key="@string/gyro_mouse_enabled"
android:title="Gyro mouse" />
<org.kde.kdeconnect.Helpers.LongSummaryPreferenceCategory
android:key="@string/sendkeystrokes_pref_category"
android:summary="@string/sendkeystrokes_pref_category_summary"
android:title="@string/sendkeystrokes_pref_category_title">
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/pref_keystrokes_enable"
android:defaultValue="true"
android:key="@string/pref_sendkeystrokes_enabled"
@@ -70,7 +77,7 @@
android:summary="@string/sendkeystrokes_pref_enabled_summary"
/>
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/pref_send_safe_text_immediately"
android:defaultValue="true"
android:key="@string/pref_send_safe_text_immediately"

View File

@@ -14,7 +14,7 @@
android:summary="@string/mpris_time_settings_summary"
android:title="@string/mpris_time_settings_title" />
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/mpris_notification_preference"
android:defaultValue="true"
android:key="@string/mpris_notification_key"

View File

@@ -1,3 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="180dp" android:minHeight="80dp"
android:initialLayout="@layout/widget_remotecommandplugin" android:resizeMode="horizontal|vertical" android:previewImage="@drawable/icon" />
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="180dp"
android:minHeight="80dp"
android:initialLayout="@layout/widget_remotecommandplugin"
android:resizeMode="horizontal|vertical"
android:previewImage="@drawable/remotecommand_widget_preview"
/>

View File

@@ -5,7 +5,7 @@
android:layout_height="match_parent"
tools:keep="@xml/remotekeyboardplugin_preferences">
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/remotekeyboard_editing_only"
android:defaultValue="true"
android:key="@string/remotekeyboard_editing_only"

View File

@@ -5,7 +5,7 @@
android:layout_height="match_parent"
tools:keep="@xml/shareplugin_preferences">
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/share_destination_customize"
android:defaultValue="false"
android:key="share_destination_custom"
@@ -18,7 +18,7 @@
android:key="share_destination_folder_preference"
android:title="@string/share_destination_folder_preference" />
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/share_notification_preference"
android:defaultValue="true"
android:key="share_notification_preference"

View File

@@ -5,13 +5,13 @@
android:layout_height="match_parent"
tools:keep="@xml/smsplugin_preferences">
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/group_message_preference"
android:defaultValue="true"
android:key="@string/set_group_message_as_mms"
android:title="@string/set_group_message_as_mms_title" />
<SwitchPreferenceCompat
<SwitchPreference
android:id="@+id/long_text_message_preference"
android:defaultValue="false"
android:key="@string/set_long_text_as_mms"

View File

@@ -19,6 +19,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.Binder;
import android.os.Build;
@@ -33,6 +34,7 @@ import androidx.core.content.ContextCompat;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect.Helpers.NotificationHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
@@ -62,7 +64,7 @@ public class BackgroundService extends Service {
private static BackgroundService instance;
public interface DeviceListChangedCallback {
void onDeviceListChanged();
void onDeviceListChanged(boolean isConnectedToNonCellularNetwork);
}
public interface PluginCallback<T extends Plugin> {
@@ -81,6 +83,8 @@ public class BackgroundService extends Service {
return instance;
}
boolean isConnectedToNonCellularNetwork; // True when connected over wifi/usb/bluetooth/(anything other than cellular)
private boolean acquireDiscoveryMode(Object key) {
boolean wasEmpty = discoveryModeAcquisitions.isEmpty();
discoveryModeAcquisitions.add(key);
@@ -128,10 +132,9 @@ public class BackgroundService extends Service {
public void onDeviceListChanged() {
for (DeviceListChangedCallback callback : deviceListChangedCallbacks.values()) {
callback.onDeviceListChanged();
callback.onDeviceListChanged(isConnectedToNonCellularNetwork);
}
if (NotificationHelper.isPersistentNotificationEnabled(this)) {
//Update the foreground notification with the currently connected device list
NotificationManager nm = ContextCompat.getSystemService(this, NotificationManager.class);
@@ -262,6 +265,8 @@ public class BackgroundService extends Service {
instance = this;
DeviceHelper.initializeDeviceId(this);
// Register screen on listener
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
// See: https://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION
@@ -270,16 +275,19 @@ public class BackgroundService extends Service {
}
registerReceiver(new KdeConnectBroadcastReceiver(), filter);
// Watch for changes on all network connections except cellular networks
NetworkRequest.Builder networkRequestBuilder = getNonCellularNetworkRequestBuilder();
ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
cm.registerNetworkCallback(builder.build(), new ConnectivityManager.NetworkCallback() {
cm.registerNetworkCallback(networkRequestBuilder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
isConnectedToNonCellularNetwork = true;
onDeviceListChanged();
onNetworkChange();
}
@Override
public void onLost(Network network) {
isConnectedToNonCellularNetwork = false;
onDeviceListChanged();
}
});
@@ -301,6 +309,22 @@ public class BackgroundService extends Service {
}
}
private static NetworkRequest.Builder getNonCellularNetworkRequestBuilder() {
NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE);
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S) {
networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_USB)
.addTransportType(NetworkCapabilities.TRANSPORT_LOWPAN);
}
return networkRequestBuilder;
}
private void migratePluginSettings() {
SharedPreferences globalPrefs = PreferenceManager.getDefaultSharedPreferences(this);

View File

@@ -735,7 +735,7 @@ public class Device implements BaseLink.PacketReceiver {
Plugin existing = plugins.get(pluginKey);
if (existing != null) {
if (existing.isIncompatible()) {
if (!existing.isCompatible()) {
Log.i("KDE/addPlugin", "Minimum requirements (e.g. API level) not fulfilled " + pluginKey);
return false;
}
@@ -757,7 +757,7 @@ public class Device implements BaseLink.PacketReceiver {
return false;
}
if (plugin.isIncompatible()) {
if (!plugin.isCompatible()) {
Log.i("KDE/addPlugin", "Minimum requirements (e.g. API level) not fulfilled " + pluginKey);
return false;
}

View File

@@ -6,6 +6,7 @@
package org.kde.kdeconnect.Helpers;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
@@ -18,11 +19,15 @@ import com.jaredrummler.android.device.DeviceName;
import org.kde.kdeconnect.Device;
import java.util.Set;
import java.util.UUID;
public class DeviceHelper {
public static final int ProtocolVersion = 7;
public static final String KEY_DEVICE_NAME_PREFERENCE = "device_name_preference";
public static final String KEY_DEVICE_ID_PREFERENCE = "device_id_preference";
private static boolean fetchingName = false;
@@ -53,6 +58,7 @@ public class DeviceHelper {
// Could use preferences.contains but would need to check for empty String anyway.
String deviceName = preferences.getString(KEY_DEVICE_NAME_PREFERENCE, "");
if (deviceName.isEmpty()) {
//DeviceName.init(context); // Needed in DeviceName 2.x +
if (!fetchingName) {
fetchingName = true;
DeviceHelper.backgroundFetchDeviceName(context); //Starts a background thread that will eventually update the shared pref
@@ -83,7 +89,30 @@ public class DeviceHelper {
preferences.edit().putString(KEY_DEVICE_NAME_PREFERENCE, name).apply();
}
public static String getDeviceId(Context context) {
return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
@SuppressLint("HardwareIds")
public static void initializeDeviceId(Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Set<String> preferenceKeys = preferences.getAll().keySet();
if (preferenceKeys.contains(KEY_DEVICE_ID_PREFERENCE)) {
return; // We already have an ID
}
String deviceName;
if (preferenceKeys.isEmpty()) {
// For new installations, use random IDs
Log.i("DeviceHelper", "No device ID found and this looks like a new installation, creating a random ID");
deviceName = UUID.randomUUID().toString().replace('-','_');
} else {
// Use the ANDROID_ID as device ID for existing installations, for backwards compatibility
Log.i("DeviceHelper", "No device ID found but this seems an existing installation, using the Android ID");
deviceName = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
preferences.edit().putString(KEY_DEVICE_ID_PREFERENCE, deviceName).apply();
}
public static String getDeviceId(Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(KEY_DEVICE_ID_PREFERENCE, null);
}
}

View File

@@ -14,23 +14,20 @@ import android.preference.PreferenceManager;
import android.util.Base64;
import android.util.Log;
import org.apache.commons.lang3.ArrayUtils;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect.Helpers.RandomHelper;
import org.spongycastle.asn1.x500.RDN;
import org.spongycastle.asn1.x500.X500Name;
import org.spongycastle.asn1.x500.X500NameBuilder;
import org.spongycastle.asn1.x500.style.BCStyle;
import org.spongycastle.asn1.x500.style.IETFUtils;
import org.spongycastle.cert.X509CertificateHolder;
import org.spongycastle.cert.X509v3CertificateBuilder;
import org.spongycastle.cert.jcajce.JcaX509CertificateConverter;
import org.spongycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.operator.ContentSigner;
import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
import org.spongycastle.util.Arrays;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.style.IETFUtils;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.util.Arrays;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.Socket;
@@ -43,11 +40,11 @@ import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.Formatter;
import java.util.Locale;
@@ -63,9 +60,15 @@ import javax.security.auth.x500.X500Principal;
public class SslHelper {
public static X509Certificate certificate; //my device's certificate
public final static BouncyCastleProvider BC = new BouncyCastleProvider();
public static Certificate certificate; //my device's certificate
private static CertificateFactory factory;
static {
try {
factory = CertificateFactory.getInstance("X.509");
} catch (CertificateException e) {
throw new RuntimeException(e);
}
}
private final static TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
@@ -103,8 +106,7 @@ public class SslHelper {
try {
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
byte[] certificateBytes = Base64.decode(globalSettings.getString("certificate", ""), 0);
X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes);
X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder);
X509Certificate cert = (X509Certificate) parseCertificate(certificateBytes);
String certDeviceId = getCommonNameFromCertificate(cert);
if (!certDeviceId.equals(deviceId)) {
@@ -145,11 +147,12 @@ public class SslHelper {
nameBuilder.build(),
publicKey
);
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(privateKey);
certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateBuilder.build(contentSigner));
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
byte[] certificateBytes = certificateBuilder.build(contentSigner).getEncoded();
certificate = parseCertificate(certificateBytes);
SharedPreferences.Editor edit = settings.edit();
edit.putString("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
edit.putString("certificate", Base64.encodeToString(certificateBytes, 0));
edit.apply();
setLocale(initialLocale, context);
@@ -180,12 +183,11 @@ public class SslHelper {
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
// Get remote device certificate if trusted
X509Certificate remoteDeviceCertificate = null;
Certificate remoteDeviceCertificate = null;
if (isDeviceTrusted) {
SharedPreferences devicePreferences = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
byte[] certificateBytes = Base64.decode(devicePreferences.getString("certificate", ""), 0);
X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes);
remoteDeviceCertificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder);
remoteDeviceCertificate = parseCertificate(certificateBytes);
}
// Setup keystore
@@ -257,9 +259,8 @@ public class SslHelper {
return formatter.toString();
}
public static Certificate parseCertificate(byte[] certificateBytes) throws IOException, CertificateException {
X509CertificateHolder certificateHolder = new X509CertificateHolder(certificateBytes);
return new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder);
public static Certificate parseCertificate(byte[] certificateBytes) throws CertificateException {
return factory.generateCertificate(new ByteArrayInputStream(certificateBytes));
}
private static String getCommonNameFromCertificate(X509Certificate cert) {
@@ -269,7 +270,7 @@ public class SslHelper {
return IETFUtils.valueToString(rdn.getFirst().getValue());
}
public static String getVerificationKey(X509Certificate certificateA, Certificate certificateB) {
public static String getVerificationKey(Certificate certificateA, Certificate certificateB) {
try {
byte[] a = certificateA.getPublicKey().getEncoded();
byte[] b = certificateB.getPublicKey().getEncoded();

View File

@@ -1,12 +1,15 @@
package org.kde.kdeconnect;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import androidx.multidex.MultiDexApplication;
public class MyApplication extends MultiDexApplication {
import org.kde.kdeconnect.UserInterface.ThemeUtil;
public class MyApplication extends Application {
private static class LifecycleObserver implements DefaultLifecycleObserver {
private boolean inForeground = false;
@@ -30,7 +33,7 @@ public class MyApplication extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
ThemeUtil.setUserPreferredTheme(this);
ProcessLifecycleOwner.get().getLifecycle().addObserver(foregroundTracker);
}

View File

@@ -34,7 +34,6 @@ public class BigscreenActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
final ActivityBigscreenBinding binding = ActivityBigscreenBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

View File

@@ -32,14 +32,13 @@ public class BigscreenPlugin extends Plugin {
private final static String PACKET_TYPE_BIGSCREEN_STT = "kdeconnect.bigscreen.stt";
@Override
public boolean isIncompatible() {
return !device.getDeviceType().equals(Device.DeviceType.Tv) || super.isIncompatible();
public boolean isCompatible() {
return device.getDeviceType().equals(Device.DeviceType.Tv) && super.isCompatible();
}
@Override
public boolean onCreate() {
optionalPermissionExplanation = R.string.bigscreen_optional_permission_explanation;
return true;
protected int getOptionalPermissionExplanation() {
return R.string.bigscreen_optional_permission_explanation;
}
@Override

View File

@@ -92,10 +92,8 @@ public class ContactsPlugin extends Plugin {
}
@Override
public boolean onCreate() {
permissionExplanation = R.string.contacts_permission_explanation;
return true;
protected int getPermissionExplanation() {
return R.string.contacts_permission_explanation;
}
@Override

View File

@@ -26,7 +26,6 @@ public class FindMyPhoneActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
final ActivityFindMyPhoneBinding binding = ActivityFindMyPhoneBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

View File

@@ -33,7 +33,6 @@ public class ComposeSendActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_compose_send);

View File

@@ -16,9 +16,14 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.hardware.SensorManager;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.hardware.Sensor;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import java.util.List;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
@@ -29,7 +34,7 @@ import org.kde.kdeconnect_tp.R;
import java.util.Objects;
public class MousePadActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, MousePadGestureDetector.OnGestureListener {
public class MousePadActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, MousePadGestureDetector.OnGestureListener, SensorEventListener {
private String deviceId;
private final static float MinDistanceToSendScroll = 2.5f; // touch gesture scroll
@@ -43,11 +48,13 @@ public class MousePadActivity extends AppCompatActivity implements GestureDetect
private float mCurrentSensitivity;
private float displayDpiMultiplier;
private int scrollDirection = 1;
private boolean allowGyro = false;
private boolean gyroEnabled = false;
private boolean isScrolling = false;
private float accumulatedDistanceY = 0;
private GestureDetector mDetector;
private SensorManager mSensorManager;
private MousePadGestureDetector mMousePadGestureDetector;
private PointerAccelerationProfile mPointerAccelerationProfile;
@@ -74,10 +81,40 @@ public class MousePadActivity extends AppCompatActivity implements GestureDetect
private ClickType singleTapAction, doubleTapAction, tripleTapAction;
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
float X = -values[2] * 70 * mCurrentSensitivity * displayDpiMultiplier;
float Y = -values[0] * 70 * mCurrentSensitivity * displayDpiMultiplier;
if (X < 0.25 && X > -0.25) {
X = 0;
} else {
X = X * mCurrentSensitivity * displayDpiMultiplier;
}
if (Y < 0.25 && Y > -0.25) {
Y = 0;
} else {
Y = Y * mCurrentSensitivity * displayDpiMultiplier;
}
final float nX = X;
final float nY = Y;
BackgroundService.RunWithPlugin(this, deviceId, MousePadPlugin.class, plugin -> {
plugin.sendMouseDelta(nX, nY);
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_mousepad);
@@ -92,6 +129,7 @@ public class MousePadActivity extends AppCompatActivity implements GestureDetect
mDetector = new GestureDetector(this, this);
mMousePadGestureDetector = new MousePadGestureDetector(this);
mDetector.setOnDoubleTapListener(this);
mSensorManager = ContextCompat.getSystemService(this, SensorManager.class);
keyListenerView = findViewById(R.id.keyListener);
keyListenerView.setDeviceId(deviceId);
@@ -102,6 +140,9 @@ public class MousePadActivity extends AppCompatActivity implements GestureDetect
} else {
scrollDirection = 1;
}
if ((prefs.getBoolean(getString(R.string.gyro_mouse_enabled), false)) && (mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null)) {
allowGyro = true;
}
String singleTapSetting = prefs.getString(getString(R.string.mousepad_single_tap_key),
getString(R.string.mousepad_default_single));
String doubleTapSetting = prefs.getString(getString(R.string.mousepad_double_tap_key),
@@ -123,7 +164,6 @@ public class MousePadActivity extends AppCompatActivity implements GestureDetect
//Technically xdpi and ydpi should be handled separately,
//but since ydpi is usually almost equal to xdpi, only xdpi is used for the multiplier.
displayDpiMultiplier = StandardDpi / getResources().getDisplayMetrics().xdpi;
switch (sensitivitySetting) {
case "slowest":
mCurrentSensitivity = 0.2f;
@@ -158,7 +198,32 @@ public class MousePadActivity extends AppCompatActivity implements GestureDetect
getWindow().getDecorView().setSystemUiVisibility(fullscreenType);
}
});
}
@Override
protected void onResume() {
if (allowGyro == true && gyroEnabled == false) {
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
gyroEnabled = true;
}
super.onResume();
}
@Override
protected void onPause() {
if (gyroEnabled == true) {
mSensorManager.unregisterListener(this);
gyroEnabled = false;
}
super.onPause();
}
@Override protected void onStop() {
if (gyroEnabled == true) {
mSensorManager.unregisterListener(this);
gyroEnabled = false;
}
super.onStop();
}
@Override
@@ -244,6 +309,8 @@ public class MousePadActivity extends AppCompatActivity implements GestureDetect
mPrevX = mCurrentX;
mPrevY = mCurrentY;
});
break;
}
return true;

View File

@@ -48,7 +48,6 @@ public class SendKeystrokesToHostActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
binding = ActivitySendkeystrokesBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
@@ -80,7 +79,7 @@ public class SendKeystrokesToHostActivity extends AppCompatActivity {
// device is connected and send the text to it without user confirmation, to make sending of
// short and safe text like PINs/TANs very fluent
//
// (contentIsOkay gets used in updateComputerList again)
// (contentIsOkay gets used in updateDeviceList again)
if (prefs.getBoolean(getString(R.string.pref_send_safe_text_immediately), true)) {
SafeTextChecker safeTextChecker = new SafeTextChecker(SAFE_CHARS, MAX_SAFE_LENGTH);
contentIsOkay = safeTextChecker.isSafe(toSend);
@@ -108,11 +107,11 @@ public class SendKeystrokesToHostActivity extends AppCompatActivity {
// subscribe to new connected devices
BackgroundService.RunCommand(this, service -> {
service.onNetworkChange();
service.addDeviceListChangedCallback("SendKeystrokesToHostActivity", this::updateComputerList);
service.addDeviceListChangedCallback("SendKeystrokesToHostActivity", unused -> updateDeviceList());
});
// list all currently connected devices
updateComputerList();
updateDeviceList();
} else {
Toast.makeText(getApplicationContext(), R.string.sendkeystrokes_wrong_data, Toast.LENGTH_LONG).show();
@@ -143,7 +142,7 @@ public class SendKeystrokesToHostActivity extends AppCompatActivity {
}
private void updateComputerList() {
private void updateDeviceList() {
BackgroundService.RunCommand(this, service -> {
Collection<Device> devices = service.getDevices().values();

View File

@@ -16,6 +16,7 @@ import androidx.fragment.app.DialogFragment;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.Plugins.RemoteKeyboardPlugin.RemoteKeyboardPlugin;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect.UserInterface.StartActivityAlertDialogFragment;
import org.kde.kdeconnect_tp.R;
@@ -58,10 +59,14 @@ public class MouseReceiverPlugin extends Plugin {
@Override
public boolean onPacketReceived(NetworkPacket np) {
if (!np.getType().equals(PACKET_TYPE_MOUSEPAD_REQUEST)) {
Log.e("MouseReceiverPlugin", "cannot receive packets of type: " + np.getType());
Log.e("MouseReceiverPlugin", "Invalid packet type for MouseReceiverPlugin: " + np.getType());
return false;
}
if (RemoteKeyboardPlugin.getMousePadPacketType(np) != RemoteKeyboardPlugin.MousePadPacketType.Mouse) {
return false; // This packet will be handled by the RemoteKeyboardPlugin instead, silently ignore
}
double dx = np.getDouble("dx", 0);
double dy = np.getDouble("dy", 0);

View File

@@ -63,7 +63,6 @@ public class MprisActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
activityMprisBinding = ActivityMprisBinding.inflate(getLayoutInflater());

View File

@@ -14,9 +14,6 @@ import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
import android.service.notification.StatusBarNotification;
import android.support.v4.media.MediaMetadataCompat;
@@ -77,13 +74,6 @@ public class MprisMediaSession implements
private Context context;
private MediaSessionCompat mediaSession;
//Callback for mpris plugin updates
private final Handler mediaNotificationHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
updateMediaNotification();
}
};
//Callback for control via the media session API
private final MediaSessionCompat.Callback mediaSessionCallback = new MediaSessionCompat.Callback() {
@Override
@@ -134,8 +124,8 @@ public class MprisMediaSession implements
context = _context;
mprisDevices.add(device);
mpris.setPlayerListUpdatedHandler("media_notification", mediaNotificationHandler);
mpris.setPlayerStatusUpdatedHandler("media_notification", mediaNotificationHandler);
mpris.setPlayerListUpdatedHandler("media_notification", this::updateMediaNotification);
mpris.setPlayerStatusUpdatedHandler("media_notification", this::updateMediaNotification);
NotificationReceiver.RunCommand(context, service -> {

View File

@@ -9,7 +9,6 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -213,80 +212,71 @@ public class MprisNowPlayingFragment extends Fragment implements VolumeKeyListen
BackgroundService.RunWithPlugin(requireContext(), deviceId, MprisPlugin.class, mpris -> {
targetPlayer = mpris.getPlayerStatus(targetPlayerName);
mpris.setPlayerStatusUpdatedHandler("activity", new Handler() {
@Override
public void handleMessage(Message msg) {
requireActivity().runOnUiThread(() -> updatePlayerStatus(mpris));
}
});
mpris.setPlayerStatusUpdatedHandler("activity", () -> requireActivity().runOnUiThread(() -> updatePlayerStatus(mpris)));
mpris.setPlayerListUpdatedHandler("activity", () -> {
final List<String> playerList = mpris.getPlayerList();
final ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(),
android.R.layout.simple_spinner_item,
playerList.toArray(ArrayUtils.EMPTY_STRING_ARRAY)
);
mpris.setPlayerListUpdatedHandler("activity", new Handler() {
@Override
public void handleMessage(Message msg) {
final List<String> playerList = mpris.getPlayerList();
final ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(),
android.R.layout.simple_spinner_item,
playerList.toArray(ArrayUtils.EMPTY_STRING_ARRAY)
);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
requireActivity().runOnUiThread(() -> {
mprisControlBinding.playerSpinner.setAdapter(adapter);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
requireActivity().runOnUiThread(() -> {
mprisControlBinding.playerSpinner.setAdapter(adapter);
if (playerList.isEmpty()) {
mprisControlBinding.noPlayers.setVisibility(View.VISIBLE);
mprisControlBinding.playerSpinner.setVisibility(View.GONE);
mprisControlBinding.nowPlayingTextview.setText("");
} else {
mprisControlBinding.noPlayers.setVisibility(View.GONE);
mprisControlBinding.playerSpinner.setVisibility(View.VISIBLE);
}
if (playerList.isEmpty()) {
mprisControlBinding.noPlayers.setVisibility(View.VISIBLE);
mprisControlBinding.playerSpinner.setVisibility(View.GONE);
mprisControlBinding.nowPlayingTextview.setText("");
} else {
mprisControlBinding.noPlayers.setVisibility(View.GONE);
mprisControlBinding.playerSpinner.setVisibility(View.VISIBLE);
}
mprisControlBinding.playerSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int pos, long id) {
mprisControlBinding.playerSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int pos, long id) {
if (pos >= playerList.size()) return;
if (pos >= playerList.size()) return;
String player = playerList.get(pos);
if (targetPlayer != null && player.equals(targetPlayer.getPlayer())) {
return; //Player hasn't actually changed
}
targetPlayer = mpris.getPlayerStatus(player);
updatePlayerStatus(mpris);
if (targetPlayer != null && targetPlayer.isPlaying()) {
MprisMediaSession.getInstance().playerSelected(targetPlayer);
}
String player = playerList.get(pos);
if (targetPlayer != null && player.equals(targetPlayer.getPlayer())) {
return; //Player hasn't actually changed
}
targetPlayer = mpris.getPlayerStatus(player);
updatePlayerStatus(mpris);
@Override
public void onNothingSelected(AdapterView<?> arg0) {
targetPlayer = null;
}
});
if (targetPlayer == null) {
//If no player is selected, try to select a playing player
targetPlayer = mpris.getPlayingPlayer();
}
//Try to select the specified player
if (targetPlayer != null) {
int targetIndex = adapter.getPosition(targetPlayer.getPlayer());
if (targetIndex >= 0) {
mprisControlBinding.playerSpinner.setSelection(targetIndex);
} else {
targetPlayer = null;
if (targetPlayer != null && targetPlayer.isPlaying()) {
MprisMediaSession.getInstance().playerSelected(targetPlayer);
}
}
//If no player selected, select the first one (if any)
if (targetPlayer == null && !playerList.isEmpty()) {
targetPlayer = mpris.getPlayerStatus(playerList.get(0));
mprisControlBinding.playerSpinner.setSelection(0);
@Override
public void onNothingSelected(AdapterView<?> arg0) {
targetPlayer = null;
}
updatePlayerStatus(mpris);
});
}
if (targetPlayer == null) {
//If no player is selected, try to select a playing player
targetPlayer = mpris.getPlayingPlayer();
}
//Try to select the specified player
if (targetPlayer != null) {
int targetIndex = adapter.getPosition(targetPlayer.getPlayer());
if (targetIndex >= 0) {
mprisControlBinding.playerSpinner.setSelection(targetIndex);
} else {
targetPlayer = null;
}
}
//If no player selected, select the first one (if any)
if (targetPlayer == null && !playerList.isEmpty()) {
targetPlayer = mpris.getPlayerStatus(playerList.get(0));
mprisControlBinding.playerSpinner.setSelection(0);
}
updatePlayerStatus(mpris);
});
});
});
}
@@ -343,31 +333,31 @@ public class MprisNowPlayingFragment extends Fragment implements VolumeKeyListen
}
boolean isPlaying = playerStatus.isPlaying();
if (isPlaying) {
mprisControlBinding.playButton.setImageResource(R.drawable.ic_pause_black);
mprisControlBinding.playButton.setIconResource(R.drawable.ic_pause_black);
mprisControlBinding.playButton.setEnabled(playerStatus.isPauseAllowed());
} else {
mprisControlBinding.playButton.setImageResource(R.drawable.ic_play_black);
mprisControlBinding.playButton.setIconResource(R.drawable.ic_play_black);
mprisControlBinding.playButton.setEnabled(playerStatus.isPlayAllowed());
}
String loopStatus = playerStatus.getLoopStatus();
switch (loopStatus) {
case "None":
mprisControlBinding.loopButton.setImageResource(R.drawable.ic_loop_none_black);
mprisControlBinding.loopButton.setIconResource(R.drawable.ic_loop_none_black);
break;
case "Track":
mprisControlBinding.loopButton.setImageResource(R.drawable.ic_loop_track_black);
mprisControlBinding.loopButton.setIconResource(R.drawable.ic_loop_track_black);
break;
case "Playlist":
mprisControlBinding.loopButton.setImageResource(R.drawable.ic_loop_playlist_black);
mprisControlBinding.loopButton.setIconResource(R.drawable.ic_loop_playlist_black);
break;
}
boolean shuffle = playerStatus.getShuffle();
if (shuffle) {
mprisControlBinding.shuffleButton.setImageResource(R.drawable.ic_shuffle_on_black);
mprisControlBinding.shuffleButton.setIconResource(R.drawable.ic_shuffle_on_black);
} else {
mprisControlBinding.shuffleButton.setImageResource(R.drawable.ic_shuffle_off_black);
mprisControlBinding.shuffleButton.setIconResource(R.drawable.ic_shuffle_off_black);
}
mprisControlBinding.loopButton.setVisibility(playerStatus.isLoopStatusAllowed() ? View.VISIBLE : View.GONE);

View File

@@ -227,14 +227,18 @@ public class MprisPlugin extends Plugin {
}
}
public interface Callback {
void callback();
}
public final static String DEVICE_ID_KEY = "deviceId";
private final static String PACKET_TYPE_MPRIS = "kdeconnect.mpris";
private final static String PACKET_TYPE_MPRIS_REQUEST = "kdeconnect.mpris.request";
private final ConcurrentHashMap<String, MprisPlayer> players = new ConcurrentHashMap<>();
private boolean supportAlbumArtPayload = false;
private final HashMap<String, Handler> playerStatusUpdated = new HashMap<>();
private final HashMap<String, Handler> playerListUpdated = new HashMap<>();
private final ConcurrentHashMap<String, Callback> playerStatusUpdated = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Callback> playerListUpdated = new ConcurrentHashMap<>();
@Override
public String getDisplayName() {
@@ -349,7 +353,7 @@ public class MprisPlugin extends Plugin {
for (String key : playerStatusUpdated.keySet()) {
try {
playerStatusUpdated.get(key).dispatchMessage(new Message());
playerStatusUpdated.get(key).callback();
} catch (Exception e) {
Log.e("MprisControl", "Exception", e);
playerStatusUpdated.remove(key);
@@ -390,7 +394,7 @@ public class MprisPlugin extends Plugin {
if (!equals) {
for (String key : playerListUpdated.keySet()) {
try {
playerListUpdated.get(key).dispatchMessage(new Message());
playerListUpdated.get(key).callback();
} catch (Exception e) {
Log.e("MprisControl", "Exception", e);
playerListUpdated.remove(key);
@@ -412,20 +416,19 @@ public class MprisPlugin extends Plugin {
return new String[]{PACKET_TYPE_MPRIS_REQUEST};
}
public void setPlayerStatusUpdatedHandler(String id, Handler h) {
public void setPlayerStatusUpdatedHandler(String id, Callback h) {
playerStatusUpdated.put(id, h);
h.dispatchMessage(new Message());
h.callback();
}
public void removePlayerStatusUpdatedHandler(String id) {
playerStatusUpdated.remove(id);
}
public void setPlayerListUpdatedHandler(String id, Handler h) {
public void setPlayerListUpdatedHandler(String id, Callback h) {
playerListUpdated.put(id, h);
h.dispatchMessage(new Message());
h.callback();
}
public void removePlayerListUpdatedHandler(String id) {
@@ -500,7 +503,7 @@ public class MprisPlugin extends Plugin {
if (players.values().stream().anyMatch(player -> url.equals(player.albumArtUrl))) {
for (String key : playerStatusUpdated.keySet()) {
try {
playerStatusUpdated.get(key).dispatchMessage(new Message());
playerStatusUpdated.get(key).callback();
} catch (Exception e) {
Log.e("MprisControl", "Exception", e);
playerStatusUpdated.remove(key);

View File

@@ -29,7 +29,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.widget.TextViewCompat;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.materialswitch.MaterialSwitch;
import org.kde.kdeconnect.Helpers.ThreadHelper;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
@@ -96,7 +96,6 @@ public class NotificationFilterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
binding = ActivityNotificationFilterBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
@@ -135,7 +134,7 @@ public class NotificationFilterActivity extends AppCompatActivity {
}
private void configureSwitch(SharedPreferences sharedPreferences) {
SwitchMaterial smScreenOffNotification = findViewById(R.id.smScreenOffNotification);
MaterialSwitch smScreenOffNotification = findViewById(R.id.smScreenOffNotification);
smScreenOffNotification.setChecked(
sharedPreferences.getBoolean(getString(NotificationsPlugin.PREF_NOTIFICATION_SCREEN_OFF),false)
);

View File

@@ -107,10 +107,6 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
@Override
public boolean checkRequiredPermissions() {
//Notifications use a different kind of permission, because it was added before the current runtime permissions model
return hasPermission();
}
private boolean hasPermission() {
String notificationListenerList = Settings.Secure.getString(context.getContentResolver(), "enabled_notification_listeners");
return StringUtils.contains(notificationListenerList, context.getPackageName());
}
@@ -118,8 +114,6 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
@Override
public boolean onCreate() {
if (!hasPermission()) return false;
pendingIntents = new HashMap<>();
currentNotifications = new HashSet<>();
actions = new ArrayListValuedHashMap<>();
@@ -177,14 +171,16 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
public void onNotificationPosted(StatusBarNotification statusBarNotification) {
if (sharedPreferences != null && sharedPreferences.getBoolean(context.getString(PREF_NOTIFICATION_SCREEN_OFF),false)){
if (keyguardManager != null && keyguardManager.inKeyguardRestrictedInputMode()){
sendNotification(statusBarNotification);
sendNotification(statusBarNotification, false);
}
}else {
sendNotification(statusBarNotification);
sendNotification(statusBarNotification, false);
}
}
private void sendNotification(StatusBarNotification statusBarNotification) {
// isPreexisting is true for notifications that we are sending in response to a request command
// and that we want to send with the "silent" flag set
private void sendNotification(StatusBarNotification statusBarNotification, boolean isPreexisting) {
Notification notification = statusBarNotification.getNotification();
@@ -248,6 +244,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
np.set("isClearable", statusBarNotification.isClearable());
np.set("appName", StringUtils.defaultString(appName, packageName));
np.set("time", Long.toString(statusBarNotification.getPostTime()));
np.set("silent", isPreexisting);
if (!appDatabase.getPrivacy(packageName, AppDatabase.PrivacyOptions.BLOCK_CONTENTS)) {
RepliableNotification rn = extractRepliableNotification(statusBarNotification);
@@ -512,7 +509,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
StatusBarNotification[] notifications = service.getActiveNotifications();
if (notifications != null) { //Can happen only on API 23 and lower
for (StatusBarNotification notification : notifications) {
sendNotification(notification);
sendNotification(notification, true);
}
}
}

View File

@@ -32,8 +32,6 @@ import org.kde.kdeconnect_tp.R;
public abstract class Plugin {
protected Device device;
protected Context context;
protected int permissionExplanation = R.string.permission_explanation;
protected int optionalPermissionExplanation = R.string.optional_permission_explanation;
@Nullable
protected SharedPreferences preferences;
@@ -191,27 +189,27 @@ public abstract class Plugin {
}
/**
* Determine whether we should avoid loading this Plugin for {@link #device}.
* Returns false when we should avoid loading this Plugin for {@link #device}.
* <p>
* Called after {@link #setContext(Context, Device)} but before {@link #onCreate()}.
* </p>
* <p>
* By default, this just checks if {@link #getMinSdk()} is greater than the
* By default, this just checks if {@link #getMinSdk()} is smaller or equal than the
* {@link Build.VERSION#SDK_INT SDK version} of this Android device.
* </p>
*
* @return false if it makes sense to call {@link #onCreate()}, true otherwise
* @return true if it's safe to call {@link #onCreate()}
*/
@CallSuper
public boolean isIncompatible() {
return getMinSdk() > Build.VERSION.SDK_INT;
public boolean isCompatible() {
return Build.VERSION.SDK_INT >= getMinSdk();
}
/**
* Initialize the listeners and structures in your plugin.
* <p>
* If {@link #isIncompatible()} returns false, this will <em>not</em>
* be called.
* If {@link #isCompatible()} or {@link #checkRequiredPermissions()} returns false, this
* will <em>not</em> be called.
* </p>
*
* @return true if initialization was successful, false otherwise
@@ -246,14 +244,36 @@ public abstract class Plugin {
*/
public abstract String[] getOutgoingPacketTypes();
/**
* Should return the list of permissions from Manifest.permission.* that, if not present,
* mean the plugin can't be loaded.
*/
protected String[] getRequiredPermissions() {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
/**
* Should return the list of permissions from Manifest.permission.* that enable additional
* functionality in the plugin (without preventing the plugin to load).
*/
protected String[] getOptionalPermissions() {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
/**
* Returns the string to display before asking for the required permissions for the plugin.
*/
protected @StringRes int getPermissionExplanation() {
return R.string.permission_explanation;
}
/**
* Returns the string to display before asking for the optional permissions for the plugin.
*/
protected @StringRes int getOptionalPermissionExplanation() {
return R.string.optional_permission_explanation;
}
//Permission from Manifest.permission.*
protected boolean isPermissionGranted(String permission) {
int result = ContextCompat.checkSelfPermission(context, permission);
@@ -286,11 +306,11 @@ public abstract class Plugin {
*/
public DialogFragment getPermissionExplanationDialog() {
return requestPermissionDialog(getRequiredPermissions(), permissionExplanation);
return requestPermissionDialog(getRequiredPermissions(), getPermissionExplanation());
}
public AlertDialogFragment getOptionalPermissionExplanationDialog() {
return requestPermissionDialog(getOptionalPermissions(), optionalPermissionExplanation);
return requestPermissionDialog(getOptionalPermissions(), getOptionalPermissionExplanation());
}
public boolean checkRequiredPermissions() {

View File

@@ -82,7 +82,6 @@ public class PresenterActivity extends AppCompatActivity implements SensorEventL
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
binding = ActivityPresenterBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

View File

@@ -346,15 +346,32 @@ public class RemoteKeyboardPlugin extends Plugin implements SharedPreferences.On
np.getBoolean("ctrl"), np.getBoolean("alt"));
}
public enum MousePadPacketType {
Keyboard,
Mouse,
};
public static MousePadPacketType getMousePadPacketType(NetworkPacket np) {
if (np.has("key") || np.has("specialKey")) {
return MousePadPacketType.Keyboard;
} else {
return MousePadPacketType.Mouse;
}
}
@Override
public boolean onPacketReceived(NetworkPacket np) {
if (!np.getType().equals(PACKET_TYPE_MOUSEPAD_REQUEST)
|| (!np.has("key") && !np.has("specialKey"))) { // expect at least key OR specialKey
Log.e("RemoteKeyboardPlugin", "Invalid packet type for remotekeyboard plugin!");
if (!np.getType().equals(PACKET_TYPE_MOUSEPAD_REQUEST)) {
Log.e("RemoteKeyboardPlugin", "Invalid packet type for RemoteKeyboardPlugin: "+np.getType());
return false;
}
if (getMousePadPacketType(np) != MousePadPacketType.Keyboard) {
return false; // This packet will be handled by the MouseReceiverPlugin instead, silently ignore
}
if (RemoteKeyboardService.instance == null) {
Log.i("RemoteKeyboardPlugin", "Remote keyboard is not the currently selected input method, dropping key");
return false;

View File

@@ -75,7 +75,6 @@ public class RunCommandActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
binding = ActivityRunCommandBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

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