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

Compare commits

..

87 Commits

Author SHA1 Message Date
Albert Vaca Cintora
bd8a1c9610 Bump version to release 2020-04-17 23:11:12 +02:00
Albert Vaca Cintora
5c38de03ba Fix NPE when calling ClipboardListener.instance().setText()
Which only happens on Android 10 since we skip calling
ClipboardListener.instance().registerObserver()
2020-04-17 23:11:12 +02:00
Albert Vaca Cintora
48092f93bc Fix ConcurrentModificationException 2020-04-17 22:56:34 +02:00
Albert Vaca Cintora
f20fef2459 Fix "Connection closed by peer" crash 2020-04-17 22:56:34 +02:00
Albert Vaca Cintora
9b637eb386 Fix NPE 2020-04-17 22:56:34 +02:00
Albert Vaca Cintora
67944c075c Fix NPE 2020-04-17 22:56:34 +02:00
Albert Vaca Cintora
e4021b4bce Fix NPE 2020-04-17 22:56:34 +02:00
Albert Vaca Cintora
080f511cce Fix NPE 2020-04-17 22:06:48 +02:00
Albert Vaca Cintora
7331bd5392 Disable BigScreen by default 2020-04-17 21:59:42 +02:00
Albert Vaca Cintora
f58b6c5c39 Fix NPE 2020-04-17 21:58:47 +02:00
Albert Vaca Cintora
5808676cd0 Bump version to release 2020-04-17 00:07:27 +02:00
Albert Vaca Cintora
0fc5d09078 Revert send clipboard on Android X
This reverts 3 commits:

"Clipboard Plugin: Added support to send clipboard to multiple devices on Android 10 and later."
b92271105a

"Excluded ClipboardFloatingActivity from App recents Screen"
ee1562050c

"Make Clipboard plugin work in Android X"
b81d3a82e5
2020-04-16 23:55:22 +02:00
Anjani Kumar
b92271105a Clipboard Plugin: Added support to send clipboard to multiple devices on Android 10 and later. 2020-04-14 10:28:57 +05:30
Simon Redman
be34aa6f72 Add ecdh-sha2-nistp384 to mina-sshd's key exchange algorithms 2020-04-13 20:13:31 -07:00
l10n daemon script
c0301eaed1 GIT_SILENT made messages (after extraction) 2020-04-08 02:52:17 +02:00
Abdel-Rahman Abdel-Rahman
bfbe6b55ec Consider subscription id when sending SMS messages 2020-04-07 20:02:12 +00:00
Arjun Thekoot Harisankar
d58dd649e0 Add README.txt having the instructions on how to create a base skeleton for a Plugin 2020-04-07 11:11:05 -07:00
l10n daemon script
18a524971b GIT_SILENT made messages (after extraction) 2020-04-07 02:55:36 +02:00
l10n daemon script
d3ad014e21 GIT_SILENT made messages (after extraction) 2020-04-05 03:02:17 +02:00
l10n daemon script
fcfdec14fb GIT_SILENT made messages (after extraction) 2020-04-03 02:55:22 +02:00
l10n daemon script
d443a0d58d GIT_SILENT made messages (after extraction) 2020-04-02 02:49:19 +02:00
l10n daemon script
5dac72264f GIT_SILENT made messages (after extraction) 2020-04-01 02:53:12 +02:00
l10n daemon script
9f55fd4448 GIT_SILENT made messages (after extraction) 2020-03-31 02:51:14 +02:00
l10n daemon script
c16c2ee494 GIT_SILENT made messages (after extraction) 2020-03-30 02:48:13 +02:00
l10n daemon script
c4ad758110 GIT_SILENT made messages (after extraction) 2020-03-29 04:00:25 +02:00
Sylvia van Os
e3ca5aca57 Initial Bigscreen remote support 2020-03-27 20:33:10 +00:00
Albert Vaca Cintora
cff55ab8dd Fix battery level not being set yet when a request arrived 2020-03-27 15:43:55 +01:00
Nicolas Fella
e716205a48 Restore last player when mpris activity restarts 2020-03-26 13:49:15 +00:00
l10n daemon script
daa0676cbe GIT_SILENT made messages (after extraction) 2020-03-25 02:57:59 +01:00
l10n daemon script
e2e7b6fead GIT_SILENT made messages (after extraction) 2020-03-24 02:49:03 +01:00
l10n daemon script
977b2f9957 GIT_SILENT made messages (after extraction) 2020-03-23 02:43:50 +01:00
Philip Cohn-Cort
23337fb2f4 Target and compile against Android 10.0 (SDK 29) 2020-03-21 22:43:29 -04:00
Philip Cohn-Cort
5e0ae437bb Upgrade gradle plugin for AS 3.6.1 2020-03-21 22:43:29 -04:00
Philip Cohn-Cort
51b5989183 Request v10.2.1 of the butterknife runtime dependency
Note that there haven't been any updates to 'butterknife-compiler' since
the 10.0.0 release.
2020-03-21 22:43:29 -04:00
Philip Cohn-Cort
2c4274ed2a Update gradle wrapper files to match those bundled w/ 5.4.1 2020-03-21 22:43:29 -04:00
Philip Cohn-Cort
7e935a495e Remove old protocol v6 code from DeviceTest.java 2020-03-21 22:43:29 -04:00
Philip Cohn-Cort
06a73ca856 Use gradle.properties to control what kind of code optimization runs 2020-03-21 22:43:29 -04:00
l10n daemon script
753b61860e GIT_SILENT made messages (after extraction) 2020-03-22 02:46:17 +01:00
Albert Vaca Cintora
15773445cc Check for the actual menu item ID 2020-03-21 01:38:28 +01:00
Albert Vaca Cintora
f75ad76e78 Pause origin when continuing on phone
And simplify error cases
2020-03-21 01:30:20 +01:00
Albert Vaca Cintora
5a299376e3 Move "open URL" button to overflow menu 2020-03-21 01:25:19 +01:00
Albert Vaca Cintora
6bdd815c17 Merge branch 'strace/kdeconnect-android-seamless_playback' 2020-03-21 00:50:25 +01:00
Albert Vaca Cintora
c6514ab577 Merge branch 'anjani/kdeconnect-android-clip' 2020-03-20 23:33:09 +01:00
Erik Duisters
4d8e7cadde Use a prefences file per device/plugin combo
Cleanup global plugin preferences after migration to per device preferences
2020-03-20 20:30:58 +00:00
Albert Vaca Cintora
e7651ec9bc Merge branch 'shavez/kdeconnect-android-theme-improvements' 2020-03-20 21:28:37 +01:00
Anjani Kumar
ee1562050c Excluded ClipboardFloatingActivity from App recents Screen 2020-03-19 22:12:08 +05:30
l10n daemon script
e9d96e90a0 GIT_SILENT made messages (after extraction) 2020-03-19 02:43:38 +01:00
Md Shavez
a3b768fdf8 Added colors: secondary and onSecondary according to guidelines of material design 2020-03-17 12:30:25 +05:30
l10n daemon script
27e2a3a31d GIT_SILENT made messages (after extraction) 2020-03-17 02:46:08 +01:00
l10n daemon script
92dcec7883 GIT_SILENT made messages (after extraction) 2020-03-16 02:51:23 +01:00
l10n daemon script
4a678330a5 GIT_SILENT made messages (after extraction) 2020-03-15 02:49:01 +01:00
l10n daemon script
55259ed154 GIT_SILENT made messages (after extraction) 2020-03-14 02:47:21 +01:00
Joscha Henningsen
2c23b92bdd Fix bug concerning incorrect process status when sharing large files (>2.15GB) 2020-03-12 23:46:31 +00:00
Anjani Kumar
b81d3a82e5 Make Clipboard plugin work in Android X
## Summary

Fixes #5

BUG: 417419](https://bugs.kde.org/show_bug.cgi?id=417419)

This patch introduces a workaround to access the restricted clipboard in Android X.
Clipboard synchronisation in KDE Connect was one of the killer features before Android X. An action button is added in the persistent foreground notification **Send Clipboard** which adds the ability to send the clipboard using a small workaround. Clipboard Synchronisation works as usual in lower Android Versions.

This is a very convenient workaround for sending clipboard quickly as it does not requires to open the app. Floating Activity is quite handy for quick actions.

## Details of the workaround

### ClipboardFloatingActivity

* This activity is only executed in Android X.
* This is transparent, accesses the clipboard when in focus.
* Sends a `NetworkPacket` containing *text* and *timestamp*.
* When the packet has been sent, it pops up a toast with a success message.
* Automatically closes after the showing the Toast.

### Reverted changes for Android X.

* Changes done in commits 54be4a1a99 and 9f3b75b748 have been reverted.
* These changes are not required anymore as the workaround for clipboard sync works.

The action button in the notification for **Send Clipboard** is not added in the lower versions of Android. **It is only added in Android X**.

**Two way sync is working in Android X with this patch. Sync works normally in lower Android versions.**

## Test Plan

### Before:

Clipboard from PC to Phones were synchronised but Clipboard of phones didn't get synchronised with the PC.

### After:

The action button is up in Android X while using other apps.

![Screenshot_20200227-150435_Chrome](/uploads/201960e1577321c8a77c9945bd2b5e76/Screenshot_20200227-150435_Chrome.png)

After clicking the button, a cute Toast appears with the message *Clipboard sent*

![Screenshot_20200228-233701_Chrome](/uploads/8da58b1006b95ce82c7cec2c91f32878/Screenshot_20200228-233701_Chrome.png)

I think this is one of the best workarounds available to make this awesome plugin work.
2020-03-12 03:56:37 +00:00
l10n daemon script
61c1629ff0 GIT_SILENT made messages (after extraction) 2020-03-11 02:52:45 +01:00
Simon Redman
36f592a665 [SMS App] Add interface for querying a range of messages
## Summary
This patch adds an interface to return only a specified window of messages.

The current implementation of the conversation interface loads all messages every time the conversation is requested. This is might be painfully slow to load in case the conversation is large or if there are a lot of MMS/RCS messages in the conversation (since those are wildly slower to load than SMS)

Used by https://invent.kde.org/kde/kdeconnect-kde/merge_requests/203 to enable Desktop functionality

## Test Plan

 - With new Android app and old Desktop app:
   - The Android app will notice the missing fields and query for all messages as before.
 - With old Android app and new Desktop app:
   - The desktop will send fields for the new interface which will not be read and all messages will be returned.
 - With new Android app and new Desktop app:
   - The new interface is used and returns only a certain number of messages at a time.

## Known Issues
There is an un-covered corner case if lots of MMS messages are received in the same second (or SMS messages in the same millisecond): Since the interfaces uses timestamps as a filter, it might happen that not all messages sharing the same timestamp are returned. The fact that there are still more messages sharing the timestamp is invisible to the caller. This could be a real-world problem if, for example, a user gets off a plane and their phone downloads a bunch of MMS all at once.
2020-03-11 00:34:31 +00:00
l10n daemon script
2b934af3fa GIT_SILENT made messages (after extraction) 2020-03-04 02:48:50 +01:00
l10n daemon script
34cad4c117 GIT_SILENT made messages (after extraction) 2020-02-26 02:50:14 +01:00
Anjani Kumar
d7f3931eeb Removed extra string resource 2020-02-25 02:46:32 +05:30
Anjani Kumar
0a225d3217 Added a check for RunCommands being empty before adding action button. 2020-02-24 22:39:58 +05:30
Anjani Kumar
e5e0b6dad6 Added two new string resources in strings.xml for two action buttons 2020-02-24 22:39:58 +05:30
Anjani Kumar
e3f0572b9d Adding two action buttons (Send Files/Run Commands) in notification only when there is a single device connected 2020-02-24 22:39:58 +05:30
Albert Vaca
06bce217ac Merge remote-tracking branch 'albertvaka/photo-npe-fix' 2020-02-24 11:41:40 +01:00
l10n daemon script
e1f418e597 GIT_SILENT made messages (after extraction) 2020-02-21 02:41:41 +01:00
Albert Vaca
fb97bb5dbb Merge branch 'work/androidx-bump' 2020-02-18 21:13:06 +01:00
Simon Redman
0d69c0b96c Fix duplicated addresses 2020-02-17 16:34:51 -08:00
l10n daemon script
3dc171632c GIT_SILENT made messages (after extraction) 2020-02-17 02:46:50 +01:00
Dmitriy Bogdanov
4c5114388a Set correct actions in MPRIS notification 2020-02-14 16:14:58 +04:00
Albert Vaca Cintora
546613f4b8 Bump Androidx version
We went over the DEX methods limit, so I enabled Proguard on debug :(
2020-02-09 21:51:56 +01:00
l10n daemon script
4fe2b1b601 GIT_SILENT made messages (after extraction) 2020-02-08 02:48:36 +01:00
l10n daemon script
0b85d80634 GIT_SILENT made messages (after extraction) 2020-02-05 02:48:04 +01:00
l10n daemon script
0ca20767c7 GIT_SILENT made messages (after extraction) 2020-01-28 02:42:08 +01:00
l10n daemon script
519cfd8253 GIT_SILENT made messages (after extraction) 2020-01-25 02:46:28 +01:00
l10n daemon script
c09b310c6b GIT_SILENT made messages (after extraction) 2020-01-21 02:49:00 +01:00
l10n daemon script
c88a9df295 GIT_SILENT made messages (after extraction) 2020-01-20 02:46:40 +01:00
Soul Trace
564251e3cb MprisActivity: Fix "Open URL" button visibility check
It should be checked against empty string, not against null.
2020-01-19 11:39:23 +03:00
Soul Trace
b99082ef00 Let user open in the PC browser media URL to Android device [1/2]
Seek position is preserved for following domains:
youtube.com
youtu.be
pornhub.com
vimeo.com
dailymotion.com
twitch.tv

ic_arrow_black.xml was converted from Kubuntu 19.10 AMD64
breeze-icon-theme package:
/usr/share/icons/breeze-dark/actions/32/arrow.svg
2020-01-18 17:27:49 +00:00
l10n daemon script
6d8faa7c48 GIT_SILENT made messages (after extraction) 2020-01-18 02:47:42 +01:00
l10n daemon script
f2ef2e9047 GIT_SILENT made messages (after extraction) 2020-01-17 02:48:41 +01:00
l10n daemon script
45a5385ee5 GIT_SILENT made messages (after extraction) 2020-01-16 02:45:12 +01:00
Albert Vaca
386c3cec21 Listen to MY_PACKAGE_REPLACED to restart the service on app upgrades.
The old PACKAGE_REPLACED event doesn't work since Oreo [1].

[1] https://developer.android.com/about/versions/oreo/background.html#broadcasts

BUG: 416245
2020-01-15 12:46:22 +01:00
Albert Vaca Cintora
54be4a1a99 Don't load clipboard plugin in Android 10 2020-01-14 23:02:38 +01:00
Albert Vaca Cintora
9f3b75b748 Notify Android 10 users that clipboard won't work 2020-01-14 23:02:38 +01:00
Albert Vaca Cintora
b1e3113343 Allow negative button to not be present 2020-01-14 23:02:38 +01:00
Albert Vaca Cintora
2ee3c543f5 Remove requestCode from get[Optional]PermissionExplanationDialog 2020-01-14 23:02:38 +01:00
l10n daemon script
6a43975951 GIT_SILENT made messages (after extraction) 2020-01-14 02:45:56 +01:00
Albert Vaca Cintora
7f0c849fb0 Fix NPE on plugin in onActivityResult 2019-11-25 14:32:27 +01:00
76 changed files with 1855 additions and 475 deletions

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="11370"
android:versionName="1.13.7">
android:versionCode="11410"
android:versionName="1.14.1">
<supports-screens
android:anyDensity="true"
@@ -106,6 +106,9 @@
android:path="/"
android:scheme="package" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
@@ -198,6 +201,16 @@
android:scheme="kdeconnect" />
</intent-filter>
</activity>
<activity
android:name="org.kde.kdeconnect.Plugins.BigscreenPlugin.BigscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/pref_plugin_bigscreen"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity"
android:windowSoftInputMode="stateHidden|adjustResize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity"
android:label="@string/pref_plugin_mousepad"

View File

@@ -6,15 +6,16 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.android.tools.build:gradle:3.6.1'
}
}
android {
compileSdkVersion 28
compileSdkVersion 29
defaultConfig {
minSdkVersion 14
targetSdkVersion 28
targetSdkVersion 29
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
dexOptions {
javaMaxHeapSize "2g"
@@ -54,14 +55,13 @@ android {
}
buildTypes {
debug {
minifyEnabled false
useProguard false
minifyEnabled true
signingConfig signingConfigs.debug
}
release { //keep on 'release' for faster builds, set to 'all' when testing to make sure proguard is not deleting important stuff
// keep minifyEnabled false above for faster builds; set to 'true'
// when testing to make sure ProGuard/R8 is not deleting important stuff
release {
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
@@ -81,11 +81,14 @@ dependencies {
implementation 'androidx.media:media:1.1.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.lifecycle:lifecycle-runtime:2.1.0'
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
implementation 'androidx.lifecycle:lifecycle-common-java8:2.1.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.lifecycle:lifecycle-runtime:2.2.0'
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'com.jakewharton:disklrucache:2.0.2' //For caching album art bitmaps
implementation 'com.jaredrummler:android-device-names:1.1.9' //To get a human-friendly device name
@@ -95,7 +98,8 @@ dependencies {
//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 'com.jakewharton:butterknife:10.0.0'
//noinspection AnnotationProcessorOnCompilePath - c.f. https://issuetracker.google.com/issues/140881211
implementation 'com.jakewharton:butterknife:10.2.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.0.0'
implementation 'org.atteo.classindex:classindex:3.6'
@@ -109,3 +113,7 @@ dependencies {
testImplementation 'org.mockito:mockito-core:2.23.0'
testImplementation 'org.skyscreamer:jsonassert:1.3.0'
}
repositories {
google()
}

View File

@@ -1,2 +1,11 @@
android.enableJetifier=true
android.useAndroidX=true
android.useAndroidX=true
###
# This 'android.enableR8' property only matters when the current
# build variant has 'minifyEnabled true'.
#
# Set this to false to use ProGuard.
# Set this to true to use R8.
#
# Default: true
android.enableR8=false

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Sun Oct 27 20:27:45 CET 2019
#Fri Mar 27 09:59:30 CET 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

116
gradlew vendored
View File

@@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
@@ -6,42 +22,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -60,6 +40,46 @@ cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -85,7 +105,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -150,11 +170,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

30
gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -8,14 +24,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +62,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +75,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="32"
android:viewportHeight="32"
android:width="32dp"
android:height="32dp">
<path
android:pathData="M8.990234 5c-0.5522847 0 -1 0.4477153 -1 1 0 0.5522847 0.4477153 1 1 1 0.5522847 0 1 -0.4477153 1 -1 0 -0.5522847 -0.4477153 -1 -1 -1zm2 4L11 29 16.841796 21.769531 26 21Z"
android:fillColor="#FF000000" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:pathData="M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"
android:fillColor="#010101"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M4,12l1.41,1.41L11,7.83V20h2V7.83l5.58,5.59L20,12l-8,-8 -8,8z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,7v4H5.83l3.58,-3.59L8,6l-6,6 6,6 1.41,-1.41L5.83,13H21V7z"/>
</vector>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.gridlayout.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
grid:useDefaultMargins="true">
<ImageButton
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" />
<ImageButton
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" />
<ImageButton
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" />
<ImageButton
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" />
<ImageButton
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" />
<ImageButton
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" />
</androidx.gridlayout.widget.GridLayout>

View File

@@ -26,7 +26,7 @@
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"
style="@style/Widget.MaterialComponents.FloatingActionButton"
style="@style/KdeConnectThemeBase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"

View File

@@ -100,7 +100,6 @@
android:contentDescription="@string/mpris_next"
android:src="@drawable/ic_next_black"
android:theme="@style/DisableableButton" />
</LinearLayout>
<LinearLayout

View File

@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Nun se coneutó con dengún preséu</string>
<string name="foreground_notification_no_devices">Nun se coneutó con nengún preséu</string>
<string name="foreground_notification_devices">Coneutóse con %s</string>
<string name="pref_plugin_telephony">Avisador telefónicu</string>
<string name="pref_plugin_telephony_desc">Unvia avisos de les llamaes entrantes</string>
@@ -19,6 +19,7 @@
<string name="pref_plugin_runcommand_desc">Aiciona comandos remotos dende\'l preséu</string>
<string name="pref_plugin_contacts">Sincronizador de contautos</string>
<string name="pref_plugin_contacts_desc">Permite la sincronización de la llista telefónica del teléfonu</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Unviu y receición de pings</string>
<string name="pref_plugin_notifications">Sincronización d\'avisos</string>
<string name="pref_plugin_notifications_desc">Accede a los avisos n\'otros preseos</string>
@@ -33,7 +34,7 @@
<string name="no_permissions_remotekeyboard">Pa recibir calcos de tecles precises activar el tecláu remotu de KDE Connect</string>
<string name="send_ping">Unviar un ping</string>
<string name="open_mpris_controls">Mandu multimedia</string>
<string name="remotekeyboard_editing_only_title">Remanar les tecles remotes namái al editar</string>
<string name="remotekeyboard_editing_only_title">Remanar les tecles remotes namás al editar</string>
<string name="open_mousepad">Entrada remota</string>
<string name="mousepad_info">Movi un deu pela pantalla pa mover el mur. Con un toque faes un clic esquierdu y teniendo primío faes l\'aición d\'arrastrar y soltar, col toque de dos deos simules un clic drechu y col toque de tres simules un clic col botón d\'en mediu del mur. Esliza dos deos pela pantalla pa desplazate.</string>
<string name="mousepad_double_tap_settings_title">Aición al tocar con dos deos</string>
@@ -128,7 +129,7 @@
<item>2 minutos</item>
</string-array>
<string name="mpris_notification_settings_summary">Permite\'l control de reproductores multimedia ensin abrir KDE Connect</string>
<string name="share_to">Compartir con...</string>
<string name="share_to">Compartir con</string>
<string name="protocol_version_newer">Esti preséu una versión nueva del protocolu</string>
<string name="plugin_settings_with_name">%s</string>
<string name="custom_devices_settings">Llista de preseos personalizada</string>
@@ -145,6 +146,7 @@
<string name="title_activity_notification_filter">Peñera d\'avisos</string>
<string name="filter_apps_info">Van sincronizase los avisos de les aplicaciones esbillaes.</string>
<string name="sftp_sdcard">Tarxeta SD</string>
<string name="sftp_readonly">(namás llectura)</string>
<string name="add_device_dialog_title">Amiestu d\'un preséu</string>
<string name="add_device_hint">Nome d\'agospiu o direición IP</string>
<string name="sftp_preference_configured_storage_locations">Allugamientos d\'almacenamientu configuraos</string>
@@ -167,11 +169,13 @@
<string name="device_rename_confirm">Renomar</string>
<string name="refresh">Refrescar</string>
<string name="unreachable_description">Esti preséu empareyáu nun ye algamable. Asegúrate de que ta coneutáu a la mesma rede que tu.</string>
<string name="no_wifi">Nun tas coneutáu a una rede Wi-Fi polo que nun vas ser a ver dengún preséu. Calca equí p\'activar el Wi-Fi.</string>
<string name="no_file_browser">Nun hai dengún restolador de ficheros instaláu.</string>
<string name="no_wifi">Nun tas coneutáu a una rede Wi-Fi polo que nun vas ser a ver nengún preséu. Calca equí p\'activar el Wi-Fi.</string>
<string name="on_non_trusted_message">Nun tas nuna rede d\'enfotu. Desactivóse la descubrición automática.</string>
<string name="no_file_browser">Nun hai nengún restolador de ficheros instaláu.</string>
<string name="pref_plugin_telepathy">Unviu de SMS</string>
<string name="pref_plugin_telepathy_desc">Unvia SMS dende l\'ordenador</string>
<string name="findmyphone_description">Fai qu\'esti preséu suene pa que pueas alcontralu</string>
<string name="findmyphone_found">Alcontrélu</string>
<string name="plugins_need_permission">Dalgunos plugins precisen permisos pa funcionar (tócalos pa más información):</string>
<string name="permission_explanation">Esti plugin precisa permisos pa funcionar</string>
<string name="optional_permission_explanation">Precises conceder permisos adicionales p\'activar toles funciones</string>
@@ -212,6 +216,13 @@
<string name="notification_channel_receivenotification">Avisos d\'otros preseos</string>
<string name="take_picture">Llanzamientu de la cámara</string>
<string name="plugin_photo_desc">Llanza l\'aplicación de la cámara p\'acenciellar la fechura y tresferencia de semeyes</string>
<string name="no_app_for_opening">Nun alcontró denguna aplicación afayadiza p\'abrir esti ficheru.</string>
<string name="no_app_for_opening">Nun alcontró nenguna aplicación afayadiza p\'abrir esti ficheru.</string>
<string name="remote_keyboard_service">Tecláu remotu de KDE Connect</string>
<string name="trusted_networks">Redes d\'enfotu</string>
<string name="trusted_networks_desc">Torga la descubrición automática en redes conocíes</string>
<string name="empty_trusted_networks_list_text">Entá nun amestesti nenguna rede d\'enfotu</string>
<string name="allow_all_networks_text">Permitir toes</string>
<string name="location_permission_needed_title">Ríquese un permisu</string>
<string name="location_permission_needed_desc">Android rique\'l permisu Allugamientu pa indentificar redes Wi-Fi</string>
<string name="clipboard_android_x_incompat">Android 10 quitó l\'accesu al cartafueyu en toles aplicaciones. Esti plugin va desactivase.</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">No està connectat a cap dispositiu</string>
<string name="foreground_notification_devices">Connectat a: %s</string>
<string name="foreground_notification_send_clipboard">Envia al porta-retalls</string>
<string name="pref_plugin_telephony">Notificador de la telefonia</string>
<string name="pref_plugin_telephony_desc">Envia notificacions per a les trucades entrants</string>
<string name="pref_plugin_battery">Informa de la bateria</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Permet navegar de forma remota pel sistema de fitxers del dispositiu</string>
<string name="pref_plugin_clipboard">Sincronitza el porta-retalls</string>
<string name="pref_plugin_clipboard_desc">Comparteix el contingut del porta-retalls</string>
<string name="pref_plugin_clipboard_sent">S\'ha enviat al porta-retalls</string>
<string name="pref_plugin_mousepad">Entrada remota</string>
<string name="pref_plugin_mousepad_desc">Usa el vostre telèfon o tauleta com un ratolí i un teclat</string>
<string name="pref_plugin_presenter">Presentació de diapositives remota</string>
@@ -30,9 +32,10 @@
<string name="pref_plugin_receive_notifications">Rep les notificacions</string>
<string name="pref_plugin_receive_notifications_desc">Rep notificacions des d\'altres dispositius i mostrar-los a l\'Android</string>
<string name="pref_plugin_sharereceiver">Comparteix i rep</string>
<string name="pref_plugin_sharereceiver_desc">Comparteix els fitxers i els URL entre els dispositius</string>
<string name="pref_plugin_sharereceiver_desc">Comparteix els fitxers i URL entre els dispositius</string>
<string name="device_list_empty">No hi ha cap dispositiu</string>
<string name="ok">D\'acord</string>
<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 accedir a les notificacions</string>
@@ -197,7 +200,7 @@
<string name="sftp_no_storage_locations_configured">No s\'ha configurat cap ubicació d\'emmagatzematge</string>
<string name="sftp_saf_permission_explanation">Per accedir remotament als fitxer cal configurar les ubicacions d\'emmagatzematge</string>
<string name="no_players_connected">No s\'ha trobat cap reproductor</string>
<string name="send_files">Envia els fitxers</string>
<string name="send_files">Envia fitxers</string>
<string name="pairing_title">Dispositius del KDE Connect</string>
<string name="pairing_description">Els altres dispositius que executin el KDE Connect a la mateixa xarxa han d\'aparèixer aquí.</string>
<string name="device_rename_title">Reanomena el dispositiu</string>
@@ -285,4 +288,15 @@
<string name="allow_all_networks_text">Permet totes</string>
<string name="location_permission_needed_title">Es requereix permís</string>
<string name="location_permission_needed_desc">L\'Android requereix el permís d\'ubicació per identificar la xarxa WiFi</string>
<string name="clipboard_android_x_incompat">L\'Android 10 ha tret l\'accés al porta-retalls a totes les aplicacions. Aquest connector estarà inhabilitat.</string>
<string name="mpris_open_url">Continua reproduint aquí</string>
<string name="cant_open_url">No s\'ha pogut obrir l\'URL per a continuar reproduint</string>
<string name="bigscreen_home">Inici</string>
<string name="bigscreen_up">Dalt</string>
<string name="bigscreen_left">Esquerra</string>
<string name="bigscreen_select">Selecció</string>
<string name="bigscreen_right">Dreta</string>
<string name="bigscreen_down">Baix</string>
<string name="pref_plugin_bigscreen">Pantalla gran remota</string>
<string name="pref_plugin_bigscreen_desc">Useu el dispositiu com a remot per a la Pantalla gran del Plasma</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Žádná připojená zařízení</string>
<string name="foreground_notification_devices">Připojen k: %s</string>
<string name="foreground_notification_send_clipboard">Přečíst schránku</string>
<string name="pref_plugin_telephony">Upozornění telefonie</string>
<string name="pref_plugin_telephony_desc">Posílat upozornění na příchozí hovory</string>
<string name="pref_plugin_battery">Hlášení baterie</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Umožní vám vzdáleně prohlížet souborový systém tohoto zařízení</string>
<string name="pref_plugin_clipboard">Synchronizace schránky</string>
<string name="pref_plugin_clipboard_desc">Sdílet obsah schránky</string>
<string name="pref_plugin_clipboard_sent">Schránka poslána</string>
<string name="pref_plugin_mousepad">Vzdálený vstup</string>
<string name="pref_plugin_mousepad_desc">Používejte svůj telefon nebo tablet jako touchpad a klávesnici</string>
<string name="pref_plugin_presenter">Ovladač promítání</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Sdílet soubory a odkazy mezi zařízeními</string>
<string name="device_list_empty">Žádná zařízení</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Zrušit</string>
<string name="open_settings">Otevřít nastavení</string>
<string name="no_permissions">Pro zpřístupnění upozornění potřebujete oprávnění</string>
@@ -221,6 +224,7 @@
<string name="refresh">Obnovit</string>
<string name="unreachable_description">Toto spárované zařízení je nedosažitelné. Ujistěte se, že běží ve stejné síti.</string>
<string name="no_wifi">Nejste připojeni k síti WiFi, takže nemůžete vidět žádná zařízení. Pro zapnutí WiFi klikněte zde.</string>
<string name="on_non_trusted_message">Síť není důvěryhodná. Automatické hledání bylo vypnuto.</string>
<string name="no_file_browser">Není nainstalován žádný prohlížeč souborů.</string>
<string name="pref_plugin_telepathy">Poslat SMS</string>
<string name="pref_plugin_telepathy_desc">Posílejte zprávy ze své pracovní plochy</string>
@@ -228,6 +232,7 @@
<string name="findmyphone_title_tablet">Najít můj tablet</string>
<string name="findmyphone_title_tv">Najít mou TV</string>
<string name="findmyphone_description">Prozvoní toto zařízení, takže jej můžete najít</string>
<string name="findmyphone_found">Nalezeno</string>
<string name="open">Otevřít</string>
<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>
@@ -258,6 +263,7 @@
<string name="notification_channel_persistent">Stálý ukazatel</string>
<string name="notification_channel_media_control">Ovládání médií</string>
<string name="notification_channel_filetransfer">Přenos souboru</string>
<string name="notification_channel_high_priority">Vysoká priorita</string>
<string name="mpris_stop">Zastavit současný přehrávač</string>
<string name="copy_url_to_clipboard">Kopírovat URL do schránky</string>
<string name="clipboard_toast">Zkopírováno do schránky</string>
@@ -291,4 +297,14 @@
<string name="no_app_for_opening">Pro otevření tohoto souboru nebyla nalezena vhodná aplikace</string>
<string name="remote_keyboard_service">Vzdálená klávesnice pro KDE Connect</string>
<string name="presenter_pointer">Ukazatel</string>
<string name="trusted_networks">Důvěryhodné sítě</string>
<string name="trusted_networks_desc">Omezit automatické hledání na známé sítě</string>
<string name="add_trusted_network">Přidat %1s</string>
<string name="empty_trusted_networks_list_text">Nepřidali jste žádné důvěryhodné sítě</string>
<string name="allow_all_networks_text">Povolit všechny</string>
<string name="location_permission_needed_title">Získán přístup</string>
<string name="location_permission_needed_desc">Pro identifikaci sítě WiFi Android vyžaduje oprávnění zjistit polohu</string>
<string name="clipboard_android_x_incompat">Android 10 odstranit přístup ke schránce pro všechny aplikace. Tento modul bude zakázán.</string>
<string name="mpris_open_url">Pokračovat v přehrávání zde</string>
<string name="cant_open_url">Nelze otevřít URL pro pokračování v přehrávání</string>
</resources>

View File

@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="kde_connect">KDE-Connect</string>
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Keine bestehenden Verbindungen</string>
<string name="foreground_notification_devices">Verbunden mit %s</string>
<string name="pref_plugin_telephony">Telefon-Integration</string>
@@ -85,7 +85,7 @@
<string name="error_canceled_by_user">Abbruch durch Benutzer</string>
<string name="error_canceled_by_other_peer">Abbruch durch Gegenstelle</string>
<string name="encryption_info_title">Verschlüsselungsinformationen</string>
<string name="encryption_info_msg_no_ssl">Das andere Gerät verwendet eine ältere Version von KDE-Connect. Daher muss eine veraltete Verschlüsselungsmethode verwendet werden</string>
<string name="encryption_info_msg_no_ssl">Das andere Gerät verwendet eine ältere Version von KDE Connect. Daher muss eine veraltete Verschlüsselungsmethode verwendet werden</string>
<string name="my_device_fingerprint">Der SHA1-Fingerabdruck Ihres Gerätezertifikats lautet:</string>
<string name="remote_device_fingerprint">Der SHA1-Fingerabdruck des Gerätezertifikats der Gegenstelle lautet:</string>
<string name="pair_requested">Verbindung angefordert</string>
@@ -150,7 +150,7 @@
<item>2 Minuten</item>
</string-array>
<string name="mpris_notification_settings_title">Benachrichtigung zur Medienkontrolle anzeigen</string>
<string name="mpris_notification_settings_summary">Die Steuerung der Medienwiedergabe auch dann erlauben wenn KDE-Connect nicht geöffnet ist</string>
<string name="mpris_notification_settings_summary">Die Steuerung der Medienwiedergabe auch dann erlauben wenn KDE Connect nicht geöffnet ist</string>
<string name="share_to">Freigeben für ...</string>
<string name="protocol_version_newer">Dieses Gerät verwendet eine neuere Protokollversion</string>
<string name="plugin_settings_with_name">%s-Einstellungen</string>
@@ -199,7 +199,7 @@
<string name="no_players_connected">Keine Medienspieler gefunden</string>
<string name="send_files">Dateien senden</string>
<string name="pairing_title">KDE-Connect-Geräte</string>
<string name="pairing_description">Andere Geräte im selben Netzwerk, auf denen KDE-Connect läuft, sollten hier angezeigt werden</string>
<string name="pairing_description">Andere Geräte im selben Netzwerk, auf denen KDE Connect läuft, sollten hier angezeigt werden</string>
<string name="device_rename_title">Geräte umbenennen</string>
<string name="device_rename_confirm">Umbenennen</string>
<string name="refresh">Aktualisieren</string>
@@ -212,6 +212,7 @@
<string name="findmyphone_title_tablet">Mein Tablet suchen</string>
<string name="findmyphone_title_tv">Meinen Fernseher suchen</string>
<string name="findmyphone_description">Ruft dieses Gerät an, damit Sie es finden können</string>
<string name="findmyphone_found">Gefunden</string>
<string name="open">Öffnen</string>
<string name="close">Schließen</string>
<string name="plugins_need_permission">Einige Module benötigen zusätzliche Berechtigungen, tippen Sie für weitere Details:</string>
@@ -234,7 +235,7 @@
<string name="presenter_lock_tip">Sie können Ihr Gerät sperren und mit Hilfe der Lauter-/Leiser-Taste zur vorherigen/nächsten Folie wechseln</string>
<string name="add_command">Einen Befehl hinzufügen</string>
<string name="addcommand_explanation">Es sind keine Befehle vorhanden</string>
<string name="addcommand_explanation2">Sie können neue Befehle in den Systemeinstellungen für KDE-Connect hinzufügen</string>
<string name="addcommand_explanation2">Sie können neue Befehle in den Systemeinstellungen für KDE Connect hinzufügen</string>
<string name="add_command_description">Sie können neue Befehle auf der Arbeitsfläche hinzufügen</string>
<string name="pref_plugin_mprisreceiver">Steuerung der Medienwiedergabe</string>
<string name="pref_plugin_mprisreceiver_desc">Ein verbundenes Gerät zum Steuern der lokalen Medienwiedergabe verwenden</string>
@@ -242,6 +243,7 @@
<string name="notification_channel_persistent">Dauerhafte Benachrichtigung</string>
<string name="notification_channel_media_control">Medienkontrolle</string>
<string name="notification_channel_filetransfer">Dateiübertragung</string>
<string name="notification_channel_high_priority">Hohe Priorität</string>
<string name="mpris_stop">Die aktuelle Medienwiedergabe beenden</string>
<string name="copy_url_to_clipboard">Adresse in die Zwischenablage kopieren</string>
<string name="clipboard_toast">In die Zwischenablage kopiert</string>
@@ -273,6 +275,9 @@
<string name="take_picture">Kamera starten</string>
<string name="plugin_photo_desc">Die Kamera starten um das Erstellen und Übertragen von Bildern zu vereinfachen</string>
<string name="no_app_for_opening">Es wurde keine passende App zum Öffnen dieser Datei gefunden</string>
<string name="remote_keyboard_service">Entfernte Tastatur für KDE-Connect</string>
<string name="remote_keyboard_service">Entfernte Tastatur für KDE Connect</string>
<string name="presenter_pointer">Laserpointer</string>
<string name="trusted_networks">Vertrauenswürdiges Netzwerk</string>
<string name="add_trusted_network">%1s hinzufügen</string>
<string name="location_permission_needed_title">Berechtigung erforderlich</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Not connected to any device</string>
<string name="foreground_notification_devices">Connected to: %s</string>
<string name="foreground_notification_send_clipboard">Send Clipboard</string>
<string name="pref_plugin_telephony">Telephony notifier</string>
<string name="pref_plugin_telephony_desc">Send notifications for incoming calls</string>
<string name="pref_plugin_battery">Battery report</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Allows to browse this device\'s filesystem remotely</string>
<string name="pref_plugin_clipboard">Clipboard sync</string>
<string name="pref_plugin_clipboard_desc">Share the clipboard content</string>
<string name="pref_plugin_clipboard_sent">Clipboard Sent</string>
<string name="pref_plugin_mousepad">Remote input</string>
<string name="pref_plugin_mousepad_desc">Use your phone or tablet as a touchpad and keyboard</string>
<string name="pref_plugin_presenter">Slideshow remote</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Share files and URLs between devices</string>
<string name="device_list_empty">No devices</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Cancel</string>
<string name="open_settings">Open settings</string>
<string name="no_permissions">You need to grant permission to access notifications</string>
@@ -205,6 +208,7 @@
<string name="refresh">Refresh</string>
<string name="unreachable_description">This paired device is not reachable. Make sure it is connected to your same network.</string>
<string name="no_wifi">You\'re not connected to a Wi-Fi network, so you may not be able to see any devices. Click here to enable Wi-Fi.</string>
<string name="on_non_trusted_message">Not on a trusted network: autodiscovery is disabled.</string>
<string name="no_file_browser">There are no file browsers installed.</string>
<string name="pref_plugin_telepathy">Send SMS</string>
<string name="pref_plugin_telepathy_desc">Send text messages from your desktop</string>
@@ -212,6 +216,7 @@
<string name="findmyphone_title_tablet">Find my tablet</string>
<string name="findmyphone_title_tv">Find my TV</string>
<string name="findmyphone_description">Rings this device so you can find it</string>
<string name="findmyphone_found">Found it</string>
<string name="open">Open</string>
<string name="close">Close</string>
<string name="plugins_need_permission">Some Plugins need permissions to work (tap for more info):</string>
@@ -242,6 +247,7 @@
<string name="notification_channel_persistent">Persistent indicator</string>
<string name="notification_channel_media_control">Media control</string>
<string name="notification_channel_filetransfer">File transfer</string>
<string name="notification_channel_high_priority">High priority</string>
<string name="mpris_stop">Stop the current player</string>
<string name="copy_url_to_clipboard">Copy URL to clipboard</string>
<string name="clipboard_toast">Copied to clipboard</string>
@@ -275,4 +281,22 @@
<string name="no_app_for_opening">No suitable app found to open this file</string>
<string name="remote_keyboard_service">KDE Connect Remote Keyboard</string>
<string name="presenter_pointer">Pointer</string>
<string name="trusted_networks">Trusted networks</string>
<string name="trusted_networks_desc">Restrict autodiscovery to known networks</string>
<string name="add_trusted_network">Add %1s</string>
<string name="empty_trusted_networks_list_text">You have not added any trusted network yet</string>
<string name="allow_all_networks_text">Allow all</string>
<string name="location_permission_needed_title">Permission required</string>
<string name="location_permission_needed_desc">Android requires the Location permission to identify your WiFi network</string>
<string name="clipboard_android_x_incompat">Android 10 has removed clipboard access to all apps. This plugin will be disabled.</string>
<string name="mpris_open_url">Continue playing here</string>
<string name="cant_open_url">Cannot open URL to continue playing</string>
<string name="bigscreen_home">Home</string>
<string name="bigscreen_up">Up</string>
<string name="bigscreen_left">Left</string>
<string name="bigscreen_select">Select</string>
<string name="bigscreen_right">Right</string>
<string name="bigscreen_down">Down</string>
<string name="pref_plugin_bigscreen">Bigscreen remote</string>
<string name="pref_plugin_bigscreen_desc">Use your device as a remote for Plasma Bigscreen</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">No conectado a ningún dispositivo</string>
<string name="foreground_notification_devices">Conectado a: %s</string>
<string name="foreground_notification_send_clipboard">Enviar al portapapeles</string>
<string name="pref_plugin_telephony">Notificador de telefonía</string>
<string name="pref_plugin_telephony_desc">Enviar notificaciones por llamadas entrantes</string>
<string name="pref_plugin_battery">Informe de la batería</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Permite examinar de forma remota el sistema de archivos de este dispositivo</string>
<string name="pref_plugin_clipboard">Sincronización del portapapeles</string>
<string name="pref_plugin_clipboard_desc">Compartir el contenido del portapapeles</string>
<string name="pref_plugin_clipboard_sent">Enviado al portapapeles</string>
<string name="pref_plugin_mousepad">Entrada remota</string>
<string name="pref_plugin_mousepad_desc">Usar su teléfono o tableta como teclado y teclado táctil</string>
<string name="pref_plugin_presenter">Presentación de diapositivas remota</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Compartir archivos y URL entre dispositivos</string>
<string name="device_list_empty">Ningún dispositivo</string>
<string name="ok">Aceptar</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Cancelar</string>
<string name="open_settings">Abrir preferencias</string>
<string name="no_permissions">Debe otorgar permisos para acceder a las notificaciones</string>
@@ -205,6 +208,7 @@
<string name="refresh">Actualizar</string>
<string name="unreachable_description">Este dispositivo vinculado no está disponible. Asegúrese que está conectado a su misma red.</string>
<string name="no_wifi">No está conectado a una red Wi-Fi, por lo que puede que no vea ningún dispositivo. Pulse aquí para activar el Wi-Fi.</string>
<string name="on_non_trusted_message">No se encuentra en una red confiable: el auto-descubrimiento está desactivado.</string>
<string name="no_file_browser">No hay navegadores de archivos instalados.</string>
<string name="pref_plugin_telepathy">Enviar SMS</string>
<string name="pref_plugin_telepathy_desc">Enviar mensajes de texto desde su escritorio</string>
@@ -212,6 +216,7 @@
<string name="findmyphone_title_tablet">Encontrar mi tableta</string>
<string name="findmyphone_title_tv">Encontrar mi TV</string>
<string name="findmyphone_description">Hace sonar este dispositivo para que pueda encontrarlo</string>
<string name="findmyphone_found">Encontrado</string>
<string name="open">Abrir</string>
<string name="close">Cerrar</string>
<string name="plugins_need_permission">Algunos complementos necesitan permisos para funcionar (pulse para más información):</string>
@@ -242,6 +247,7 @@
<string name="notification_channel_persistent">Indicador persistente</string>
<string name="notification_channel_media_control">Control multimedia</string>
<string name="notification_channel_filetransfer">Transferencia de archivo</string>
<string name="notification_channel_high_priority">Alta prioridad</string>
<string name="mpris_stop">Parar el reproductor actual</string>
<string name="copy_url_to_clipboard">Copiar URL al portapapeles</string>
<string name="clipboard_toast">Copiado en el portapapeles</string>
@@ -275,4 +281,22 @@
<string name="no_app_for_opening">No se encontró ninguna aplicación adecuada para abrir este archivo</string>
<string name="remote_keyboard_service">Teclado remoto de KDE Connect</string>
<string name="presenter_pointer">Puntero</string>
<string name="trusted_networks">Redes confiables</string>
<string name="trusted_networks_desc">Restringir el auto-descubrimiento para redes conocidas</string>
<string name="add_trusted_network">Añadir %1s</string>
<string name="empty_trusted_networks_list_text">No ha añadido ninguna red confiable de momento</string>
<string name="allow_all_networks_text">Permitir todas</string>
<string name="location_permission_needed_title">Permisos requeridos</string>
<string name="location_permission_needed_desc">Android necesita el permiso de localización para identificar su red WiFi</string>
<string name="clipboard_android_x_incompat">Android 10 ha eliminado el acceso al portapapeles para todas las aplicaciones. Este complemento se desactivará.</string>
<string name="mpris_open_url">Continuar reproduciendo aquí</string>
<string name="cant_open_url">No se pudo abrir la URL para continuar reproduciendo</string>
<string name="bigscreen_home">Inicio</string>
<string name="bigscreen_up">Arriba</string>
<string name="bigscreen_left">Izquierda</string>
<string name="bigscreen_select">Seleccionar</string>
<string name="bigscreen_right">Derecha</string>
<string name="bigscreen_down">Abajo</string>
<string name="pref_plugin_bigscreen">Bigscreen remoto</string>
<string name="pref_plugin_bigscreen_desc">Use su dispositivo como mando remoto para Plasma Bigscreen</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Pole ühendatud ühegi seadmega</string>
<string name="foreground_notification_devices">Ühendatud seadmega: %s</string>
<string name="foreground_notification_send_clipboard">Saadeti lõikepuhvrisse</string>
<string name="pref_plugin_telephony">Telefoni märguanded</string>
<string name="pref_plugin_telephony_desc">Sisenevate kõnede märguannete saatmine</string>
<string name="pref_plugin_battery">Aku aruanne</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Seadme failisüsteemi eemalt sirvimise võimaldamine</string>
<string name="pref_plugin_clipboard">Lõikepuhvri sünkroonimine</string>
<string name="pref_plugin_clipboard_desc">Lõikepuhvri sisu jagamine</string>
<string name="pref_plugin_clipboard_sent">Lõikepuhvrist saadud</string>
<string name="pref_plugin_mousepad">Kaugsisestus</string>
<string name="pref_plugin_mousepad_desc">Telefoni või tahvli kasutamine puuteplaadi ja klaviatuurina</string>
<string name="pref_plugin_presenter">Kaugslaidiseanss</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Failide ja URL-ide jagamine seadmete vahel</string>
<string name="device_list_empty">Seadmed puuduvad</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Loobu</string>
<string name="open_settings">Ava seadistused</string>
<string name="no_permissions">Märguannete nägemiseks tuleb anda vastavad õigused</string>
@@ -285,4 +288,15 @@
<string name="allow_all_networks_text">Luba kõik</string>
<string name="location_permission_needed_title">Õigusenõue</string>
<string name="location_permission_needed_desc">Android nõuab asukohaõigust sinu WiFi-võrgu tuvastamiseks</string>
<string name="clipboard_android_x_incompat">Android 10 eemaldas lõikepuhvri kasutamise võimaluse kõigilt rakendustelt. See plugin enam ei tööta.</string>
<string name="mpris_open_url">Jätka esitamist siin</string>
<string name="cant_open_url">URL-i avamine esitamise jätkamiseks nurjus</string>
<string name="bigscreen_home">Kodu</string>
<string name="bigscreen_up">Ülal</string>
<string name="bigscreen_left">Vasakul</string>
<string name="bigscreen_select">Vali</string>
<string name="bigscreen_right">Paremal</string>
<string name="bigscreen_down">All</string>
<string name="pref_plugin_bigscreen">Kaugsuurekraan</string>
<string name="pref_plugin_bigscreen_desc">Oma seadme kasutamine Plasma kaugsuurekraanina</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Non connesso ad alcun dispositivo</string>
<string name="foreground_notification_devices">Connesso a: %s</string>
<string name="foreground_notification_send_clipboard">Invia appunti</string>
<string name="pref_plugin_telephony">Notifiche telefoniche</string>
<string name="pref_plugin_telephony_desc">Invia notifiche per le chiamate in ingresso</string>
<string name="pref_plugin_battery">Livello batteria</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Consente di navigare da remoto il filesystem del dispositivo</string>
<string name="pref_plugin_clipboard">Sincronizzazione appunti</string>
<string name="pref_plugin_clipboard_desc">Condividi il contenuto degli appunti</string>
<string name="pref_plugin_clipboard_sent">Appunti inviati</string>
<string name="pref_plugin_mousepad">Impulso remoto</string>
<string name="pref_plugin_mousepad_desc">Usa il tuo telefono o il tablet come touchpad e tastiera</string>
<string name="pref_plugin_presenter">Telecomando della presentazione</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Condividi file e URL tra i dispositivi</string>
<string name="device_list_empty">Nessun dispositivo</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Annulla</string>
<string name="open_settings">Apri impostazioni</string>
<string name="no_permissions">Devi concedere i permessi per l\'accesso alle notifiche</string>
@@ -205,6 +208,7 @@
<string name="refresh">Aggiorna</string>
<string name="unreachable_description">Questo dispositivo associato non è raggiungibile. Assicurati che sia connesso alla tua stessa rete.</string>
<string name="no_wifi">Non sei connesso a una rete Wi-Fi, per cui non sarai in grado di vedere alcun dispositivo. Fai clic qui per abilitare il Wi-Fi.</string>
<string name="on_non_trusted_message">Non in una rete affidabile: il rilevamento automatico è disabilitato.</string>
<string name="no_file_browser">Non ci sono navigatori di file installati.</string>
<string name="pref_plugin_telepathy">Invia SMS</string>
<string name="pref_plugin_telepathy_desc">Invia messaggi di testo dal tuo desktop</string>
@@ -212,6 +216,7 @@
<string name="findmyphone_title_tablet">Trova il mio tablet</string>
<string name="findmyphone_title_tv">Trova il mio televisore</string>
<string name="findmyphone_description">Fa squillare questo dispositivo per trovarlo</string>
<string name="findmyphone_found">Trovato</string>
<string name="open">Apri</string>
<string name="close">Chiudi</string>
<string name="plugins_need_permission">Alcune estensioni hanno bisogno di permessi per funzionare (tocca per maggiori informazioni):</string>
@@ -242,6 +247,7 @@
<string name="notification_channel_persistent">Indicatore persistente</string>
<string name="notification_channel_media_control">Controllo multimediale</string>
<string name="notification_channel_filetransfer">Trasferimento file</string>
<string name="notification_channel_high_priority">Priorità alta</string>
<string name="mpris_stop">Ferma il lettore attuale</string>
<string name="copy_url_to_clipboard">Copia l\'URL negli appunti</string>
<string name="clipboard_toast">Copiato negli appunti</string>
@@ -275,4 +281,22 @@
<string name="no_app_for_opening">Nessuna applicazione appropriata trovata per aprire questo file</string>
<string name="remote_keyboard_service">Tastiera remota di KDE Connect</string>
<string name="presenter_pointer">Puntatore</string>
<string name="trusted_networks">Reti affidabili</string>
<string name="trusted_networks_desc">Limita il rilevamento automatico alle reti conosciute</string>
<string name="add_trusted_network">Aggiungi %1s</string>
<string name="empty_trusted_networks_list_text">Non hai aggiunto ancora alcuna rete affidabile</string>
<string name="allow_all_networks_text">Consenti tutte</string>
<string name="location_permission_needed_title">Permesso richiesto</string>
<string name="location_permission_needed_desc">Android richiede il permesso Posizione per identificare la tua rete WiFi</string>
<string name="clipboard_android_x_incompat">Android 10 ha rimosso l\'accesso agli appunti a tutte le applicazioni. Questa estensione sarà disabilitata.</string>
<string name="mpris_open_url">Continua qui la riproduzione</string>
<string name="cant_open_url">Impossibile aprire l\'URL per continuare la riproduzione</string>
<string name="bigscreen_home">Inizio</string>
<string name="bigscreen_up">Su</string>
<string name="bigscreen_left">Sinistra</string>
<string name="bigscreen_select">Seleziona</string>
<string name="bigscreen_right">A destra</string>
<string name="bigscreen_down">Giù</string>
<string name="pref_plugin_bigscreen">Telecomando Bigscreen</string>
<string name="pref_plugin_bigscreen_desc">Utilizza il tuo dispositivo come telecomando per Plasma Bigscreen</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">연결된 장치 없음</string>
<string name="foreground_notification_devices">연결됨: %s</string>
<string name="foreground_notification_send_clipboard">클립보드 보내기</string>
<string name="pref_plugin_telephony">전화 알림이</string>
<string name="pref_plugin_telephony_desc">수신 통화 알림 보내기</string>
<string name="pref_plugin_battery">배터리 보고</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">원격으로 이 장치의 파일 시스템 보기</string>
<string name="pref_plugin_clipboard">클립보드 동기화</string>
<string name="pref_plugin_clipboard_desc">클립보드 내용 동기화</string>
<string name="pref_plugin_clipboard_sent">클립보드 보냄</string>
<string name="pref_plugin_mousepad">원격 입력</string>
<string name="pref_plugin_mousepad_desc">내 휴대폰이나 태블릿을 터치패드와 키보드로 사용하기</string>
<string name="pref_plugin_presenter">슬라이드 쇼 리모콘</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">장치끼리 파일과 URL 공유</string>
<string name="device_list_empty">장치 없음</string>
<string name="ok">확인</string>
<string name="sad_ok">확인 :(</string>
<string name="cancel">취소</string>
<string name="open_settings">설정 열기</string>
<string name="no_permissions">알림 접근 권한이 필요합니다</string>
@@ -147,7 +150,7 @@
<string name="protocol_version_newer">이 장치의 프로토콜 버전이 더 새롭습니다</string>
<string name="plugin_settings_with_name">%s 설정</string>
<string name="invalid_device_name">잘못된 장치 이름</string>
<string name="shareplugin_text_saved">텍스트 수신, 클립보드 복사됨</string>
<string name="shareplugin_text_saved">텍스트 수신, 클립보드 복사됨</string>
<string name="custom_devices_settings">사용자 정의 장치 목록</string>
<string name="custom_device_list">IP로 장치 추가</string>
<string name="custom_device_deleted">사용자 정의 장치 삭제됨</string>
@@ -197,6 +200,7 @@
<string name="refresh">새로 고침</string>
<string name="unreachable_description">이 연결된 장치에 접근할 수 없습니다. 같은 네트워크에 있는지 확인하십시오.</string>
<string name="no_wifi">Wi-Fi 네트워크에 연결된 것 같지 않습니다. 다른 장치를 볼 수 없습니다. 여기를 누르면 Wi-Fi를 활성화합니다.</string>
<string name="on_non_trusted_message">신뢰할 수 없는 네트워크: 자동 발견을 비활성화했습니다.</string>
<string name="no_file_browser">설치된 파일 탐색기가 없습니다.</string>
<string name="pref_plugin_telepathy">SMS 보내기</string>
<string name="pref_plugin_telepathy_desc">데스크톱에서 문자 메시지 보내기</string>
@@ -204,6 +208,7 @@
<string name="findmyphone_title_tablet">내 태블릿 찾기</string>
<string name="findmyphone_title_tv">내 TV 찾기</string>
<string name="findmyphone_description">이 장치에서 소리를 울려서 찾는 데 도움을 줍니다</string>
<string name="findmyphone_found">찾았음</string>
<string name="open">열기</string>
<string name="close">닫기</string>
<string name="plugins_need_permission">권한이 필요한 플러그인(정보를 보려면 누르기):</string>
@@ -234,9 +239,10 @@
<string name="notification_channel_persistent">항상 표시된 표시기</string>
<string name="notification_channel_media_control">미디어 제어</string>
<string name="notification_channel_filetransfer">파일 전송</string>
<string name="notification_channel_high_priority">높은 우선 순위</string>
<string name="mpris_stop">현재 재생기 정지</string>
<string name="copy_url_to_clipboard">클립보드로 URL 복사</string>
<string name="clipboard_toast">클립보드 복사됨</string>
<string name="clipboard_toast">클립보드 복사됨</string>
<string name="runcommand_notreachable">장치에 접근할 수 없음</string>
<string name="runcommand_notpaired">장치가 연결되지 않음</string>
<string name="runcommand_nosuchdevice">장치가 없음</string>
@@ -267,4 +273,22 @@
<string name="no_app_for_opening">이 파일을 열 수 있는 앱을 찾을 수 없음</string>
<string name="remote_keyboard_service">KDE Connect 원격 키보드</string>
<string name="presenter_pointer">포인터</string>
<string name="trusted_networks">신뢰할 수 있는 네트워크</string>
<string name="trusted_networks_desc">신뢰할 수 있는 네트워크에서만 자동 발견 사용</string>
<string name="add_trusted_network">%1s 추가</string>
<string name="empty_trusted_networks_list_text">신뢰할 수 있는 네트워크를 추가하지 않았습니다</string>
<string name="allow_all_networks_text">모두 허용</string>
<string name="location_permission_needed_title">권한이 필요함</string>
<string name="location_permission_needed_desc">안드로이드에서 Wi-Fi 네트워크를 식별하려면 위치 권한이 필요합니다</string>
<string name="clipboard_android_x_incompat">안드로이드 10부터는 앱에서 클립보드에 접근할 수 없습니다. 이 플러그인이 비활성화되었습니다.</string>
<string name="mpris_open_url">여기에서 계속 재생</string>
<string name="cant_open_url">계속 재생할 URL을 열 수 없음</string>
<string name="bigscreen_home"></string>
<string name="bigscreen_up"></string>
<string name="bigscreen_left">왼쪽</string>
<string name="bigscreen_select">선택</string>
<string name="bigscreen_right">오른쪽</string>
<string name="bigscreen_down">아래</string>
<string name="pref_plugin_bigscreen">큰 화면 리모콘</string>
<string name="pref_plugin_bigscreen_desc">내 장치를 Plasma 큰 화면의 리모콘으로 사용</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Neprisijungta prie jokio įrenginio</string>
<string name="foreground_notification_devices">Prisijungta prie: %s</string>
<string name="foreground_notification_send_clipboard">Siųsti iškarpinę</string>
<string name="pref_plugin_telephony">Telefonijos pranešiklis</string>
<string name="pref_plugin_telephony_desc">Siųsti gaunamųjų skambučių pranešimus</string>
<string name="pref_plugin_battery">Akumuliatoriaus ataskaita</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Leidžia nuotoliniu būdu naršyti šio įrenginio failų sistemą</string>
<string name="pref_plugin_clipboard">Iškarpinės sinchronizavimas</string>
<string name="pref_plugin_clipboard_desc">Bendrinti iškarpinės turinį</string>
<string name="pref_plugin_clipboard_sent">Iškarpinė išsiųsta</string>
<string name="pref_plugin_mousepad">Nuotolinis įvedimas</string>
<string name="pref_plugin_mousepad_desc">Naudoti savo telefoną ar planšetę kaip jutiklinį kilimėlį ir klaviatūrą</string>
<string name="pref_plugin_presenter">Nuotolinis skaidrių rodymas</string>
@@ -33,8 +35,9 @@
<string name="pref_plugin_sharereceiver_desc">Bendrinti failus ir URL adresus tarp įrenginių</string>
<string name="device_list_empty">Jokių įrenginių</string>
<string name="ok">Gerai</string>
<string name="sad_ok">Gerai :(</string>
<string name="cancel">Atsisakyti</string>
<string name="open_settings">Atverti nustatymus</string>
<string name="open_settings">Atverti nuostatas</string>
<string name="no_permissions">Norėdami gauti prieigą prie pranešimų, turite suteikti leidimą</string>
<string name="no_permission_mprisreceiver">Norėdami valdyti savo medijos leistuves, turite suteikti prieigą prie pranešimų</string>
<string name="no_permissions_remotekeyboard">Norėdami gauti klavišų paspaudimus, turite aktyvuoti KDE Connect nuotolinę klaviatūrą</string>
@@ -74,7 +77,7 @@
<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>
<string name="device_menu_plugins">Priedo nuostatos</string>
<string name="device_menu_plugins">Papildinio nuostatos</string>
<string name="device_menu_unpair">Panaikinti suporavimą</string>
<string name="pair_new_device">Suporuoti naują įrenginį</string>
<string name="unknown_device">Nežinomas įrenginys</string>
@@ -148,7 +151,7 @@
<string name="request_pairing">Užklausti suporuoti</string>
<string name="pairing_accept">Priimti</string>
<string name="pairing_reject">Atmesti</string>
<string name="settings">Nustatyti</string>
<string name="settings">Nuostatos</string>
<string name="mpris_play">Atkurti</string>
<string name="mpris_pause">Pristabdyti</string>
<string name="mpris_previous">Ankstesnis</string>
@@ -232,10 +235,10 @@
<string name="findmyphone_found">Radau</string>
<string name="open">Atverti</string>
<string name="close">Užverti</string>
<string name="plugins_need_permission">Kai kurie priedai tam, kad veiktų, reikalauja leidimų (bakstelėkite išsamesnei informacijai):</string>
<string name="permission_explanation">Šis priedas tam, kad veiktų, reikalauja leidimų</string>
<string name="plugins_need_permission">Kai kurie papildiniai tam, kad veiktų, reikalauja leidimų (bakstelėkite išsamesnei informacijai):</string>
<string name="permission_explanation">Šis papildinys tam, kad veiktų, reikalauja leidimų</string>
<string name="optional_permission_explanation">Norėdami įjungti visas funkcijas, turite suteikti papildomus leidimus</string>
<string name="plugins_need_optional_permission">Kai kurių priedų ypatybės, dėl leidimų trūkumo, buvo išjungtos (bakstelėkite išsamesnei informacijai):</string>
<string name="plugins_need_optional_permission">Kai kurių papildinių ypatybės, dėl leidimų trūkumo, buvo išjungtos (bakstelėkite išsamesnei informacijai):</string>
<string name="share_optional_permission_explanation">Norėdami bendrinti failus tarp savo telefono ir savo darbalaukio, turite suteikti prieigą prie telefono saugyklos</string>
<string name="telepathy_permission_explanation">Norėdami skaityti ir rašyti SMS žinutes iš savo darbalaukio, turite suteikti prieigą prie SMS žinučių</string>
<string name="telephony_permission_explanation">Norėdami matyti telefono skambučius darbalaukyje, turite suteikti prieigą prie telefono skambučių žurnalo ir telefono būsenos</string>
@@ -245,14 +248,14 @@
<string name="telephony_pref_blocked_title">Užblokuoti numeriai</string>
<string name="telephony_pref_blocked_dialog_desc">Nerodyti skambučių ir SMS žinučių iš šių numerių. Nurodykite kiekvienoje eilutėje po vieną</string>
<string name="mpris_coverart_description">Dabartinės įvairialypės terpės iliustracija</string>
<string name="device_icon_description">Įrenginio ženkliukas</string>
<string name="settings_icon_description">Nustatymų ženkliukas</string>
<string name="device_icon_description">Įrenginio piktograma</string>
<string name="settings_icon_description">Nuostatų piktograma</string>
<string name="presenter_fullscreen">Visas ekranas</string>
<string name="presenter_exit">Išeiti iš pristatymo</string>
<string name="presenter_lock_tip">Galite užrakinti savo įrenginį ir perėjimui prie kitos/ankstesnės skaidrės naudoti garsumo mygtukus</string>
<string name="add_command">Pridėti komandą</string>
<string name="addcommand_explanation">Nėra registruota jokių komandų</string>
<string name="addcommand_explanation2">Galite pridėti naujas komandas KDE Connect sistemos nustatymuose</string>
<string name="addcommand_explanation2">Galite pridėti naujas komandas KDE Connect sistemos nuostatose</string>
<string name="add_command_description">Galite pridėti komandas darbalaukyje</string>
<string name="pref_plugin_mprisreceiver">Medijos leistuvės valdymas</string>
<string name="pref_plugin_mprisreceiver_desc">Valdyti savo telefono medijos leistuves iš kito įrenginio</string>
@@ -267,7 +270,7 @@
<string name="runcommand_notreachable">Device is not reachable</string>
<string name="runcommand_notpaired">Device is not paired</string>
<string name="runcommand_nosuchdevice">Nėra tokio įrenginio</string>
<string name="runcommand_noruncommandplugin">Šis įrenginys neturi įjungto priedo Vykdyti komandą</string>
<string name="runcommand_noruncommandplugin">Šis įrenginys neturi įjungto papildinio Vykdyti komandą</string>
<string name="pref_plugin_findremotedevice">Rasti nuotolinį įrenginį</string>
<string name="pref_plugin_findremotedevice_desc">Skambinti į nuotolinį įrenginį</string>
<string name="ring">Skambinti</string>
@@ -278,11 +281,11 @@
<string name="devices">Įrenginiai</string>
<string name="settings_rename">Įrenginio pavadinimas</string>
<string name="settings_dark_mode">Tamsus apipavidalinimas</string>
<string name="settings_more_settings_title">Daugiau nustatymų</string>
<string name="settings_more_settings_text">Nustatymus kiekvienam atskiram įrenginiui galima rasti įrenginyje \"Priedo nustatymuose\".</string>
<string name="settings_more_settings_title">Daugiau nuostatų</string>
<string name="settings_more_settings_text">Nuostatas kiekvienam atskiram įrenginiui galima rasti įrenginyje \"Papildinio nuostatose\".</string>
<string name="setting_persistent_notification">Rodyti pastovų pranešimą</string>
<string name="setting_persistent_notification_oreo">Pastovus pranešimas</string>
<string name="setting_persistent_notification_description">Bakstelėkite, norėdami įjungti/išjungti Pranešimų nustatymuose</string>
<string name="setting_persistent_notification_description">Bakstelėkite, norėdami įjungti/išjungti Pranešimų nuostatose</string>
<string name="extra_options">Papildomos parinktys</string>
<string name="privacy_options">Privatumo parinktys</string>
<string name="set_privacy_options">Nustatyti savo privatumo parinktis</string>
@@ -301,4 +304,15 @@
<string name="allow_all_networks_text">Leisti visus</string>
<string name="location_permission_needed_title">Reikalingas leidimas</string>
<string name="location_permission_needed_desc">Android reikalauja Vietos leidimo, kad atpažintų jūsų belaidį (WiFi) tinklą</string>
<string name="clipboard_android_x_incompat">Android 10 pašalino iškarpinės prieigą prie visų programėlių. Šis papildinys bus išjungtas.</string>
<string name="mpris_open_url">Tęsti atkūrimą čia</string>
<string name="cant_open_url">Nepavyksta atverti URL, kad būtų tęsiamas atkūrimas</string>
<string name="bigscreen_home">Pradžia</string>
<string name="bigscreen_up">Aukštyn</string>
<string name="bigscreen_left">Kairėn</string>
<string name="bigscreen_select">Pasirinkti</string>
<string name="bigscreen_right">Dešinėn</string>
<string name="bigscreen_down">Žemyn</string>
<string name="pref_plugin_bigscreen">Bigscreen nuotolinis pultas</string>
<string name="pref_plugin_bigscreen_desc">Naudoti savo įrenginį kaip Plasma Bigscreen nuotolinį pultą</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Niet verbonden met enig apparaat</string>
<string name="foreground_notification_devices">Verbonden met: %s</string>
<string name="foreground_notification_send_clipboard">Klembord verzenden</string>
<string name="pref_plugin_telephony">Telefoniemelder</string>
<string name="pref_plugin_telephony_desc">Stuur meldingen voor inkomende oproepen</string>
<string name="pref_plugin_battery">Batterijrapportage</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Het bladeren in het bestandssysteem van het apparaat op afstand toestaan</string>
<string name="pref_plugin_clipboard">Klembordsynchronisatie</string>
<string name="pref_plugin_clipboard_desc">De inhoud van het klembord delen</string>
<string name="pref_plugin_clipboard_sent">Klembord verzonden</string>
<string name="pref_plugin_mousepad">Invoer op afstand</string>
<string name="pref_plugin_mousepad_desc">Uw telefoon of tablet gebruiken als een touchpad en toetsenbord</string>
<string name="pref_plugin_presenter">Diavoorstelling op afstand</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Bestanden en URL\'s delen tussen apparaten</string>
<string name="device_list_empty">Geen apparaten</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Annuleren</string>
<string name="open_settings">Instellingen openen</string>
<string name="no_permissions">U moet toestemming geven voor toegang tot meldingen</string>
@@ -285,4 +288,15 @@
<string name="allow_all_networks_text">Allen toestaan</string>
<string name="location_permission_needed_title">Toestemming vereist</string>
<string name="location_permission_needed_desc">Android vereist de toestemming voor locatie om uw WiFi-netwerk te identificeren</string>
<string name="clipboard_android_x_incompat">Android 10 heeft toegang tot het klembord naar alle toepassingen verwijderd. Deze plug-in zal uitgeschakeld worden.</string>
<string name="mpris_open_url">Hier doorgaan met afspelen</string>
<string name="cant_open_url">Kan URL niet openen om door te gaan met afspelen</string>
<string name="bigscreen_home">Home</string>
<string name="bigscreen_up">Omhoog</string>
<string name="bigscreen_left">Links</string>
<string name="bigscreen_select">Selecteren</string>
<string name="bigscreen_right">Rechts</string>
<string name="bigscreen_down">Omlaag</string>
<string name="pref_plugin_bigscreen">Bigscreen op afstand</string>
<string name="pref_plugin_bigscreen_desc">Gebruik uw apparaat als een Bigscreen op afstand</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Ikkje tilkopla ei eining</string>
<string name="foreground_notification_devices">Kopla til: %s</string>
<string name="foreground_notification_send_clipboard">Send utklippstavle</string>
<string name="pref_plugin_telephony">Telefonvarsling</string>
<string name="pref_plugin_telephony_desc">Send varsling ved oppringing</string>
<string name="pref_plugin_battery">Batterirapport</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Tillat lesing av filsystemet frå datamaskina</string>
<string name="pref_plugin_clipboard">Synkroniser utklippstavle</string>
<string name="pref_plugin_clipboard_desc">Del innhaldet på utklippstavla</string>
<string name="pref_plugin_clipboard_sent">Utklippstavle send</string>
<string name="pref_plugin_mousepad">Fjernstyring</string>
<string name="pref_plugin_mousepad_desc">Bruk telefonen eller nettbrettet som styreplate og tastatur</string>
<string name="pref_plugin_presenter">Fjernstyring av lysbiletvising</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Del filer og nettadresser mellom einingar</string>
<string name="device_list_empty">Ingen einingar</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Avbryt</string>
<string name="open_settings">Opna innstillingar</string>
<string name="no_permissions">Du må gje tilgang til lesing av varslingar</string>
@@ -205,6 +208,7 @@
<string name="refresh">Oppdater</string>
<string name="unreachable_description">Får ikkje kontakt med den para eininga. Sjå til at ho er kopla til same nettverk.</string>
<string name="no_wifi">Du er ikkje kopla til eit Wi-Fi-nettverk, så du vil ikkje kunna sjå nokon einingar. Trykk her for å slå på Wi-Fi.</string>
<string name="on_non_trusted_message">Ikkje på eit tiltrudd nettverk: autooppdaging er slått av.</string>
<string name="no_file_browser">Ingen filhandsamarar er installerte.</string>
<string name="pref_plugin_telepathy">Send SMS</string>
<string name="pref_plugin_telepathy_desc">Send tekstmeldingar frå datamaskina</string>
@@ -212,7 +216,7 @@
<string name="findmyphone_title_tablet">Finn nettbrettet mitt</string>
<string name="findmyphone_title_tv">Finn TV-en min</string>
<string name="findmyphone_description">Spel av lydsignal på eininga, slik at du lett kan finna ho</string>
<string name="findmyphone_found">Funnen</string>
<string name="findmyphone_found">Fann han</string>
<string name="open">Opna</string>
<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>
@@ -243,6 +247,7 @@
<string name="notification_channel_persistent">Evigvarande varslingar</string>
<string name="notification_channel_media_control">Mediestyring</string>
<string name="notification_channel_filetransfer">Filoverføring</string>
<string name="notification_channel_high_priority">Høg prioritet</string>
<string name="mpris_stop">Stopp gjeldande avspelar</string>
<string name="copy_url_to_clipboard">Kopier adresse til utklippstavla</string>
<string name="clipboard_toast">Kopiert til utklippstavla</string>
@@ -276,4 +281,22 @@
<string name="no_app_for_opening">Fann ikkje nokon app som kan opna denne fila</string>
<string name="remote_keyboard_service">KDE Connect fjerntastatur</string>
<string name="presenter_pointer">Peikar</string>
<string name="trusted_networks">Tiltrudde nettverk</string>
<string name="trusted_networks_desc">Avgrens autooppdaging til kjende nettverk</string>
<string name="add_trusted_network">Legg til %1s</string>
<string name="empty_trusted_networks_list_text">Du har ikkje lagt til eit tiltrudd nettverk enno</string>
<string name="allow_all_networks_text">Tillat alle</string>
<string name="location_permission_needed_title">Krev utvida løyve</string>
<string name="location_permission_needed_desc">Tilgang til geografisk plassering må vera påslått for identifisering av Wi-Fi-nettverket</string>
<string name="clipboard_android_x_incompat">Android 10 har fjerna tilgang til utklippstavla for alle program. Programtillegget vert derfor slått av.</string>
<string name="mpris_open_url">Hald fram avspeling her</string>
<string name="cant_open_url">Kan ikkje opna adressa for framhald av avspeling</string>
<string name="bigscreen_home">Heim</string>
<string name="bigscreen_up">Opp</string>
<string name="bigscreen_left">Venstre</string>
<string name="bigscreen_select">Vel</string>
<string name="bigscreen_right">Høgre</string>
<string name="bigscreen_down">Ned</string>
<string name="pref_plugin_bigscreen">Bigscreen-fjernkontroll</string>
<string name="pref_plugin_bigscreen_desc">Bruk eininga som fjernkontroll for Plasma Bigscreen</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Não está conectado a nenhum dispositivo</string>
<string name="foreground_notification_devices">Conectado a: %s</string>
<string name="foreground_notification_send_clipboard">Enviar área de transferência</string>
<string name="pref_plugin_telephony">Notificação de telefonia</string>
<string name="pref_plugin_telephony_desc">Envia notificações de chamadas recebidas</string>
<string name="pref_plugin_battery">Relatório da bateria</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Permite navegar remotamente pelo sistema de arquivos deste telefone</string>
<string name="pref_plugin_clipboard">Sincronizar área de transferência</string>
<string name="pref_plugin_clipboard_desc">Compartilha o conteúdo da área de transferência</string>
<string name="pref_plugin_clipboard_sent">Área de transferência enviada</string>
<string name="pref_plugin_mousepad">Introdução de dados remota</string>
<string name="pref_plugin_mousepad_desc">Use seu telefone ou tablet como mouse e teclado</string>
<string name="pref_plugin_presenter">Apresentação de slides remota</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Compartilha arquivos e URLs entre os dispositivos</string>
<string name="device_list_empty">Sem dispositivos</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Cancelar</string>
<string name="open_settings">Abrir configurações</string>
<string name="no_permissions">Você precisa conceder permissão para acessar as notificações</string>
@@ -285,4 +288,15 @@
<string name="allow_all_networks_text">Permitir tudo</string>
<string name="location_permission_needed_title">É necessário ter permissão</string>
<string name="location_permission_needed_desc">O Android precisa da permissão de Localização para identificar a sua rede Wi-Fi</string>
<string name="clipboard_android_x_incompat">O Android 10 removeu o acesso à área de transferência para todos os aplicativos. Este plugin ficará desativado.</string>
<string name="mpris_open_url">Continuar tocando aqui</string>
<string name="cant_open_url">Não foi possível abrir a URL para continuar tocando</string>
<string name="bigscreen_home">Início</string>
<string name="bigscreen_up">Para cima</string>
<string name="bigscreen_left">Esquerda</string>
<string name="bigscreen_select">Selecionar</string>
<string name="bigscreen_right">Direita</string>
<string name="bigscreen_down">Para baixo</string>
<string name="pref_plugin_bigscreen">Controle remoto do Bigscreen</string>
<string name="pref_plugin_bigscreen_desc">Use seu dispositivo como um controle remoto para o Plasma Bigscreen</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Não está ligado a nenhum dispositivo</string>
<string name="foreground_notification_devices">Ligado a: %s</string>
<string name="foreground_notification_send_clipboard">Enviar para a Área de Transferência</string>
<string name="pref_plugin_telephony">Notificação telefónica</string>
<string name="pref_plugin_telephony_desc">Enviar notificações para as chamadas recebidas</string>
<string name="pref_plugin_battery">Relatório da bateria</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Permite navegar pelo sistema de ficheiros remoto deste dispositivo</string>
<string name="pref_plugin_clipboard">Sincronização da área de transferência</string>
<string name="pref_plugin_clipboard_desc">Partilhar o conteúdo da área de transferência</string>
<string name="pref_plugin_clipboard_sent">Enviado para a Área de Transferência</string>
<string name="pref_plugin_mousepad">Introdução remota de dados</string>
<string name="pref_plugin_mousepad_desc">Usar o seu telefone ou \'tablet\' como um rato ou teclado</string>
<string name="pref_plugin_presenter">Apresentação remota</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Partilhar ficheiros e URL\'s entre dispositivos</string>
<string name="device_list_empty">Sem dispositivos</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Cancelar</string>
<string name="open_settings">Abrir a configuração</string>
<string name="no_permissions">Precisa de dar permissões de acesso às notificações</string>
@@ -285,4 +288,15 @@
<string name="allow_all_networks_text">Permitir tudo</string>
<string name="location_permission_needed_title">É necessária a permissão</string>
<string name="location_permission_needed_desc">O Android precisa da permissão de Localização para identificar a sua rede WiFi</string>
<string name="clipboard_android_x_incompat">O Android 10 removeu o acesso à área de transferência para todas as aplicações. Este \'plugin\' ficará desactivado.</string>
<string name="mpris_open_url">Continuar a tocar aqui</string>
<string name="cant_open_url">Não é possível abrir o URL para continuar a tocar</string>
<string name="bigscreen_home">Início</string>
<string name="bigscreen_up">Cima</string>
<string name="bigscreen_left">Esquerda</string>
<string name="bigscreen_select">Seleccionar</string>
<string name="bigscreen_right">Direita</string>
<string name="bigscreen_down">Baixo</string>
<string name="pref_plugin_bigscreen">Comando à distância do ecrã grande</string>
<string name="pref_plugin_bigscreen_desc">Use o seu dispositivo como um comando à distância para o Plasma em Ecrã Grande</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Не подключено ни к одному устройству</string>
<string name="foreground_notification_devices">Подключено к: %s</string>
<string name="foreground_notification_send_clipboard">Передать буфер обмена</string>
<string name="pref_plugin_telephony">События телефонии</string>
<string name="pref_plugin_telephony_desc">Отправка уведомлений о звонках</string>
<string name="pref_plugin_battery">Состояние батареи</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Позволяет удалённо просматривать файловую систему устройства</string>
<string name="pref_plugin_clipboard">Синхронизация буфера обмена</string>
<string name="pref_plugin_clipboard_desc">Использование общего буфера обмена</string>
<string name="pref_plugin_clipboard_sent">Буфер обмена передан</string>
<string name="pref_plugin_mousepad">Удалённый ввод</string>
<string name="pref_plugin_mousepad_desc">Использование телефона или планшета в качестве сенсорной панели и клавиатуры</string>
<string name="pref_plugin_presenter">Пульт управления слайд-шоу</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Пересылка файлов и адресов URL между устройствами</string>
<string name="device_list_empty">Нет устройств</string>
<string name="ok">ОК</string>
<string name="sad_ok">ОК :(</string>
<string name="cancel">Отмена</string>
<string name="open_settings">Настроить</string>
<string name="no_permissions">Нужно разрешить доступ к уведомлениям</string>
@@ -220,6 +223,8 @@
<string name="device_rename_confirm">Переименовать</string>
<string name="refresh">Обновить</string>
<string name="unreachable_description">Это сопряжённое устройство недоступно. Проверьте, что оно подключено к той же локальной сети.</string>
<string name="no_wifi">Другие устройства недоступны, так как вы не подключены к сети Wi-Fi. Нажмите здесь для включения Wi-Fi.</string>
<string name="on_non_trusted_message">Автоматическое обнаружение отключено, так как вы подключены к недоверенной сети.</string>
<string name="no_file_browser">Не удалось открыть диалог выбора файла.</string>
<string name="pref_plugin_telepathy">Отправка SMS</string>
<string name="pref_plugin_telepathy_desc">Отправка SMS-сообщений с вашего компьютера</string>
@@ -227,6 +232,7 @@
<string name="findmyphone_title_tablet">Поиск планшета</string>
<string name="findmyphone_title_tv">Поиск телевизора</string>
<string name="findmyphone_description">Подача звукового сигнала на устройстве, чтобы вы могли его найти</string>
<string name="findmyphone_found">Найден</string>
<string name="open">Открыть</string>
<string name="close">Закрыть</string>
<string name="plugins_need_permission">Некоторым модулям нужны разрешения для работы (нажмите для просмотра подробностей):</string>
@@ -252,10 +258,12 @@
<string name="addcommand_explanation2">Вы можете добавить новые команды в «Параметрах системы» в разделе «KDE Connect».</string>
<string name="add_command_description">Команды возможно добавлять с ПК</string>
<string name="pref_plugin_mprisreceiver">Управление мультимедиа</string>
<string name="pref_plugin_mprisreceiver_desc">Управление воспроизведением на телефоне с другого устройства</string>
<string name="notification_channel_default">Прочие уведомления</string>
<string name="notification_channel_persistent">Постоянный индикатор</string>
<string name="notification_channel_media_control">Управление воспроизведением</string>
<string name="notification_channel_filetransfer">Передача файлов</string>
<string name="notification_channel_high_priority">Высокий приоритет</string>
<string name="mpris_stop">Остановить воспроизведение</string>
<string name="copy_url_to_clipboard">Копировать URL в буфер обмена</string>
<string name="clipboard_toast">Скопировано в буфер обмена</string>
@@ -289,4 +297,12 @@
<string name="no_app_for_opening">Для этого файла нет приложений, способных его открыть</string>
<string name="remote_keyboard_service">Удалённая клавиатура KDE Connect</string>
<string name="presenter_pointer">Указатель</string>
<string name="trusted_networks">Доверенные сети</string>
<string name="trusted_networks_desc">Не использовать автоматическое обнаружение в недоверенных сетях</string>
<string name="add_trusted_network">Добавить %1s</string>
<string name="empty_trusted_networks_list_text">Пока нет ни одной доверенной сети</string>
<string name="allow_all_networks_text">Разрешить во всех сетях</string>
<string name="location_permission_needed_title">Требуется разрешение</string>
<string name="location_permission_needed_desc">Для получения сведений о Wi-Fi подключении на ОС Android требуются разрешение доступа к службе определения местоположения</string>
<string name="clipboard_android_x_incompat">В ОС Android версии 10 для всех приложений был запрещён доступ к буферу. Этот подключаемый модуль будет отключён.</string>
</resources>

View File

@@ -3,65 +3,68 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Nepripojené k žiadnemu zariadeniu</string>
<string name="foreground_notification_devices">Pripojené k: %s</string>
<string name="pref_plugin_telephony">Telefónny notifikátor</string>
<string name="pref_plugin_telephony_desc">Poslať oznámenia pre prichádzajúce hovory</string>
<string name="pref_plugin_battery">Oznam o batérii</string>
<string name="pref_plugin_battery_desc">Periodicky oznamovať stav batérie</string>
<string name="pref_plugin_sftp">Odhaliť súborový systém</string>
<string name="pref_plugin_sftp_desc">Umožní prehliadač súborový systém zariadenia vzdialene</string>
<string name="foreground_notification_send_clipboard">Odoslať schránku</string>
<string name="pref_plugin_telephony">Nástroj na upozornenie telefonátov</string>
<string name="pref_plugin_telephony_desc">Odošle upozornenia na prichádzajúce hovory</string>
<string name="pref_plugin_battery">Hlásenia batérie</string>
<string name="pref_plugin_battery_desc">Pravidelne hlási stav batérie</string>
<string name="pref_plugin_sftp">Odhalenie súborového systému</string>
<string name="pref_plugin_sftp_desc">Umožní vzdialené prehliadanie súborového systému zariadenia</string>
<string name="pref_plugin_clipboard">Synchronizácia schránky</string>
<string name="pref_plugin_clipboard_desc">Zdieľať obsah schránky</string>
<string name="pref_plugin_clipboard_desc">Zdieľa obsah schránky</string>
<string name="pref_plugin_clipboard_sent">Schránka odoslaná</string>
<string name="pref_plugin_mousepad">Vzdialený vstup</string>
<string name="pref_plugin_mousepad_desc">Použiť váš telefón alebo tablet ako touchpad a klávesnicu</string>
<string name="pref_plugin_mousepad_desc">Použije váš telefón alebo tablet ako touchpad a klávesnicu</string>
<string name="pref_plugin_presenter">Diaľkový ovládač prezentácie</string>
<string name="pref_plugin_presenter_desc">Používajte vaše zariadenie na posúvanie stránok prezentácie</string>
<string name="pref_plugin_remotekeyboard">Prijímať vzdialené stlačenia klávesov</string>
<string name="pref_plugin_remotekeyboard_desc">Prjímať udalosti stlačenia kláves z diaľkových zariadení</string>
<string name="pref_plugin_presenter_desc">Použije vaše zariadenie na zmenu snímok prezentácie</string>
<string name="pref_plugin_remotekeyboard">Prijímanie vzdialených stlačení klávesov</string>
<string name="pref_plugin_remotekeyboard_desc">Prijme udalosti stlačenia klávesov z diaľkových zariadení</string>
<string name="pref_plugin_mpris">Multimediálne ovládače</string>
<string name="pref_plugin_mpris_desc">Poskytuje vzdialené ovládanie pre váš prehrávač médií</string>
<string name="pref_plugin_runcommand">Spust príkaz</string>
<string name="pref_plugin_runcommand_desc">Vyvol vzdialené príkazy z vášho mobilu alebo tabletu</string>
<string name="pref_plugin_contacts">Synchronizér kontaktov</string>
<string name="pref_plugin_contacts_desc">Povoliť synchronizáciu kontaktov zo zariadenia</string>
<string name="pref_plugin_mpris_desc">Poskytuje diaľkové ovládanie pre váš prehrávač médií</string>
<string name="pref_plugin_runcommand">Spustenie príkazu</string>
<string name="pref_plugin_runcommand_desc">Vyvolá vzdialené príkazy z vášho telefónu alebo tabletu</string>
<string name="pref_plugin_contacts">Nástroj na synchronizáciu kontaktov</string>
<string name="pref_plugin_contacts_desc">Umožní synchronizáciu adresára kontaktov zariadenia</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Poslať a prij pingy</string>
<string name="pref_plugin_notifications">Synchronizácia pripomienok</string>
<string name="pref_plugin_notifications_desc">Prístup k vašim pripomienkam z iných zariadení</string>
<string name="pref_plugin_receive_notifications">Prij upozornenia</string>
<string name="pref_plugin_receive_notifications_desc">Prístup k pripomienkam z iných zariadení a zobrazenie ich na Androide</string>
<string name="pref_plugin_sharereceiver">Zdieľať a prij</string>
<string name="pref_plugin_sharereceiver_desc">Zdieľať súbory a medzi zariadeniami</string>
<string name="pref_plugin_ping_desc">Odošle a prijme signály ping</string>
<string name="pref_plugin_notifications">Synchronizácia upozornení</string>
<string name="pref_plugin_notifications_desc">Umožní prístup k vašim upozorneniam iných zariadení</string>
<string name="pref_plugin_receive_notifications">Prijímanie upozornení</string>
<string name="pref_plugin_receive_notifications_desc">Prijme upozornenia z iného zariadenia a zobrazí ich v systéme Android</string>
<string name="pref_plugin_sharereceiver">Zdieľanie a prijímanie</string>
<string name="pref_plugin_sharereceiver_desc">Zdieľa súbory a URL medzi zariadeniami</string>
<string name="device_list_empty">Žiadne zariadenia</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Zrušiť</string>
<string name="open_settings">Otvoriť nastavenia</string>
<string name="no_permissions">Musíte povoliť oprávnenia na prístup k pripomienkam</string>
<string name="no_permission_mprisreceiver">Aby ste mohli ovládať prehrávače médií musíte udeliť oprávnenie pristupovať k oznámeniam.</string>
<string name="no_permissions_remotekeyboard">Ak chcete prijímať stlačenia klávesov, musíte aktivovať KDE Connect Vzdialená Klávesnica</string>
<string name="send_ping">Poslať ping</string>
<string name="no_permissions">Musíte udeliť oprávnenia na prístup k upozorneniam</string>
<string name="no_permission_mprisreceiver">Aby ste mohli ovládať multimediálne prehrávače, musíte udeliť prístup k upozorneniam</string>
<string name="no_permissions_remotekeyboard">Na prijímanie stlačenia klávesov, musíte aktivovať vzdialenú klávesnicu aplikácie KDE Connect</string>
<string name="send_ping">Odoslať ping</string>
<string name="open_mpris_controls">Multimediálny ovládač</string>
<string name="remotekeyboard_editing_only_title">Spracovať vzdialené klávesy iba počas upravovania</string>
<string name="remotekeyboard_not_connected">Nie je dostupné žiadne aktívne pripojenie ku klávesnici, nastavte ho v kdeconnect</string>
<string name="remotekeyboard_connected">Pripojenie ku vzdialenej klávesnici je aktívne</string>
<string name="remotekeyboard_multiple_connections">Je dostupných viac vzdialených klávesníc, vyberte jednu na nastavenie</string>
<string name="remotekeyboard_not_connected">Nie je žiadne aktívne pripojenie k vzdialenej klávesnici. Vytvorte nejaké v aplikácii kdeconnect</string>
<string name="remotekeyboard_connected">Pripojenie k vzdialenej klávesnici je aktívne</string>
<string name="remotekeyboard_multiple_connections">Je dostupných viac pripojení k vzdialeným klávesniciam, vyberte zariadenie na nastavenie</string>
<string name="open_mousepad">Vzdialený vstup</string>
<string name="mousepad_info">Posúvajte prst na obrazovke na posun kurzora. Ťuknutie vyvolá klik a použite dva/tri prsty pre pravé a stredné tlačidlo. Použite dva prsty na posúvanie. Použite dlhé stlačenie pre drag and drop.</string>
<string name="mousepad_double_tap_settings_title">Nastaviť akciu dvoch prstov</string>
<string name="mousepad_triple_tap_settings_title">Nastaviť akciu troch prstov</string>
<string name="mousepad_info">Posúvajte prst na obrazovke pre pohyb kurzorom. Ťuknutím kliknete a použitím dvoch/troch prstov stlačíte pravé a stredné tlačidlo. Použitím dvoch prstov rolujete. Použite dlhého stlačenia vykonáte ťahanie a spustenie.</string>
<string name="mousepad_double_tap_settings_title">Nastaviť akciu po ťuknutí dvoma prstami</string>
<string name="mousepad_triple_tap_settings_title">Nastaviť akciu po ťuknutí troma prstami</string>
<string name="mousepad_sensitivity_settings_title">Nastaviť citlivosť touchpadu</string>
<string name="mousepad_acceleration_profile_settings_title">Nastaviť zrýchlenie ukazovateľa</string>
<string name="mousepad_scroll_direction_title">Obrátený smer rolovania</string>
<string name="mousepad_scroll_direction_title">Obrát smer rolovania</string>
<string-array name="mousepad_tap_entries">
<item>Kliknutie pravým tlačidlom</item>
<item>Stredný klik</item>
<item>Nič</item>
<item>Kliknutie stredným tlačidlom</item>
<item>Žiadna</item>
</string-array>
<string-array name="mousepad_sensitivity_entries">
<item>Najpomalšie</item>
<item>Nad najpomalším</item>
<item>Predvolené</item>
<item>Nad priemerným</item>
<item>Najrýchlejšie</item>
<item>Najpomalšia</item>
<item>Pomalá</item>
<item>Predvolená</item>
<item>Rýchla</item>
<item>Najrýchlejšia</item>
</string-array>
<string-array name="mousepad_acceleration_profile_entries">
<item>Žiadne zrýchlenie</item>
@@ -74,26 +77,26 @@
<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>
<string name="device_menu_plugins">Nastavenia pluginu</string>
<string name="device_menu_unpair">Odpárovať</string>
<string name="device_menu_plugins">Nastavenia zás. modulu</string>
<string name="device_menu_unpair">Zrušiť párovanie</string>
<string name="pair_new_device">Spárovať nové zariadenie</string>
<string name="unknown_device">Neznáme zariadenie</string>
<string name="error_not_reachable">Zariadenie nedostup</string>
<string name="error_already_paired">Zariadenie už spárované</string>
<string name="error_could_not_send_package">Nemôžem poslať balík</string>
<string name="error_not_reachable">Zariadenie nie je dosiahnuteľ</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é iným klientom</string>
<string name="encryption_info_title">Informácia o šifrovaní</string>
<string name="encryption_info_msg_no_ssl">Ďalšie zariadenie nepoužíva aktuálnu verziu KDE Connect, používam klasickú metódu šifrovania.</string>
<string name="my_device_fingerprint">Odtlačok SHA1 vášho certifikátu zariadenia je:</string>
<string name="remote_device_fingerprint">Odtlačok SHA1 vzdialeného certifikátu zariadenia je:</string>
<string name="error_canceled_by_other_peer">Zrušené druhým účastníkom</string>
<string name="encryption_info_title">Informácie o šifrovaní</string>
<string name="encryption_info_msg_no_ssl">Druhé zariadenie nepoužíva najnovšiu verziu aplikácie KDE Connect. Použije sa zastaralý spôsob šifrovania.</string>
<string name="my_device_fingerprint">Odtlačok SHA1 certifikátu vášho zariadenia je:</string>
<string name="remote_device_fingerprint">Odtlačok SHA1 certifikátu vzdialeného zariadenia je:</string>
<string name="pair_requested">Spárovanie vyžiadané</string>
<string name="pairing_request_from">Požiadavka na spárovanie od %1s</string>
<string name="pairing_request_from">Požiadavka na spárovanie zo zariadenia %1s</string>
<plurals name="incoming_file_title">
<item quantity="one">Prijímam %1$d súbor z %2$s</item>
<item quantity="few">Prijímam %1$d súbory z %2$s</item>
<item quantity="many">Prijímam %1$d súborov z %2$s</item>
<item quantity="one">Prijíma sa %1$d súbor z %2$s</item>
<item quantity="few">Prijímajú sa %1$d súbory z %2$s</item>
<item quantity="many">Prijíma sa %1$d súborov z %2$s</item>
<item quantity="other"/>
</plurals>
<plurals name="incoming_files_text">
@@ -103,9 +106,9 @@
<item quantity="other"/>
</plurals>
<plurals name="outgoing_file_title">
<item quantity="one">Posielam %1$d súbor do %2$s</item>
<item quantity="few">Posielam %1$d súbory do %2$s</item>
<item quantity="many">Posielam %1$d súborov do %2$s</item>
<item quantity="one">Odosiela sa %1$d súbor do zariadenia %2$s</item>
<item quantity="few">Odosielajú sa %1$d súbory do zariadenia %2$s</item>
<item quantity="many">Odosiela sa %1$d súborov do zariadenia %2$s</item>
<item quantity="other"/>
</plurals>
<plurals name="outgoing_files_text">
@@ -115,37 +118,37 @@
<item quantity="other"/>
</plurals>
<plurals name="received_files_title">
<item quantity="one">Prijatý súbor od %1$s</item>
<item quantity="few">Prijaté %2$d súbory od %1$s</item>
<item quantity="many">Prijatých %2$d súborov od %1$s</item>
<item quantity="one">Prijatý súbor zo zariadenia %1$s</item>
<item quantity="few">Prijaté %2$d súbory zo zariadenia %1$s</item>
<item quantity="many">Prijatých %2$d súborov zo zariadenia %1$s</item>
<item quantity="other"/>
</plurals>
<plurals name="received_files_fail_title">
<item quantity="one">Zlyhalo prijatie súboru od %1$s</item>
<item quantity="few">Zlyhalo prijatie %2$d z %3$d súborov od %1$s</item>
<item quantity="many">Zlyhalo prijatie %2$d z %3$d súborov od %1$s</item>
<item quantity="one">Zlyhalo prijatie súboru zo zariadenia %1$s</item>
<item quantity="few">Zlyhalo prijatie %2$d súborov z %3$d zo zariadenia %1$s</item>
<item quantity="many">Zlyhalo prijatie %2$d súborov z %3$d zo zariadenia %1$s</item>
<item quantity="other"/>
</plurals>
<plurals name="sent_files_title">
<item quantity="one">Poslať súbor do %1$s</item>
<item quantity="few">Poslať %2$d súbory do %1$s</item>
<item quantity="many">Poslať %2$d súborov do %1$s</item>
<item quantity="one">Odosla súbor do zariadenia %1$s</item>
<item quantity="few">Odosla %2$d súbory do zariadenia %1$s</item>
<item quantity="many">Odoslaných %2$d súborov do zariadenia %1$s</item>
<item quantity="other"/>
</plurals>
<plurals name="send_files_fail_title">
<item quantity="one">Zlyhalo odoslanie súboru do %1$s</item>
<item quantity="few">Zlyhalo odoslanie %2$d z %3$d súborov do %1$s</item>
<item quantity="many">Zlyhalo odoslanie %2$d z %3$d súborov do %1$s</item>
<item quantity="one">Zlyhalo odoslanie súboru do zariadenia %1$s</item>
<item quantity="few">Zlyhalo odoslanie %2$d súborov z %3$d do zariadenia %1$s</item>
<item quantity="many">Zlyhalo odoslanie %2$d súborov z %3$d do zariadenia %1$s</item>
<item quantity="other"/>
</plurals>
<string name="received_file_text">Ťuknite na otvorenie \'%1s\'</string>
<string name="cannot_create_file">Nomožno vytvoriť súbor %s</string>
<string name="tap_to_answer">Tapnite na odpoveď</string>
<string name="right_click">Poslať kliknutie pravým</string>
<string name="middle_click">Poslať kliknutie stredným</string>
<string name="received_file_text">Ťuknutím otvoríte súbor \"%1s\"</string>
<string name="cannot_create_file">Nedá sa vytvoriť súbor %s</string>
<string name="tap_to_answer">Ťuknutím odpoviete</string>
<string name="right_click">Odoslať kliknutie pravým tlačidlom</string>
<string name="middle_click">Odoslať kliknutie stredným tlačidlom</string>
<string name="show_keyboard">Zobraziť klávesnicu</string>
<string name="device_not_paired">Zariadenie nespárované</string>
<string name="request_pairing">Požiadavka na spárovanie</string>
<string name="device_not_paired">Zariadenie nie je spárované</string>
<string name="request_pairing">Požiadať o spárovanie</string>
<string name="pairing_accept">Prijať</string>
<string name="pairing_reject">Odmietnuť</string>
<string name="settings">Nastavenia</string>
@@ -156,8 +159,8 @@
<string name="mpris_ff">Pretočiť dopredu</string>
<string name="mpris_next">Nasledovné</string>
<string name="mpris_volume">Hlasitosť</string>
<string name="mpris_time_settings_title">Tlačidlá dopredu/pretočiť</string>
<string name="mpris_time_settings_summary">Prispôsobiť čas na pretáčanie dopredu alebo dozadu pri stlačení</string>
<string name="mpris_time_settings_title">Tlačidlá pretočenia dopredu/dozadu</string>
<string name="mpris_time_settings_summary">Upraviť čas pretáčania dopredu/dozadu po stlačení tlačidla</string>
<string-array name="mpris_time_entries">
<item>10 sekúnd</item>
<item>20 sekúnd</item>
@@ -165,129 +168,151 @@
<item>1 minúta</item>
<item>2 minúty</item>
</string-array>
<string name="mpris_notification_settings_title">Zobraziť oznámenie ovládania médií</string>
<string name="mpris_notification_settings_summary">Povoliť ovládanie vaších prehrávačov médií bez otvárania KDE Connect</string>
<string name="mpris_notification_settings_title">Zobraziť upozornenie ovládania médií</string>
<string name="mpris_notification_settings_summary">Umožní ovládanie vašich multimediálnych prehrávačov bez otvorenia aplikácie KDE Connect</string>
<string name="share_to">Zdieľať do...</string>
<string name="protocol_version_newer">Toto zariadenie používa novšiu verziu protokolu</string>
<string name="plugin_settings_with_name">%s nastavenia</string>
<string name="plugin_settings_with_name">Nastavenia modulu %s</string>
<string name="invalid_device_name">Neplatný názov zariadenia</string>
<string name="shareplugin_text_saved">Prijatý text, uložený do schránky</string>
<string name="custom_devices_settings">Zoznam vlastných zariadení</string>
<string name="custom_device_list">Pridať zariadenia podľa IP</string>
<string name="custom_device_deleted">Odstránené vlastné zariadenie</string>
<string name="custom_device_list_help">Ak vaše zariadenie nie je automaticky zistené, môžete pridať jeho IP adresu alebo názov hostiteľa kliknutím na plávajúce tlačidlo</string>
<string name="custom_device_list">Pridať zariadenia podľa adries IP</string>
<string name="custom_device_deleted">Vlastné zariadenie odstránené</string>
<string name="custom_device_list_help">Ak vaše zariadenie nie je automaticky zistené, môžete pridať jeho adresu IP alebo názov hostiteľa kliknutím na plávajúce tlačidlo</string>
<string name="custom_device_fab_hint">Pridať zariadenie</string>
<string name="undo">Vrátiť</string>
<string name="share_notification_preference">Hlučné pripomienky</string>
<string name="undo">Vrátiť späť</string>
<string name="share_notification_preference">Hlučné upozornenia</string>
<string name="share_notification_preference_summary">Vibrovať a prehrať zvuk pri prijatí súboru</string>
<string name="share_destination_customize">Prispôsobiť cieľový priečinok</string>
<string name="share_destination_customize_summary_disabled">Prijaté súbory sa objavia v priečinku Stiahnuté</string>
<string name="share_destination_customize_summary_enabled">Súbory budú uložené v priečinku nižšie</string>
<string name="share_destination_folder_preference">Cieľový priečinok</string>
<string name="share">Zdieľať</string>
<string name="share_received_file">Zdiaľať \"%s\"</string>
<string name="share_received_file">Zdieľať súbor \"%s\"</string>
<string name="title_activity_notification_filter">Filter upozornení</string>
<string name="filter_apps_info">Upozornenia budú synchronizované pre vybrané aplikácie.</string>
<string name="sftp_sdcard_num">SD karta %d</string>
<string name="sftp_sdcard">SD karta</string>
<string name="filter_apps_info">Pre vybrané aplikácie budú synchronizované upozornenia.</string>
<string name="sftp_sdcard_num">Karta SD %d</string>
<string name="sftp_sdcard">Karta SD</string>
<string name="sftp_readonly">(iba na čítanie)</string>
<string name="sftp_camera">Obrázky fotoaparátu</string>
<string name="add_device_dialog_title">Pridať zariadenie</string>
<string name="add_device_hint">Hostiteľ alebo IP adresa</string>
<string name="sftp_preference_detected_sdcards">Rozpoznané SD karty</string>
<string name="sftp_preference_edit_sdcard_title">Upraviť SD kartu</string>
<string name="sftp_preference_configured_storage_locations">Nastavené umiestnenia úložiska</string>
<string name="add_device_dialog_title">Pridanie zariadenia</string>
<string name="add_device_hint">Názov hostiteľa alebo adresa IP</string>
<string name="sftp_preference_detected_sdcards">Rozpoznané karty SD</string>
<string name="sftp_preference_edit_sdcard_title">Upraviť kartu SD</string>
<string name="sftp_preference_configured_storage_locations">Nastavené umiestnenia úložísk</string>
<string name="sftp_preference_add_storage_location_title">Pridať umiestnenie úložiska</string>
<string name="sftp_preference_edit_storage_location">Upraviť umiestnenie úložiska</string>
<string name="sftp_preference_add_camera_shortcut">Pridať skratku na priečinok s fotkami</string>
<string name="sftp_preference_add_camera_shortcut_summary_on">Pridať skratku na priečinok s fotkami</string>
<string name="sftp_preference_add_camera_shortcut_summary_off">Nepridávať skratku na priečinok s fotkami</string>
<string name="sftp_storage_preference_storage_location">umiestnenie úložiska</string>
<string name="sftp_storage_preference_storage_location_already_configured">toto umiestnenie už bolo nastavené</string>
<string name="sftp_storage_preference_click_to_select">kliknite na výber</string>
<string name="sftp_storage_preference_display_name">Zobraziť meno</string>
<string name="sftp_preference_add_camera_shortcut">Pridať odkaz na priečinok fotoaparátu</string>
<string name="sftp_preference_add_camera_shortcut_summary_on">Pridá odkaz na priečinok fotoaparátu</string>
<string name="sftp_preference_add_camera_shortcut_summary_off">Nepridá odkaz na priečinok fotoaparátu</string>
<string name="sftp_storage_preference_storage_location">Umiestnenie úložiska</string>
<string name="sftp_storage_preference_storage_location_already_configured">Toto umiestnenie už bolo nastavené</string>
<string name="sftp_storage_preference_click_to_select">Kliknutím vyberiete</string>
<string name="sftp_storage_preference_display_name">Zobraziť názov</string>
<string name="sftp_storage_preference_display_name_already_used">Tento zobrazovaný názov už je použitý</string>
<string name="sftp_storage_preference_display_name_cannot_be_empty">Zobrazovaný názov nemôže byť prázdny</string>
<string name="sftp_action_mode_menu_delete">Vymazať</string>
<string name="sftp_no_sdcard_detected">Nebola rozpoznaná žiadna SD karta</string>
<string name="sftp_no_storage_locations_configured">Žiadne umiestnenia úložiska nastavené</string>
<string name="sftp_saf_permission_explanation">Na vzdialený prístup k súborom musíte nastaviť umiestnenia úložiska</string>
<string name="sftp_action_mode_menu_delete">Odstrániť</string>
<string name="sftp_no_sdcard_detected">Nebola rozpoznaná žiadna karta SD</string>
<string name="sftp_no_storage_locations_configured">Nie sú nastavené žiadne umiestnenia úložísk</string>
<string name="sftp_saf_permission_explanation">Na vzdialený prístup k súborom musíte nastaviť umiestnenia úložísk</string>
<string name="no_players_connected">Nenašli sa žiadne prehrávače</string>
<string name="send_files">Odoslať súbory</string>
<string name="pairing_title">KDE Connect zariadenia</string>
<string name="pairing_description">Iné zariadenie so spusteným KDE Connect v rovnakej sieti by sa tu mali objaviť.</string>
<string name="device_rename_title">Premenovať zariadenie</string>
<string name="pairing_title">Zariadenia aplikácie KDE Connect</string>
<string name="pairing_description">Tu by sa mali objaviť iné zariadenie so spustenou aplikáciou KDE Connect v rovnakej sieti.</string>
<string name="device_rename_title">Premenovanie zariadenia</string>
<string name="device_rename_confirm">Premenovať</string>
<string name="refresh">Obnoviť</string>
<string name="unreachable_description">Toto spárované zariadenie nie je dosiahnuteľné. Prosím, uistite sa, že je pripojené do rovnakej siete.</string>
<string name="unreachable_description">Toto spárované zariadenie nie je dosiahnuteľné. Prosím, uistite sa, že je pripojené do rovnakej siete ako vy.</string>
<string name="no_wifi">Nie ste pripojení k sieti Wi-Fi, takže pravdepodobne nebudete môcť vidieť žiadne zariadenia. Kliknutím sem povolíte pripojenie Wi-Fi.</string>
<string name="on_non_trusted_message">Pripojené na nedôveryhodnej sieti: automatické objavovanie je zakázané.</string>
<string name="no_file_browser">Nie sú nainštalované žiadne prehliadače.</string>
<string name="pref_plugin_telepathy">Poslať SMS</string>
<string name="pref_plugin_telepathy_desc">Posielať textové správy z vášho počítača</string>
<string name="pref_plugin_telepathy">Odoslať SMS</string>
<string name="pref_plugin_telepathy_desc">Odosielanie textových správ z vášho počítača</string>
<string name="findmyphone_title">Nájsť môj telefón</string>
<string name="findmyphone_title_tablet">Nájsť môj tablet</string>
<string name="findmyphone_title_tv">Nájsť môj TV</string>
<string name="findmyphone_description">Prezvoní vaše zariadenie, aby ste ho našli</string>
<string name="findmyphone_title_tv">Nájsť môj televízor</string>
<string name="findmyphone_description">Prezvoní toto zariadenie, aby ste ho mohli nájsť</string>
<string name="findmyphone_found">Nájdené</string>
<string name="open">Otvoriť</string>
<string name="close">Zavrieť</string>
<string name="plugins_need_permission">Niektoré Pluginy potrebujú oprávnenia aby fungovali (ťuknite pre viac info):</string>
<string name="permission_explanation">Tento plugin potrebuje oprávnenia aby fungoval</string>
<string name="optional_permission_explanation">Musíte povoliť oprávnenia na povolenie všetkých funkcií</string>
<string name="plugins_need_optional_permission">Niektoré pluginy majú zakázané funkcie pre nedostatok opránení (ťuknite pre viac info):</string>
<string name="share_optional_permission_explanation">Na zdieľanie súborov medzi vašim telefónom a počítačom potrebujete dať prístup k úložisku telefónu</string>
<string name="telepathy_permission_explanation">Na čítanie a písanie SMS z vašeho počítača, potrebujete dať oprávnienie na SMS</string>
<string name="telephony_permission_explanation">Aby ste videli telefónne hovory z počítača, potrebujete dať oprávnenie na zoznamy hovorov a stav telefónu</string>
<string name="telephony_optional_permission_explanation">Aby ste videli meno kontaktu namiesto čísla, potrebujete dať oprávnenie na telefónne kontakty</string>
<string name="contacts_permission_explanation">Na zdieľanie kontaktov s počítačom, potrebujete dať oprávnenie na kontakty</string>
<string name="select_ringtone">Nastaviť tón zvonenia</string>
<string name="plugins_need_permission">Niektoré zásuvné moduly vyžadujú oprávnenia, aby mohli fungovať (ťuknutím získate viac informácií):</string>
<string name="permission_explanation">Tento zásuvný modul vyžaduje oprávnenie, aby mohol fungovať</string>
<string name="optional_permission_explanation">Musíte udeliť oprávnenia navyše, aby boli povolené všetky funkcie</string>
<string name="plugins_need_optional_permission">Niektoré zásuvné moduly majú zakázané funkcie, pretože im chýbajú oprávnenia (ťuknutím získate viac informácií):</string>
<string name="share_optional_permission_explanation">Na zdieľanie súborov medzi vašim telefónom a počítačom, musíte udeliť prístup k úložisku telefónu</string>
<string name="telepathy_permission_explanation">Na čítanie a písanie SMS z vášho počítača, musíte udeliť oprávnenie k správam SMS</string>
<string name="telephony_permission_explanation">Na prezeranie telefónnych hovorov z vášho počítača, musíte udeliť oprávnenie k záznamom hovorov a stavu telefónu</string>
<string name="telephony_optional_permission_explanation">Na prezeranie mien kontaktov namiesto telefónnych čísel, musíte udeliť prístup k telefónnym kontaktom</string>
<string name="contacts_permission_explanation">Na zdieľanie vášho adresára kontaktov s počítačom, musíte udeliť oprávnenie ku kontaktom</string>
<string name="select_ringtone">Vybrať zvonenie</string>
<string name="telephony_pref_blocked_title">Blokované čísla</string>
<string name="telephony_pref_blocked_dialog_desc">Nezobrazovať hovory a SMS z týchto čísel. Prosím upresnite jedno číslo na riadok</string>
<string name="mpris_coverart_description">Obal aktuáneho média</string>
<string name="telephony_pref_blocked_dialog_desc">Z týchto čísel sa nebudú zobrazovať hovori ani správy SMS. Prosím, ute jedno číslo na riadok</string>
<string name="mpris_coverart_description">Obrázok obalu aktuálneho média</string>
<string name="device_icon_description">Ikona zariadenia</string>
<string name="settings_icon_description">Ikona Nastavení</string>
<string name="presenter_fullscreen">Celá obrazovka</string>
<string name="settings_icon_description">Ikona nastavení</string>
<string name="presenter_fullscreen">Na celú obrazovku</string>
<string name="presenter_exit">Ukončiť prezentáciu</string>
<string name="presenter_lock_tip">Môžete zamknúť vaše zariadenie a používať tlačidlá hlasitosti na prechod medzi snímkami</string>
<string name="presenter_lock_tip">Môžete uzamknúť vaše zariadenie a použiť klávesy hlasitosti na prechod na predchádzajúci a nasledujúci snímok</string>
<string name="add_command">Pridať príkaz</string>
<string name="addcommand_explanation">Nie sú registrované žiadne príkazy</string>
<string name="addcommand_explanation2">Môžete pridať nové príkazy v KDE Connect systémových nastaveniach</string>
<string name="addcommand_explanation2">Môžete pridať nové príkazy v systémových nastaveniach aplikácie KDE Connect</string>
<string name="add_command_description">Môžete pridať príkazy na počítači</string>
<string name="pref_plugin_mprisreceiver">Multimediálny ovládač</string>
<string name="pref_plugin_mprisreceiver_desc">Ovláda multimediálne prehrávače vášho telefónu z iného zariadenia</string>
<string name="notification_channel_default">Ostatné upozornenia</string>
<string name="notification_channel_persistent">Trvalý indikátor</string>
<string name="notification_channel_media_control">Multimediálny ovládač</string>
<string name="notification_channel_filetransfer">Prenos súborov</string>
<string name="notification_channel_high_priority">Vysoká priorita</string>
<string name="mpris_stop">Zastaviť aktuálny prehrávač</string>
<string name="copy_url_to_clipboard">Kopírovať adresu do schránky</string>
<string name="copy_url_to_clipboard">Kopírovať URL do schránky</string>
<string name="clipboard_toast">Uložené do schránky</string>
<string name="runcommand_notreachable">Zariadenie nedostup</string>
<string name="runcommand_notpaired">Zariadenie nespárované</string>
<string name="runcommand_nosuchdevice">Zadané zariadenie neexistuje</string>
<string name="runcommand_noruncommandplugin">Toto zariadenie nemá povolený plugin na Spustenie príkazu</string>
<string name="pref_plugin_findremotedevice">Náj vzdialené zariadenie</string>
<string name="pref_plugin_findremotedevice_desc">Zazvon na vzdialenom zariadení</string>
<string name="runcommand_notreachable">Zariadenie nie je dosiahnuteľ</string>
<string name="runcommand_notpaired">Zariadenie nie je spárované</string>
<string name="runcommand_nosuchdevice">Neexistuje žiadne zariadenie</string>
<string name="runcommand_noruncommandplugin">Toto zariadenie nemá povolený zásuvný modul spustenia príkazu</string>
<string name="pref_plugin_findremotedevice">Nájdenie vzdialeného zariadenia</string>
<string name="pref_plugin_findremotedevice_desc">Zazvoní na vašom vzdialenom zariadení</string>
<string name="ring">Zazvoniť</string>
<string name="pref_plugin_systemvolume">Systémová hlasitosť</string>
<string name="pref_plugin_systemvolume_desc">Ovládať systémovú hlasitosť vzdialeného zariadenia</string>
<string name="pref_plugin_systemvolume_desc">Ovláda systémovú hlasitosť vzdialeného zariadenia</string>
<string name="mute">Stlmiť</string>
<string name="all">Všetko</string>
<string name="devices">Zariadenia</string>
<string name="settings_rename">Názov zariadenia</string>
<string name="settings_dark_mode">Tmavá téma</string>
<string name="settings_dark_mode">Tmavý motív</string>
<string name="settings_more_settings_title">Viac nastavení</string>
<string name="settings_more_settings_text">Nstavenia pre konkrétne zariadenia sú dostupné v \"Nastaveniach pluginu\" na zariadení.</string>
<string name="settings_more_settings_text">Nastavenia zariadenia môžete nájsť v ponuke \"Nastavenia zás. modulov\" pri každom zariadení</string>
<string name="setting_persistent_notification">Zobrazovať trvalé oznámenie</string>
<string name="setting_persistent_notification_oreo">Trvalé oznámenie</string>
<string name="setting_persistent_notification_description">Ťuknite na zapnutie/vypnutie v Nastaveniach oznámení</string>
<string name="extra_options">Ďalšie možnosti</string>
<string name="privacy_options">Možnosti súkromia</string>
<string name="set_privacy_options">Nastavte vaše súkromie</string>
<string name="block_contents">Blokovať obsah oznámení</string>
<string name="block_images">Blokovať obrázky v oznámeniach</string>
<string name="notification_channel_receivenotification">Oznámenia iných zariadení</string>
<string name="take_picture">Spust fotoaparát</string>
<string name="plugin_photo_desc">Spust aplikáciu fotoaparátu na uľahčenie snímania a prenosu obrázkov</string>
<string name="setting_persistent_notification_description">Ťuknutím povolíte/zakážete nastavenia v upozornení</string>
<string name="extra_options">Voľby navyše</string>
<string name="privacy_options">Voľby súkromia</string>
<string name="set_privacy_options">Nastavte voľby vášho súkromia</string>
<string name="block_contents">Blokovať obsah upozornení</string>
<string name="block_images">Blokovať obrázky v upozorneniach</string>
<string name="notification_channel_receivenotification">Upozornenia z iných zariadení</string>
<string name="take_picture">Spustenie fotoaparátu</string>
<string name="plugin_photo_desc">Spustí aplikáciu fotoaparátu na uľahčenie zachytenia a prenosu obrázkov</string>
<string name="no_app_for_opening">Nenašla sa vhodná aplikácia na otvorenie tohto súboru</string>
<string name="remote_keyboard_service">KDE Connect Vzdialená Klávesnica</string>
<string name="presenter_pointer">Ukazovateľ</string>
<string name="trusted_networks">Dôveryhodné siete</string>
<string name="trusted_networks_desc">Obmedzí automatické objavovanie iba na známe siete</string>
<string name="add_trusted_network">Pridať sieť %1s</string>
<string name="empty_trusted_networks_list_text">Zatiaľ ste nepridali žiadnu dôveryhodnú sieť</string>
<string name="allow_all_networks_text">Povoliť všetky</string>
<string name="location_permission_needed_title">Potrebné oprávnenia</string>
<string name="location_permission_needed_desc">Systém Android vyžaduje oprávnenia k umiestneniu kvôli identifikácie vašej siete WiFi</string>
<string name="clipboard_android_x_incompat">V systéme Android 10 je odstránený prístup k schránke pre všetky aplikácie. Tento zásuvný modul bude zakázaný.</string>
<string name="mpris_open_url">Pokračovať v prehrávaní tu</string>
<string name="cant_open_url">Nedá sa otvoriť URL pre pokračovanie v prehrávaní</string>
<string name="bigscreen_home">Domov</string>
<string name="bigscreen_up">Hore</string>
<string name="bigscreen_left">Doľava</string>
<string name="bigscreen_select">Vybrať</string>
<string name="bigscreen_right">Doprava</string>
<string name="bigscreen_down">Dole</string>
<string name="pref_plugin_bigscreen">Diaľkové ovládanie obrazovky Bigscreen</string>
<string name="pref_plugin_bigscreen_desc">Použije vaše zariadenie ako diaľkové ovládanie obrazovky Plasma Bigscreen</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE-anslut</string>
<string name="foreground_notification_no_devices">Inte ansluten till någon apparat</string>
<string name="foreground_notification_devices">Ansluten till: %s</string>
<string name="foreground_notification_send_clipboard">Skicka klippbordet</string>
<string name="pref_plugin_telephony">Telefonunderrättelser</string>
<string name="pref_plugin_telephony_desc">Skicka underrättelser för inkommande samtal</string>
<string name="pref_plugin_battery">Batterirapport</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Gör det möjligt att bläddra i apparatens filsystem från annan apparat</string>
<string name="pref_plugin_clipboard">Synkronisera klippbord</string>
<string name="pref_plugin_clipboard_desc">Dela klippbordets innehåll</string>
<string name="pref_plugin_clipboard_sent">Klippbordet skickat</string>
<string name="pref_plugin_mousepad">Extern inmatning</string>
<string name="pref_plugin_mousepad_desc">Använd telefonen eller surfplattan som mus och tangentbord</string>
<string name="pref_plugin_presenter">Fjärrbildspel</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Dela filer och webbadresser mellan apparater</string>
<string name="device_list_empty">Inga apparater</string>
<string name="ok">Ok</string>
<string name="sad_ok">Ok</string>
<string name="cancel">Avbryt</string>
<string name="open_settings">Öppna inställningarna</string>
<string name="no_permissions">Du måste ge rättighet att komma åt underrättelser</string>
@@ -285,4 +288,15 @@
<string name="allow_all_networks_text">Tillåt alla</string>
<string name="location_permission_needed_title">Rättighet krävs</string>
<string name="location_permission_needed_desc">Android kräver platsrättigheter för att identifiera WIFI-nätverk</string>
<string name="clipboard_android_x_incompat">Android 10 har tagit bort åtkomst till klippbordet för alla applikationer. Det här insticksprogrammet kommer att inaktiveras.</string>
<string name="mpris_open_url">Fortsätt spela här</string>
<string name="cant_open_url">Kan inte öppna webbadress för att sluta spela</string>
<string name="bigscreen_home">Hem</string>
<string name="bigscreen_up">Uppåt</string>
<string name="bigscreen_left">Vänster</string>
<string name="bigscreen_select">Markera</string>
<string name="bigscreen_right">Höger</string>
<string name="bigscreen_down">Neråt</string>
<string name="pref_plugin_bigscreen">Fjärrkontroll för storskärm</string>
<string name="pref_plugin_bigscreen_desc">Använd apparaten som en fjärrkontroll för Plasma storskärm</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Не з\'єднано із жодним пристроєм</string>
<string name="foreground_notification_devices">З\'єднано з %s</string>
<string name="foreground_notification_send_clipboard">Надіслати вміст буфера</string>
<string name="pref_plugin_telephony">Телефонний сповіщувач</string>
<string name="pref_plugin_telephony_desc">Надсилати сповіщення щодо вхідних дзвінків</string>
<string name="pref_plugin_battery">Звіт щодо заряду</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">Надає змогу віддалено переглядати файлову систему цього пристрою</string>
<string name="pref_plugin_clipboard">Синхронізація буфера</string>
<string name="pref_plugin_clipboard_desc">Спільне використання буфера обміну даними</string>
<string name="pref_plugin_clipboard_sent">Вміст буфера надіслано</string>
<string name="pref_plugin_mousepad">Дистанційне введення</string>
<string name="pref_plugin_mousepad_desc">Скористайтеся телефоном або планшетом як замінником сенсорної панелі і клавіатури</string>
<string name="pref_plugin_presenter">Віддалений показ слайдів</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">Спільне використання файлів і адрес між пристроями</string>
<string name="device_list_empty">Немає пристроїв</string>
<string name="ok">Гаразд</string>
<string name="sad_ok">Гаразд :(</string>
<string name="cancel">Скасувати</string>
<string name="open_settings">Відкрити вікно параметрів</string>
<string name="no_permissions">Вам слід надати доступ до сповіщень</string>
@@ -301,4 +304,15 @@
<string name="allow_all_networks_text">Дозволити всі</string>
<string name="location_permission_needed_title">Потрібні права доступу</string>
<string name="location_permission_needed_desc">Android потрібні права доступу до даних місця перебування для ідентифікації вашої мережі WiFi</string>
<string name="clipboard_android_x_incompat">У Android 10 вилучено доступ до буфера даних для усіх програм. Цей додаток буде вимкнено.</string>
<string name="mpris_open_url">Продовжити відтворення тут</string>
<string name="cant_open_url">Не вдалося відкрити адресу для продовження відтворення</string>
<string name="bigscreen_home">Домівка</string>
<string name="bigscreen_up">Вгору</string>
<string name="bigscreen_left">Ліворуч</string>
<string name="bigscreen_select">Вибрати</string>
<string name="bigscreen_right">Праворуч</string>
<string name="bigscreen_down">Вниз</string>
<string name="pref_plugin_bigscreen">Керування великим екраном</string>
<string name="pref_plugin_bigscreen_desc">Скористайтеся вашим пристроєм як дистанційним керуванням для великого екрана Плазми</string>
</resources>

View File

@@ -197,6 +197,7 @@
<string name="refresh">刷新</string>
<string name="unreachable_description">此配对设备不可达。请确认它已经连接到与您相同的网络。</string>
<string name="no_wifi">您未连接到 Wi-Fi 网络,所以您可能无法看到任何设备。点击此处启用 Wi-Fi。</string>
<string name="on_non_trusted_message">不在信任的网络上:自动发现已被禁用。</string>
<string name="no_file_browser">未安装文件浏览器</string>
<string name="pref_plugin_telepathy">发送短消息</string>
<string name="pref_plugin_telepathy_desc">从桌面发送短消息</string>
@@ -204,6 +205,7 @@
<string name="findmyphone_title_tablet">找到我的平板电脑</string>
<string name="findmyphone_title_tv">查找我的电视</string>
<string name="findmyphone_description">让设备响铃从而找到它</string>
<string name="findmyphone_found">已发现</string>
<string name="open">打开</string>
<string name="close">关闭</string>
<string name="plugins_need_permission">某些插件需要权限才能工作 (点击以获取更多信息)</string>
@@ -234,6 +236,7 @@
<string name="notification_channel_persistent">持久性通知</string>
<string name="notification_channel_media_control">媒体控制</string>
<string name="notification_channel_filetransfer">文件传送</string>
<string name="notification_channel_high_priority">高优先级</string>
<string name="mpris_stop">停止但前播放器</string>
<string name="copy_url_to_clipboard">复制 URL 到剪贴板</string>
<string name="clipboard_toast">已复制到剪贴板</string>
@@ -267,4 +270,11 @@
<string name="no_app_for_opening">没有找到合适的应用程序打开此文件</string>
<string name="remote_keyboard_service">KDE Connect 远程键盘</string>
<string name="presenter_pointer">指针</string>
<string name="trusted_networks">信任的网络</string>
<string name="trusted_networks_desc">限制只在已知网络中启用自动发现</string>
<string name="add_trusted_network">添加 %1s</string>
<string name="empty_trusted_networks_list_text">您还没有添加任何可信的网络</string>
<string name="allow_all_networks_text">允许所有</string>
<string name="location_permission_needed_title">需要权限</string>
<string name="location_permission_needed_desc">Android 需要位置权限才能识别您的 WiFi 网络</string>
</resources>

View File

@@ -3,6 +3,7 @@
<string name="kde_connect">KDE 連線</string>
<string name="foreground_notification_no_devices">沒有連線到任何裝置</string>
<string name="foreground_notification_devices">已連線到:%s</string>
<string name="foreground_notification_send_clipboard">傳送剪貼簿</string>
<string name="pref_plugin_telephony">電話通知器</string>
<string name="pref_plugin_telephony_desc">傳送未接來電的通知</string>
<string name="pref_plugin_battery">電池報告</string>
@@ -11,6 +12,7 @@
<string name="pref_plugin_sftp_desc">同意讓遠端可以瀏覽檔案系統</string>
<string name="pref_plugin_clipboard">同步剪貼簿</string>
<string name="pref_plugin_clipboard_desc">分享剪貼簿的內容</string>
<string name="pref_plugin_clipboard_sent">已傳送剪貼簿</string>
<string name="pref_plugin_mousepad">遠端輸入</string>
<string name="pref_plugin_mousepad_desc">使用您的智慧型手機或者平板來模擬觸碰板與鍵盤</string>
<string name="pref_plugin_presenter">遠端投影片</string>
@@ -33,6 +35,7 @@
<string name="pref_plugin_sharereceiver_desc">在兩個裝置當中互相分享URL網址與檔案</string>
<string name="device_list_empty">沒有裝置</string>
<string name="ok">確認</string>
<string name="sad_ok">好吧 :(</string>
<string name="cancel">取消</string>
<string name="open_settings">開啟設定</string>
<string name="no_permissions">您需要授予存取通知的權限</string>
@@ -197,6 +200,7 @@
<string name="refresh">重新整理</string>
<string name="unreachable_description">無法連結此配對裝置。請確保它連結到與您相同的網域。</string>
<string name="no_wifi">您尚未連線至 Wi-Fi 網路,因此您可能無法看到任何裝置。按一下這裡啟用 Wi-Fi。</string>
<string name="on_non_trusted_message">不在信任網路:自動探索已停用。</string>
<string name="no_file_browser">沒有安裝此檔案的瀏覽程式</string>
<string name="pref_plugin_telepathy">傳送簡訊</string>
<string name="pref_plugin_telepathy_desc">傳送文字簡訊到您的電腦桌面</string>
@@ -204,6 +208,7 @@
<string name="findmyphone_title_tablet">尋找我的平板</string>
<string name="findmyphone_title_tv">尋找我的電視</string>
<string name="findmyphone_description">讓這個裝置發出聲響讓您能找到它</string>
<string name="findmyphone_found">找到裝置</string>
<string name="open">開啟</string>
<string name="close">關閉</string>
<string name="plugins_need_permission">部份的外掛程式需要權限才能運作(按一下以取得更多資訊)</string>
@@ -234,6 +239,7 @@
<string name="notification_channel_persistent">一致化指示器</string>
<string name="notification_channel_media_control">多媒體控制</string>
<string name="notification_channel_filetransfer">檔案傳輸</string>
<string name="notification_channel_high_priority">高優先度</string>
<string name="mpris_stop">停止目前播放器</string>
<string name="copy_url_to_clipboard">複製 URL 至剪貼簿</string>
<string name="clipboard_toast">已複製到剪貼簿</string>
@@ -267,4 +273,22 @@
<string name="no_app_for_opening">找不到適合用來開啟此檔案的應用程式</string>
<string name="remote_keyboard_service">KDE 連線遠端鍵盤</string>
<string name="presenter_pointer">指標裝置</string>
<string name="trusted_networks">信任網路</string>
<string name="trusted_networks_desc">限制只對已知網路自動探索</string>
<string name="add_trusted_network">加入 %1s</string>
<string name="empty_trusted_networks_list_text">您尚未加入任何信任網路</string>
<string name="allow_all_networks_text">全部允許</string>
<string name="location_permission_needed_title">需要權限</string>
<string name="location_permission_needed_desc">Android 需要「位置」權限才能識別你的 Wi-Fi 網路</string>
<string name="clipboard_android_x_incompat">Android 10 已移除所有應用程式的剪貼簿存取權限。此外掛程式將停用。</string>
<string name="mpris_open_url">繼續在此播放</string>
<string name="cant_open_url">無法開啟 URL 以繼續播放</string>
<string name="bigscreen_home">首頁</string>
<string name="bigscreen_up"></string>
<string name="bigscreen_left"></string>
<string name="bigscreen_select">選擇</string>
<string name="bigscreen_right"></string>
<string name="bigscreen_down"></string>
<string name="pref_plugin_bigscreen">Bigscreen 遠端</string>
<string name="pref_plugin_bigscreen_desc">將您的裝置用作 Plasma Bigscreen 的遠端</string>
</resources>

View File

@@ -39,6 +39,7 @@
<string name="pref_plugin_sharereceiver_desc">Share files and URLs between devices</string>
<string name="device_list_empty">No devices</string>
<string name="ok">OK</string>
<string name="sad_ok">OK :(</string>
<string name="cancel">Cancel</string>
<string name="open_settings">Open settings</string>
<string name="no_permissions">You need to grant permission to access notifications</string>
@@ -352,4 +353,16 @@
<string name="location_permission_needed_title">Permission required</string>
<string name="location_permission_needed_desc">Android requires the Location permission to identify your WiFi network</string>
<string name="clipboard_android_x_incompat">Android 10 has removed clipboard access to all apps. This plugin will be disabled.</string>
<string name="mpris_open_url">Continue playing here</string>
<string name="cant_open_url">Can\'t open URL to continue playing</string>
<string name="bigscreen_home">Home</string>
<string name="bigscreen_up">Up</string>
<string name="bigscreen_left">Left</string>
<string name="bigscreen_select">Select</string>
<string name="bigscreen_right">Right</string>
<string name="bigscreen_down">Down</string>
<string name="pref_plugin_bigscreen">Bigscreen remote</string>
<string name="pref_plugin_bigscreen_desc">Use your device as a remote for Plasma Bigscreen</string>
</resources>

View File

@@ -6,8 +6,10 @@
<!-- KdeConnectThemeBase styles must only be defined in the main res/values/ folder -->
<style name="KdeConnectThemeBase.Dark" parent="Theme.MaterialComponents">
<item name="colorPrimary">@color/darkGrey</item>
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/darkStatusBarBackground</item>
<item name="colorSecondary">@color/primary</item>
<item name="colorOnSecondary">@android:color/black</item>
<item name="colorAccent">@color/accent</item>
<item name="android:windowBackground">@android:color/black</item>
<item name="toolbarStyle">@style/KdeConnectTheme.Toolbar.Dark</item>

View File

@@ -9,6 +9,8 @@
<!-- The three colors used by system widgets, according to https://chris.banes.me/2014/10/17/appcompat-v21/ -->
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primaryDark</item>
<item name="colorSecondary">@color/primary</item>
<item name="colorOnSecondary">@android:color/white</item>
<item name="colorAccent">@color/accent</item>
<item name="toolbarStyle">@style/KdeConnectTheme.Toolbar</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>

View File

@@ -42,6 +42,7 @@ import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.channels.NotYetConnectedException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import androidx.annotation.WorkerThread;
@@ -210,6 +211,11 @@ public class LanLink extends BaseLink {
}
outputStream.flush();
Log.i("KDE/LanLink", "Finished sending payload ("+progress+" bytes written)");
} catch(SSLHandshakeException e) {
// The exception can be due to several causes. "Connection closed by peer" seems to be a common one.
// If we could distinguish different cases we could react differently for some of them, but I haven't found how.
Log.e("sendPacket","Payload SSLSocket failed");
e.printStackTrace();
} finally {
try { server.close(); } catch (Exception ignored) { }
try { payloadSocket.close(); } catch (Exception ignored) { }

View File

@@ -32,9 +32,12 @@ import android.net.ConnectivityManager;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import androidx.core.app.NotificationCompat;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
@@ -43,18 +46,20 @@ import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandActivity;
import org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandPlugin;
import org.kde.kdeconnect.Plugins.SharePlugin.SendFileActivity;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import androidx.core.app.NotificationCompat;
//import org.kde.kdeconnect.Backends.BluetoothBackend.BluetoothLinkProvider;
public class BackgroundService extends Service {
@@ -274,6 +279,7 @@ public class BackgroundService extends Service {
initializeSecurityParameters();
NotificationHelper.initializeChannels(this);
loadRememberedDevicesFromSettings();
migratePluginSettings();
registerLinkProviders();
//Link Providers need to be already registered
@@ -284,6 +290,29 @@ public class BackgroundService extends Service {
}
}
private void migratePluginSettings() {
SharedPreferences globalPrefs = PreferenceManager.getDefaultSharedPreferences(this);
for (String pluginKey : PluginFactory.getAvailablePlugins()) {
if (PluginFactory.getPluginInfo(pluginKey).supportsDeviceSpecificSettings()) {
Iterator<Device> it = devices.values().iterator();
while (it.hasNext()) {
Device device = it.next();
Plugin plugin = PluginFactory.instantiatePluginForDevice(getBaseContext(), pluginKey, device);
if (plugin == null) {
continue;
}
plugin.copyGlobalToDeviceSpecificSettings(globalPrefs);
if (!it.hasNext()) {
plugin.removeSettings(globalPrefs);
}
}
}
}
}
public void changePersistentNotificationVisibility(boolean visible) {
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
@@ -311,24 +340,43 @@ public class BackgroundService extends Service {
.setAutoCancel(false);
notification.setGroup("BackgroundService");
ArrayList<String> connectedDevices = new ArrayList<>();
for (Device device : getDevices().values()) {
if (device.isReachable() && device.isPaired()) {
connectedDevices.add(device.getName());
}
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
//Pre-oreo, the notification will have an empty title line without this
notification.setContentTitle(getString(R.string.kde_connect));
}
ArrayList<String> connectedDevices = new ArrayList<>();
ArrayList<String> deviceIds = new ArrayList<>();
for (Device device : getDevices().values()) {
if (device.isReachable() && device.isPaired()) {
deviceIds.add(device.getDeviceId());
connectedDevices.add(device.getName());
}
}
if (connectedDevices.isEmpty()) {
notification.setContentText(getString(R.string.foreground_notification_no_devices));
} else {
notification.setContentText(getString(R.string.foreground_notification_devices, TextUtils.join(", ", connectedDevices)));
}
if (deviceIds.size() == 1) {
// Adding two action buttons only when there is a single device connected.
// Setting up Send File Intent.
Intent sendFile = new Intent(this, SendFileActivity.class);
sendFile.putExtra("deviceId", deviceIds.get(0));
PendingIntent sendPendingFile = PendingIntent.getActivity(this, 1, sendFile, PendingIntent.FLAG_UPDATE_CURRENT);
notification.addAction(0, getString(R.string.send_files), sendPendingFile);
// Checking if there are registered commands and adding the button.
Device device = getDevice(deviceIds.get(0));
RunCommandPlugin plugin = (RunCommandPlugin) device.getPlugin("RunCommandPlugin");
if (plugin != null && !plugin.getCommandList().isEmpty()) {
Intent runCommand = new Intent(this, RunCommandActivity.class);
runCommand.putExtra("deviceId", deviceIds.get(0));
PendingIntent runPendingCommand = PendingIntent.getActivity(this, 2, runCommand, PendingIntent.FLAG_UPDATE_CURRENT);
notification.addAction(0, getString(R.string.pref_plugin_runcommand), runPendingCommand);
}
}
}
return notification.build();
}

View File

@@ -33,6 +33,12 @@ import android.preference.PreferenceManager;
import android.util.Base64;
import android.util.Log;
import androidx.annotation.AnyThread;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BasePairingHandler;
import org.kde.kdeconnect.Helpers.NotificationHelper;
@@ -57,11 +63,6 @@ import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import androidx.annotation.AnyThread;
import androidx.annotation.WorkerThread;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
public class Device implements BaseLink.PacketReceiver {
private final Context context;
@@ -712,11 +713,13 @@ public class Device implements BaseLink.PacketReceiver {
// Plugin-related functions
//
@Nullable
public <T extends Plugin> T getPlugin(Class<T> pluginClass) {
Plugin plugin = getPlugin(Plugin.getPluginKey(pluginClass));
return (T) plugin;
}
@Nullable
public Plugin getPlugin(String pluginKey) {
return plugins.get(pluginKey);
}

View File

@@ -162,7 +162,7 @@ public class FilesHelper {
// situations were we don't know the size (for instance, if the file is
// not local to the device)
if (!cursor.isNull(sizeColumnIndex)) {
size = cursor.getInt(sizeColumnIndex);
size = cursor.getLong(sizeColumnIndex);
}
lastModified = getLastModifiedTime(context, uri);

View File

@@ -43,12 +43,16 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -61,41 +65,18 @@ import androidx.annotation.RequiresApi;
public class SMSHelper {
/**
* Get the base address for the SMS content
* <p>
* If we want to support API < 19, it seems to be possible to read via this query
* This is highly undocumented and very likely varies between vendors but appears to work
* Get a URI for querying SMS messages
*/
private static Uri getSMSURIBad() {
return Uri.parse("content://sms/");
}
/**
* Get the base address for the SMS content
* <p>
* Use the new API way which should work on any phone API >= 19
*/
@RequiresApi(Build.VERSION_CODES.KITKAT)
private static Uri getSMSURIGood() {
private static Uri getSMSUri() {
// This constant was introduces with API 19 (KitKat)
// The value it represents was used in older Android versions so it *should* work but
// might vary between vendors.
return Telephony.Sms.CONTENT_URI;
}
private static Uri getSMSUri() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return getSMSURIGood();
} else {
return getSMSURIBad();
}
}
private static Uri getMMSUri() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return Telephony.Mms.CONTENT_URI;
} else {
// Same as with getSMSUriBad, this is unsafe if the manufacturer did their own thing
// before this was part of the API
return Uri.parse("content://mms/");
}
// Same warning as getSMSUri: This constant was introduced with API 19
return Telephony.Mms.CONTENT_URI;
}
private static Uri getMMSPartUri() {
@@ -151,15 +132,85 @@ public class SMSHelper {
*
* @param context android.content.Context running the request
* @param threadID Thread to look up
* @param numberToGet Number of messages to return. Pass null for "all"
* @return List of all messages in the thread
*/
public static @NonNull List<Message> getMessagesInThread(
@NonNull Context context,
@NonNull ThreadID threadID
@NonNull ThreadID threadID,
@Nullable Long numberToGet
) {
Uri uri = Uri.withAppendedPath(getConversationUri(), threadID.toString());
return getMessages(uri, context, null, null, null, null);
return getMessages(uri, context, null, null, null, numberToGet);
}
/**
* Get some messages in the given thread which have timestamp equal to or after the given timestamp
*
* @param context android.content.Context running the request
* @param threadID Thread to look up
* @param startTimestamp Beginning of the range to return
* @param numberToGet Number of messages to return. Pass null for "all"
* @return Some messages in the requested conversation
*/
@SuppressLint("NewApi")
public static @NonNull List<Message> getMessagesInRange(
@NonNull Context context,
@NonNull ThreadID threadID,
@NonNull Long startTimestamp,
@Nullable Long numberToGet
) {
// The stickiness with this is that Android's MMS database has its timestamp in epoch *seconds*
// while the SMS database uses epoch *milliseconds*.
// I can think of no way around this other than manually querying each one with a different
// "WHERE" statement.
Uri smsUri = getSMSUri();
Uri mmsUri = getMMSUri();
List<String> allSmsColumns = new ArrayList<>(Arrays.asList(Message.smsColumns));
List<String> allMmsColumns = new ArrayList<>(Arrays.asList(Message.mmsColumns));
if (getSubscriptionIdSupport(smsUri, context)) {
allSmsColumns.addAll(Arrays.asList(Message.multiSIMColumns));
}
if (getSubscriptionIdSupport(mmsUri, context)) {
allMmsColumns.addAll(Arrays.asList(Message.multiSIMColumns));
}
String selection = Message.THREAD_ID + " = ? AND ? >= " + Message.DATE;
String[] smsSelectionArgs = new String[] { threadID.toString(), startTimestamp.toString() };
String[] mmsSelectionArgs = new String[] { threadID.toString(), Long.toString(startTimestamp / 1000) };
String sortOrder = Message.DATE + " DESC";
List<Message> allMessages = getMessages(smsUri, context, allSmsColumns, selection, smsSelectionArgs, sortOrder, numberToGet);
allMessages.addAll(getMessages(mmsUri, context, allMmsColumns, selection, mmsSelectionArgs, sortOrder, numberToGet));
// Need to now only return the requested number of messages:
// Suppose we were requested to return N values and suppose a user sends only one MMS per
// week and N SMS per day. We have requested the same N for each, so if we just return everything
// we would return some very old MMS messages which would be very confusing.
SortedMap<Long, Collection<Message>> sortedMessages = new TreeMap<>((lhs, rhs) -> Long.compare(rhs, lhs));
for (Message message : allMessages) {
Collection<Message> existingMessages = sortedMessages.getOrDefault(message.date, new ArrayList<>());
assert existingMessages != null;
existingMessages.add(message);
sortedMessages.put(message.date, existingMessages);
}
List<Message> toReturn = new ArrayList<>(allMessages.size());
for (Collection<Message> messages : sortedMessages.values()) {
toReturn.addAll(messages);
if (numberToGet != null && toReturn.size() >= numberToGet) {
break;
}
}
return toReturn;
}
/**
@@ -226,6 +277,7 @@ public class SMSHelper {
*
* @param uri Uri indicating the messages database to read
* @param context android.content.Context running the request.
* @param fetchColumns List of columns to fetch
* @param selection Parameterizable filter to use with the ContentResolver query. May be null.
* @param selectionArgs Parameters for selection. May be null.
* @param sortOrder Sort ordering passed to Android's content resolver. May be null for unspecified
@@ -235,6 +287,7 @@ public class SMSHelper {
private static @NonNull List<Message> getMessages(
@NonNull Uri uri,
@NonNull Context context,
@NonNull Collection<String> fetchColumns,
@Nullable String selection,
@Nullable String[] selectionArgs,
@Nullable String sortOrder,
@@ -246,23 +299,9 @@ public class SMSHelper {
// of any MMSes
List<String> userPhoneNumbers = TelephonyHelper.getAllPhoneNumbers(context);
Set<String> allColumns = new HashSet<>();
allColumns.addAll(Arrays.asList(Message.smsColumns));
allColumns.addAll(Arrays.asList(Message.mmsColumns));
if (getSubscriptionIdSupport(uri, context)) {
allColumns.addAll(Arrays.asList(Message.multiSIMColumns));
}
if (!uri.equals(getConversationUri())) {
// See https://issuetracker.google.com/issues/134592631
allColumns.add(getTransportTypeDiscriminatorColumn());
}
String[] fetchColumns = {};
fetchColumns = allColumns.toArray(fetchColumns);
try (Cursor myCursor = context.getContentResolver().query(
uri,
fetchColumns,
fetchColumns.toArray(new String[]{}),
selection,
selectionArgs,
sortOrder)
@@ -304,19 +343,25 @@ public class SMSHelper {
messageInfo.put(colName, body);
}
Message message;
if (transportType == TransportType.SMS) {
message = parseSMS(context, messageInfo);
} else if (transportType == TransportType.MMS) {
message = parseMMS(context, messageInfo, userPhoneNumbers);
} else {
// As we can see, all possible transportTypes are covered, but the compiler
// requires this line anyway
throw new UnsupportedOperationException("Unknown TransportType encountered");
}
try {
Message message;
if (transportType == TransportType.SMS) {
message = parseSMS(context, messageInfo);
} else if (transportType == TransportType.MMS) {
message = parseMMS(context, messageInfo, userPhoneNumbers);
} else {
// As we can see, all possible transportTypes are covered, but the compiler
// requires this line anyway
throw new UnsupportedOperationException("Unknown TransportType encountered");
}
toReturn.add(message);
} while ((numberToGet == null || toReturn.size() != numberToGet) && myCursor.moveToNext());
toReturn.add(message);
} catch (Exception e) {
// Swallow exceptions in case we get an error reading one message so that we
// might be able to read some of them
Log.e("SMSHelper", "Got an error reading a message of type " + transportType, e);
}
} while ((numberToGet == null || toReturn.size() < numberToGet) && myCursor.moveToNext());
}
} catch (SQLiteException e) {
String[] unfilteredColumns = {};
@@ -331,9 +376,45 @@ public class SMSHelper {
throw new MessageAccessException(unfilteredColumns, uri, e);
}
}
return toReturn;
}
/**
* Gets messages which match the selection
*
* @param uri Uri indicating the messages database to read
* @param context android.content.Context running the request.
* @param selection Parameterizable filter to use with the ContentResolver query. May be null.
* @param selectionArgs Parameters for selection. May be null.
* @param sortOrder Sort ordering passed to Android's content resolver. May be null for unspecified
* @param numberToGet Number of things to get from the result. Pass null to get all
* @return Returns List<Message> of all messages in the return set, either in the order of sortOrder or in an unspecified order
*/
@SuppressLint("NewApi")
private static @NonNull List<Message> getMessages(
@NonNull Uri uri,
@NonNull Context context,
@Nullable String selection,
@Nullable String[] selectionArgs,
@Nullable String sortOrder,
@Nullable Long numberToGet
) {
Set<String> allColumns = new HashSet<>();
allColumns.addAll(Arrays.asList(Message.smsColumns));
allColumns.addAll(Arrays.asList(Message.mmsColumns));
if (getSubscriptionIdSupport(uri, context)) {
allColumns.addAll(Arrays.asList(Message.multiSIMColumns));
}
if (!uri.equals(getConversationUri())) {
// See https://issuetracker.google.com/issues/134592631
allColumns.add(getTransportTypeDiscriminatorColumn());
}
return getMessages(uri, context, allColumns, selection, selectionArgs, sortOrder, numberToGet);
}
/**
* Get all messages matching the passed filter. See documentation for Android's ContentResolver
*
@@ -509,8 +590,6 @@ public class SMSHelper {
// telco service messages) where it is not (only 1 long in that case, just the "sender")
if (addresses.size() >= 2) {
// TODO: Handle addresses for multi-target MMS
// Probably we will need to figure out the user's address at this point and strip it out of the list
event = addEventFlag(event, Message.EVENT_MULTI_TARGET);
}
@@ -536,6 +615,8 @@ public class SMSHelper {
* Get the address(es) of an MMS message
* Original implementation from https://stackoverflow.com/a/6446831/3723163
*
* The message at the first position of the list should be the sender of the message
*
* @param messageID ID of this message in the MMS database for looking up the remaining info
* @param userPhoneNumbers List of phone numbers which should be removed from the list of addresses
*/
@@ -555,7 +636,8 @@ public class SMSHelper {
String selection = Telephony.Mms.Addr.MSG_ID + " = ?";
String[] selectionArgs = {messageID.toString()};
List<Address> addresses = new ArrayList<>();
// Keep an ordered set rather than a list because Android sometimes throws duplicates at us
Set<Address> addresses = new LinkedHashSet<>();
try (Cursor addrCursor = context.getContentResolver().query(
uri,
@@ -704,6 +786,11 @@ public class SMSHelper {
}
return false;
}
@Override
public int hashCode() {
return this.address.hashCode();
}
}
/**

View File

@@ -0,0 +1,145 @@
package org.kde.kdeconnect.Helpers;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;
public class VideoUrlsHelper {
private static final int SECONDS_IN_MINUTE = 60;
private static final int MINUTES_IN_HOUR = 60;
private static final int SECONDS_IN_HOUR = SECONDS_IN_MINUTE * MINUTES_IN_HOUR;
public static URL formatUriWithSeek(String address, long position)
throws MalformedURLException {
URL url = new URL(address);
position /= 1000; // Convert ms to seconds
if (position <= 0) {
return url; // nothing to do
}
String host = url.getHost().toLowerCase();
// Most common settings as defaults:
String parameter = "t="; // Characters before timestamp
String timestamp = Long.toString(position); // Timestamp itself
String trailer = ""; // Characters after timestamp
// true - search/add to query URL part (between ? and # signs),
// false - search/add timestamp to ref (anchor) URL part (after # sign),
boolean inQuery = true;
// true - We know how to format URL with seek timestamp, false - not
boolean seekUrl = false;
// Override defaults if necessary
if (host.contains("youtube.com")
|| host.contains("youtu.be")
|| host.contains("pornhub.com")) {
seekUrl = true;
url = stripTimestampS(url, parameter, trailer, inQuery);
} else if (host.contains("vimeo.com")) {
seekUrl = true;
trailer = "s";
url = stripTimestampS(url, parameter, trailer, inQuery);
} else if (host.contains("dailymotion.com")) {
seekUrl = true;
parameter = "start=";
url = stripTimestampS(url, parameter, trailer, inQuery);
} else if (host.contains("twitch.tv")) {
seekUrl = true;
timestamp = formatTimestampHMS(position, true);
url = stripTimestampHMS(url, parameter, trailer, inQuery);
}
if (seekUrl) {
url = formatUrlWithSeek(url, timestamp, parameter, trailer, inQuery);
}
return url;
}
// Returns timestamp in 1h2m34s or 01h02m34s (according to padWithZeroes)
private static String formatTimestampHMS(long seconds, boolean padWithZeroes) {
if (seconds == 0) {
return "0s";
}
int sec = (int) (seconds % SECONDS_IN_MINUTE);
int min = (int) ((seconds / SECONDS_IN_MINUTE) % MINUTES_IN_HOUR);
int hour = (int) (seconds / SECONDS_IN_HOUR);
String hours = hour > 0 ? hour + "h" : "";
String mins = min > 0 || hour > 0 ? min + "m" : "";
String secs = sec + "s";
String value;
if (padWithZeroes) {
String hoursPad = hour > 9 ? "" : "0";
String minsPad = min > 9 ? "" : "0";
String secsPad = sec > 9 ? "" : "0";
value = hoursPad + hours + minsPad + mins + secsPad + secs;
} else {
value = hours + mins + secs;
}
return value;
}
// Remove timestamp in 01h02m34s or 1h2m34s or 02m34s or 2m34s or 01s or 1s format.
// Can also nandle rimestamps in 1234s format if called with 's' trailer
private static URL stripTimestampHMS(URL url, String parameter, String trailer, boolean inQuery)
throws MalformedURLException {
String regex = parameter + "([\\d]+[hH])?([\\d]+[mM])?[\\d]+[sS]" + trailer + "&?";
return stripTimestampCommon(url, inQuery, regex);
}
// Remove timestamp in 1234 format
private static URL stripTimestampS(URL url, String parameter, String trailer, boolean inQuery)
throws MalformedURLException {
String regex = parameter + "[\\d]+" + trailer + "&?";
return stripTimestampCommon(url, inQuery, regex);
}
private static URL stripTimestampCommon(URL url, boolean inQuery, String regex)
throws MalformedURLException {
String value;
if (inQuery) {
value = url.getQuery();
} else {
value = url.getRef();
}
if (value == null) {
return url;
}
String newValue = value.replaceAll(regex, "");
String replaced = url.toString().replaceFirst(value, newValue);
if (inQuery && replaced.endsWith("&")) {
replaced = replaced.substring(0, replaced.length() - 1);
}
return new URL(replaced);
}
private static URL formatUrlWithSeek(URL url, String position, String parameter, String trailer,
boolean inQuery) throws MalformedURLException {
String value;
String separator;
String newValue;
if (inQuery) {
value = url.getQuery();
separator = "?";
} else {
value = url.getRef();
separator = "#";
}
if (value == null) {
newValue = String.format(Locale.getDefault(), "%s%s%s%s%s",
url.toString(), separator, parameter, position, trailer);
return new URL(newValue);
}
if (inQuery) {
newValue = String.format(Locale.getDefault(), "%s&%s%s%s",
value, parameter, position, trailer);
} else {
newValue = String.format(Locale.getDefault(), "%s%s%s",
parameter, position, trailer);
}
return new URL(url.toString().replaceFirst(value, newValue));
}
}

View File

@@ -37,6 +37,12 @@ public class KdeConnectBroadcastReceiver extends BroadcastReceiver {
String action = intent.getAction();
switch (action) {
case Intent.ACTION_MY_PACKAGE_REPLACED:
Log.i("KdeConnect", "MyUpdateReceiver");
BackgroundService.RunCommand(context, service -> {
});
break;
case Intent.ACTION_PACKAGE_REPLACED:
Log.i("KdeConnect", "UpdateReceiver");
if (!intent.getData().getSchemeSpecificPart().equals(context.getPackageName())) {

View File

@@ -85,7 +85,8 @@ public class BatteryPlugin extends Plugin {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
context.registerReceiver(receiver, intentFilter);
Intent currentState = context.registerReceiver(receiver, intentFilter);
receiver.onReceive(context, currentState);
return true;
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2014 Ahmed I. Khalil <ahmedibrahimkhali@gmail.com>
* Copyright 2020 Sylvia van Os <sylvia@hackerchick.me>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.Plugins.BigscreenPlugin;
import android.os.Bundle;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R;
import androidx.appcompat.app.AppCompatActivity;
public class BigscreenActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_bigscreen);
final String deviceId = getIntent().getStringExtra("deviceId");
BackgroundService.RunWithPlugin(this, deviceId, org.kde.kdeconnect.Plugins.BigscreenPlugin.BigscreenPlugin.class, plugin -> runOnUiThread(() -> {
findViewById(R.id.left_button).setOnClickListener(v -> plugin.sendLeft());
findViewById(R.id.right_button).setOnClickListener(v -> plugin.sendRight());
findViewById(R.id.up_button).setOnClickListener(v -> plugin.sendUp());
findViewById(R.id.down_button).setOnClickListener(v -> plugin.sendDown());
findViewById(R.id.select_button).setOnClickListener(v -> plugin.sendSelect());
findViewById(R.id.home_button).setOnClickListener(v -> plugin.sendHome());
}));
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2014 Ahmed I. Khalil <ahmedibrahimkhali@gmail.com>
* Copyright 2020 Sylvia van Os <sylvia@hackerchick.me>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.Plugins.BigscreenPlugin;
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.KeyEvent;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect_tp.R;
import androidx.core.content.ContextCompat;
import static org.kde.kdeconnect.Plugins.MousePadPlugin.KeyListenerView.SpecialKeysMap;
@PluginFactory.LoadablePlugin
public class BigscreenPlugin extends Plugin {
private final static String PACKET_TYPE_MOUSEPAD_REQUEST = "kdeconnect.mousepad.request";
@Override
public String getDisplayName() {
return context.getString(R.string.pref_plugin_bigscreen);
}
@Override
public String getDescription() {
return context.getString(R.string.pref_plugin_bigscreen_desc);
}
@Override
public Drawable getIcon() {
return ContextCompat.getDrawable(context, R.drawable.ic_presenter);
}
@Override
public boolean isEnabledByDefault() {
return false;
}
@Override
public boolean hasSettings() {
return false;
}
@Override
public boolean hasMainActivity() {
return true;
}
@Override
public void startMainActivity(Activity parentActivity) {
Intent intent = new Intent(parentActivity, BigscreenActivity.class);
intent.putExtra("deviceId", device.getDeviceId());
parentActivity.startActivity(intent);
}
@Override
public String[] getSupportedPacketTypes() { return new String[0]; }
@Override
public String[] getOutgoingPacketTypes() {
return new String[]{PACKET_TYPE_MOUSEPAD_REQUEST};
}
@Override
public String getActionName() {
return context.getString(R.string.pref_plugin_bigscreen);
}
public void sendLeft() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("specialKey", SpecialKeysMap.get(KeyEvent.KEYCODE_DPAD_LEFT));
device.sendPacket(np);
}
public void sendRight() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("specialKey", SpecialKeysMap.get(KeyEvent.KEYCODE_DPAD_RIGHT));
device.sendPacket(np);
}
public void sendUp() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("specialKey", SpecialKeysMap.get(KeyEvent.KEYCODE_DPAD_UP));
device.sendPacket(np);
}
public void sendDown() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("specialKey", SpecialKeysMap.get(KeyEvent.KEYCODE_DPAD_DOWN));
device.sendPacket(np);
}
public void sendSelect() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("specialKey", SpecialKeysMap.get(KeyEvent.KEYCODE_ENTER));
device.sendPacket(np);
}
public void sendHome() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("alt", true);
np.set("specialKey", SpecialKeysMap.get(KeyEvent.KEYCODE_F4));
device.sendPacket(np);
}
}

View File

@@ -51,6 +51,7 @@ public class ClipboardListener {
public static ClipboardListener instance(Context context) {
if (_instance == null) {
_instance = new ClipboardListener(context);
// FIXME: The _instance we return won't be completely initialized yet since initialization happens on a new thread (why?)
}
return _instance;
}
@@ -102,9 +103,11 @@ public class ClipboardListener {
@SuppressWarnings("deprecation")
public void setText(String text) {
updateTimestamp = System.currentTimeMillis();
currentContent = text;
cm.setText(text);
if (cm != null) {
updateTimestamp = System.currentTimeMillis();
currentContent = text;
cm.setText(text);
}
}
}

View File

@@ -20,9 +20,15 @@
package org.kde.kdeconnect.Plugins.ClibpoardPlugin;
import android.os.Build;
import androidx.fragment.app.DialogFragment;
import androidx.preference.PreferenceManager;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.UserInterface.NoticeAlertDialogFragment;
import org.kde.kdeconnect_tp.R;
@PluginFactory.LoadablePlugin
@@ -53,6 +59,8 @@ public class ClipboardPlugin extends Plugin {
*/
private final static String PACKET_TYPE_CLIPBOARD_CONNECT = "kdeconnect.clipboard.connect";
private final static String ANDROID_10_INCOMPAT_DIALOG_SHOWN_PREFERENCE = "android10IncompatDialogShown";
@Override
public String getDisplayName() {
return context.getResources().getString(R.string.pref_plugin_clipboard);
@@ -100,8 +108,26 @@ public class ClipboardPlugin extends Plugin {
device.sendPacket(np);
}
@Override
public boolean checkRequiredPermissions() {
return Build.VERSION.SDK_INT <= Build.VERSION_CODES.P || PreferenceManager.getDefaultSharedPreferences(context).getBoolean(ANDROID_10_INCOMPAT_DIALOG_SHOWN_PREFERENCE, false);
}
@Override
public DialogFragment getPermissionExplanationDialog() {
PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(ANDROID_10_INCOMPAT_DIALOG_SHOWN_PREFERENCE, true).apply();
return new NoticeAlertDialogFragment.Builder()
.setTitle(R.string.pref_plugin_clipboard)
.setMessage(R.string.clipboard_android_x_incompat)
.setPositiveButton(R.string.sad_ok)
.create();
}
@Override
public boolean onCreate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return false;
}
ClipboardListener.instance(context).registerObserver(observer);
sendConnectPacket();
return true;

View File

@@ -188,6 +188,11 @@ public class FindMyPhonePlugin extends Plugin {
}
void stopPlaying() {
if (audioManager == null) {
// The Plugin was destroyed (probably the device disconnected)
return;
}
if (previousVolume != -1) {
audioManager.setStreamVolume(AudioManager.STREAM_ALARM, previousVolume, 0);
}

View File

@@ -20,14 +20,21 @@
package org.kde.kdeconnect.Plugins.MprisPlugin;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
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.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
@@ -37,15 +44,18 @@ import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Helpers.VideoUrlsHelper;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.SystemvolumePlugin.SystemvolumeFragment;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R;
import java.net.MalformedURLException;
import java.util.List;
import androidx.annotation.NonNull;
@@ -289,6 +299,8 @@ public class MprisActivity extends AppCompatActivity {
rewButton.setVisibility(playerStatus.isSeekAllowed() ? View.VISIBLE : View.GONE);
ffButton.setVisibility(playerStatus.isSeekAllowed() ? View.VISIBLE : View.GONE);
invalidateOptionsMenu();
//Show and hide previous/next buttons simultaneously
if (playerStatus.isGoPreviousAllowed() || playerStatus.isGoNextAllowed()) {
prevButton.setVisibility(View.VISIBLE);
@@ -367,8 +379,15 @@ public class MprisActivity extends AppCompatActivity {
setContentView(R.layout.activity_mpris);
ButterKnife.bind(this);
final String targetPlayerName = getIntent().getStringExtra("player");
String targetPlayerName = getIntent().getStringExtra("player");
getIntent().removeExtra("player");
if (targetPlayerName == null || targetPlayerName.isEmpty()) {
if (savedInstanceState != null) {
targetPlayerName = savedInstanceState.getString("targetPlayer");
}
}
deviceId = getIntent().getStringExtra("deviceId");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -445,4 +464,39 @@ public class MprisActivity extends AppCompatActivity {
nowPlayingText.setSelected(true);
}
final static int MENU_OPEN_URL = Menu.FIRST;
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
if(targetPlayer != null && !"".equals(targetPlayer.getUrl())) {
menu.add(0, MENU_OPEN_URL, Menu.NONE, R.string.mpris_open_url);
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (targetPlayer != null && item.getItemId() == MENU_OPEN_URL) {
try {
String url = VideoUrlsHelper.formatUriWithSeek(targetPlayer.getUrl(), targetPlayer.getPosition()).toString();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
targetPlayer.pause();
return true;
} catch (MalformedURLException | ActivityNotFoundException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), getString(R.string.cant_open_url), Toast.LENGTH_LONG).show();
}
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
if (targetPlayer != null) {
outState.putString("targetPlayer", targetPlayer.getPlayer());
}
super.onSaveInstanceState(outState);
}
}

View File

@@ -434,7 +434,6 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (notificationPlayer.isSeekAllowed()) {
playbackActions |= PlaybackStateCompat.ACTION_SEEK_TO;
++numActions;
}
}
playbackState.setActions(playbackActions);
@@ -496,7 +495,7 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onNotificationPosted(StatusBarNotification n) {
if (n.getPackageName().equals("com.spotify.music")) {
if ("com.spotify.music".equals(n.getPackageName())) {
spotifyRunning = true;
updateMediaNotification();
}
@@ -505,7 +504,7 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onNotificationRemoved(StatusBarNotification n) {
if (n.getPackageName().equals("com.spotify.music")) {
if ("com.spotify.music".equals(n.getPackageName())) {
spotifyRunning = false;
updateMediaNotification();
}
@@ -515,7 +514,7 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh
@Override
public void onListenerConnected(NotificationReceiver service) {
for (StatusBarNotification n : service.getActiveNotifications()) {
if (n.getPackageName().equals("com.spotify.music")) {
if ("com.spotify.music".equals(n.getPackageName())) {
spotifyRunning = true;
updateMediaNotification();
}

View File

@@ -28,6 +28,8 @@ import android.os.Handler;
import android.os.Message;
import android.util.Log;
import androidx.core.content.ContextCompat;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
@@ -40,8 +42,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import androidx.core.content.ContextCompat;
import java.util.concurrent.ConcurrentHashMap;
@PluginFactory.LoadablePlugin
public class MprisPlugin extends Plugin {
@@ -53,6 +54,7 @@ public class MprisPlugin extends Plugin {
private String artist = "";
private String album = "";
private String albumArtUrl = "";
private String url = "";
private int volume = 50;
private long length = -1;
private long lastPosition = 0;
@@ -136,6 +138,11 @@ public class MprisPlugin extends Plugin {
return AlbumArtCache.getAlbumArt(albumArtUrl, MprisPlugin.this, player);
}
//@NonNull
public String getUrl() {
return url;
}
public boolean isSetVolumeAllowed() {
return !isSpotify();
}
@@ -207,10 +214,9 @@ public class MprisPlugin extends Plugin {
private final static String PACKET_TYPE_MPRIS = "kdeconnect.mpris";
private final static String PACKET_TYPE_MPRIS_REQUEST = "kdeconnect.mpris.request";
private final HashMap<String, MprisPlayer> players = new HashMap<>();
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<>();
@Override
@@ -282,6 +288,7 @@ public class MprisPlugin extends Plugin {
playerStatus.title = np.getString("title", playerStatus.title);
playerStatus.artist = np.getString("artist", playerStatus.artist);
playerStatus.album = np.getString("album", playerStatus.album);
playerStatus.url = np.getString("url", playerStatus.url);
playerStatus.volume = np.getInt("volume", playerStatus.volume);
playerStatus.length = np.getLong("length", playerStatus.length);
if (np.has("pos")) {
@@ -401,6 +408,9 @@ public class MprisPlugin extends Plugin {
}
public MprisPlayer getPlayerStatus(String player) {
if (player == null) {
return null;
}
return players.get(player);
}
@@ -423,6 +433,9 @@ public class MprisPlugin extends Plugin {
}
boolean hasPlayer(MprisPlayer player) {
if (player == null) {
return false;
}
return players.containsValue(player);
}

View File

@@ -35,7 +35,7 @@ import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationReceiver;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.UserInterface.AlertDialogFragment;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect.UserInterface.StartActivityAlertDialogFragment;
import org.kde.kdeconnect_tp.R;
@@ -44,6 +44,7 @@ import java.util.List;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.DialogFragment;
@PluginFactory.LoadablePlugin
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
@@ -245,7 +246,7 @@ public class MprisReceiverPlugin extends Plugin {
}
@Override
public AlertDialogFragment getPermissionExplanationDialog(int requestCode) {
public DialogFragment getPermissionExplanationDialog() {
return new StartActivityAlertDialogFragment.Builder()
.setTitle(R.string.pref_plugin_mpris)
.setMessage(R.string.no_permission_mprisreceiver)
@@ -253,7 +254,7 @@ public class MprisReceiverPlugin extends Plugin {
.setNegativeButton(R.string.cancel)
.setIntentAction("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")
.setStartForResult(true)
.setRequestCode(requestCode)
.setRequestCode(MainActivity.RESULT_NEEDS_RELOAD)
.create();
}

View File

@@ -47,13 +47,14 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.fragment.app.DialogFragment;
import org.json.JSONArray;
import org.kde.kdeconnect.Helpers.AppsHelper;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.UserInterface.AlertDialogFragment;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect.UserInterface.PluginSettingsFragment;
import org.kde.kdeconnect.UserInterface.StartActivityAlertDialogFragment;
import org.kde.kdeconnect_tp.R;
@@ -567,7 +568,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
}
@Override
public AlertDialogFragment getPermissionExplanationDialog(int requestCode) {
public DialogFragment getPermissionExplanationDialog() {
return new StartActivityAlertDialogFragment.Builder()
.setTitle(R.string.pref_plugin_notifications)
.setMessage(R.string.no_permissions)
@@ -575,7 +576,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
.setNegativeButton(R.string.cancel)
.setIntentAction("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")
.setStartForResult(true)
.setRequestCode(requestCode)
.setRequestCode(MainActivity.RESULT_NEEDS_RELOAD)
.create();
}

View File

@@ -19,14 +19,11 @@ import androidx.core.content.FileProvider;
public class PhotoActivity extends AppCompatActivity {
private Uri photoURI;
private PhotoPlugin plugin;
@Override
protected void onStart() {
super.onStart();
BackgroundService.RunWithPlugin(this, getIntent().getStringExtra("deviceId"), PhotoPlugin.class, plugin -> this.plugin = plugin);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
@@ -61,12 +58,13 @@ public class PhotoActivity extends AppCompatActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == -1) {
plugin.sendPhoto(photoURI);
} else {
plugin.sendCancel();
}
BackgroundService.RunWithPlugin(this, getIntent().getStringExtra("deviceId"), PhotoPlugin.class, plugin -> {
if (resultCode == -1) {
plugin.sendPhoto(photoURI);
} else {
plugin.sendCancel();
}
});
finish();
}
}

View File

@@ -22,29 +22,56 @@ package org.kde.kdeconnect.Plugins;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.UserInterface.AlertDialogFragment;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect.UserInterface.PermissionsAlertDialogFragment;
import org.kde.kdeconnect.UserInterface.PluginSettingsFragment;
import org.kde.kdeconnect_tp.R;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
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;
public final void setContext(Context context, Device device) {
public final void setContext(@NonNull Context context, @Nullable Device device) {
this.device = device;
this.context = context;
if (device != null) {
this.preferences = this.context.getSharedPreferences(this.getSharedPreferencesName(), Context.MODE_PRIVATE);
}
}
public String getSharedPreferencesName() {
if (device == null) {
throw new RuntimeException("You have to call setContext() before you can call getSharedPreferencesName()");
}
if (this.supportsDeviceSpecificSettings())
return this.device.getDeviceId() + "_" + this.getPluginKey() + "_preferences";
else
return this.getPluginKey() + "_preferences";
}
@Nullable
public SharedPreferences getPreferences() {
return this.preferences;
}
/**
@@ -119,6 +146,30 @@ public abstract class Plugin {
return false;
}
/**
* Called to find out if a plugin supports device specific settings.
* If you return true your PluginSettingsFragment will use the device
* specific SharedPreferences to store the settings.
*
* @return true if this plugin supports device specific settings
*/
public boolean supportsDeviceSpecificSettings() { return false; }
/**
* Called when it's time to move the plugin settings from the global preferences
* to device specific preferences
*
* @param globalSharedPreferences The global Preferences to copy the settings from
*/
public void copyGlobalToDeviceSpecificSettings(SharedPreferences globalSharedPreferences) {}
/**
* Called when the plugin should remove it's settings from the provided ShardPreferences
*
* @param sharedPreferences The SharedPreferences to remove the settings from
*/
public void removeSettings(SharedPreferences sharedPreferences) {}
/**
* If hasSettings returns true, this will be called when the user
* wants to access this plugin's preferences. The default implementation
@@ -207,14 +258,14 @@ public abstract class Plugin {
return true;
}
private PermissionsAlertDialogFragment requestPermissionDialog(final String[] permissions, @StringRes int reason, int requestCode) {
private PermissionsAlertDialogFragment requestPermissionDialog(final String[] permissions, @StringRes int reason) {
return new PermissionsAlertDialogFragment.Builder()
.setTitle(getDisplayName())
.setMessage(reason)
.setPositiveButton(R.string.ok)
.setNegativeButton(R.string.cancel)
.setPermissions(permissions)
.setRequestCode(requestCode)
.setRequestCode(MainActivity.RESULT_NEEDS_RELOAD)
.create();
}
@@ -223,12 +274,12 @@ public abstract class Plugin {
* the problem (and how to fix it, if possible) to the user.
*/
public AlertDialogFragment getPermissionExplanationDialog(int requestCode) {
return requestPermissionDialog(getRequiredPermissions(), permissionExplanation, requestCode);
public DialogFragment getPermissionExplanationDialog() {
return requestPermissionDialog(getRequiredPermissions(), permissionExplanation);
}
public AlertDialogFragment getOptionalPermissionExplanationDialog(int requestCode) {
return requestPermissionDialog(getOptionalPermissions(), optionalPermissionExplanation, requestCode);
public AlertDialogFragment getOptionalPermissionExplanationDialog() {
return requestPermissionDialog(getOptionalPermissions(), optionalPermissionExplanation);
}
public boolean checkRequiredPermissions() {
@@ -242,5 +293,4 @@ public abstract class Plugin {
public int getMinSdk() {
return Build.VERSION_CODES.BASE;
}
}

View File

@@ -42,14 +42,15 @@ public class PluginFactory {
public static class PluginInfo {
PluginInfo(String displayName, String description, Drawable icon,
boolean enabledByDefault, boolean hasSettings, boolean listenToUnpaired,
String[] supportedPacketTypes, String[] outgoingPacketTypes,
boolean enabledByDefault, boolean hasSettings, boolean supportsDeviceSpecificSettings,
boolean listenToUnpaired, String[] supportedPacketTypes, String[] outgoingPacketTypes,
Class<? extends Plugin> instantiableClass) {
this.displayName = displayName;
this.description = description;
this.icon = icon;
this.enabledByDefault = enabledByDefault;
this.hasSettings = hasSettings;
this.supportsDeviceSpecificSettings = supportsDeviceSpecificSettings;
this.listenToUnpaired = listenToUnpaired;
HashSet<String> incoming = new HashSet<>();
if (supportedPacketTypes != null) Collections.addAll(incoming, supportedPacketTypes);
@@ -76,6 +77,8 @@ public class PluginFactory {
return hasSettings;
}
public boolean supportsDeviceSpecificSettings() { return supportsDeviceSpecificSettings; }
public boolean isEnabledByDefault() {
return enabledByDefault;
}
@@ -101,6 +104,7 @@ public class PluginFactory {
private final Drawable icon;
private final boolean enabledByDefault;
private final boolean hasSettings;
private final boolean supportsDeviceSpecificSettings;
private final boolean listenToUnpaired;
private final Set<String> supportedPacketTypes;
private final Set<String> outgoingPacketTypes;
@@ -120,8 +124,9 @@ public class PluginFactory {
Plugin p = ((Plugin) pluginClass.newInstance());
p.setContext(context, null);
PluginInfo info = new PluginInfo(p.getDisplayName(), p.getDescription(), p.getIcon(),
p.isEnabledByDefault(), p.hasSettings(), p.listensToUnpairedDevices(),
p.getSupportedPacketTypes(), p.getOutgoingPacketTypes(), p.getClass());
p.isEnabledByDefault(), p.hasSettings(), p.supportsDeviceSpecificSettings(),
p.listensToUnpairedDevices(), p.getSupportedPacketTypes(),
p.getOutgoingPacketTypes(), p.getClass());
pluginInfo.put(p.getPluginKey(), info);
}
} catch (Exception e) {

View File

@@ -0,0 +1,44 @@
Writing a plugin for KDE Connect
=================================
For Android (this project):
-----------------------------------------
1. Change directory to src/org/kde/kdeconnect/Plugins.
2. Copy "PingPlugin" under a different name ("FindMyPhonePlugin" in this example).
1. Enter the new "FindMyPhonePlugin" directory.
4. Rename "PingPlugin.java" to "FindMyPhonePlugin.java"
5. Edit it. Replace (case sensitive) "Ping" with "FindMyPhone", "ping" with "findmyphone", "PING" with "FINDMYPHONE"
and "plugin_ping" with "plugin_findmyphone".
6. Open res/values/strings.xml. Find and copy the lines "pref_plugin_ping_desc" and "pref_plugin_ping" replacing "ping"
with "findmyphone" and edit the plugin name and description between <string> </string>).
7. Open src/org/kde/kdeconnect/Plugins/PluginFactory.java.
A. Copy "import … PingPlugin" line with replacing "PingPlugin" with "FindMyPhonePlugin".
B. Copy "PluginFactory.registerPlugin(PingPlugin.class);" line with replacing "PingPlugin" with "FindMyPhonePlugin".
8. Open src/org/kde/kdeconnect/NetworkPacket.java. Copy a "public final static String PACKET_TYPE_PING = …" line
replacing "PING" with the packet type you will be using (should match the desktop client).
9. Now you have an empty skeleton to implement your new plugin logic.
For the desktop client (project kdeconnect-kde):
--------------------------------------
1. Enter the "plugins" directory.
2. Copy the "ping" under a different name ("findmyphone" in this example).
3. Add "add_subdirectory(findmyphone)" to CMakeLists.txt after the others "add_subdirectory".
1. Enter the new "findmyphone" directory.
5. Edit CMakeLists.txt by replacing "ping" with "findmyphone".
6. Rename other files in this directory by replacing "ping" with "findmyphone"
7. Write a description of your plugin into "README"
8. Edit findmyphoneplugin.cpp and findmyphoneplugin.h.
A. Change license header.
B. Replace (case sensitive) "ping" with "findmyphone", "PingPlugin" with "FindMyPhonePlugin" and "PING" with "FINDMYPHONE".
9. Edit kdeconnect_findmyphone.desktop file:
A. Replace "ping" with "findmyphone".
B. Change name, description, icon, author, email, version, website, license info.
C. Remove all the translations
D. Set X-KDEConnect-SupportedPacketType and X-KDEConnect-OutgoingPacketType to the packet type your plugin will receive
and send, respectively. In this example this is "kdeconnect.findmyphone". Make sure that this matches what is defined in
the findmyplugin.h file (in the line "#define PACKET_TYPE_..."), and also in Android.
10. Now you have an empty skeleton to implement your new plugin logic.

View File

@@ -35,7 +35,7 @@ import android.view.inputmethod.InputConnection;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.UserInterface.AlertDialogFragment;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect.UserInterface.StartActivityAlertDialogFragment;
import org.kde.kdeconnect_tp.R;
@@ -44,6 +44,7 @@ import java.util.concurrent.locks.ReentrantLock;
import androidx.core.content.ContextCompat;
import androidx.core.util.Pair;
import androidx.fragment.app.DialogFragment;
@PluginFactory.LoadablePlugin
public class RemoteKeyboardPlugin extends Plugin {
@@ -403,7 +404,7 @@ public class RemoteKeyboardPlugin extends Plugin {
}
@Override
public AlertDialogFragment getPermissionExplanationDialog(int requestCode) {
public DialogFragment getPermissionExplanationDialog() {
return new StartActivityAlertDialogFragment.Builder()
.setTitle(R.string.pref_plugin_remotekeyboard)
.setMessage(R.string.no_permissions_remotekeyboard)
@@ -411,7 +412,7 @@ public class RemoteKeyboardPlugin extends Plugin {
.setNegativeButton(R.string.cancel)
.setIntentAction(Settings.ACTION_INPUT_METHOD_SETTINGS)
.setStartForResult(true)
.setRequestCode(requestCode)
.setRequestCode(MainActivity.RESULT_NEEDS_RELOAD)
.create();
}
}

View File

@@ -8,6 +8,8 @@ import android.widget.RemoteViewsService;
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
class RunCommandWidgetDataProvider implements RemoteViewsService.RemoteViewsFactory {
@@ -74,10 +76,15 @@ class RunCommandWidgetDataProvider implements RemoteViewsService.RemoteViewsFact
@Override
public long getItemId(int i) {
if (RunCommandWidget.getCurrentDevice() != null)
return RunCommandWidget.getCurrentDevice().getPlugin(RunCommandPlugin.class).getCommandItems().get(i).getKey().hashCode();
return 0;
int id = 0;
if (RunCommandWidget.getCurrentDevice() != null) {
RunCommandPlugin plugin = RunCommandWidget.getCurrentDevice().getPlugin(RunCommandPlugin.class);
if (plugin != null) {
ArrayList<CommandEntry> items = plugin.getCommandItems();
id = items.get(i).getKey().hashCode();
}
}
return id;
}
@Override

View File

@@ -126,7 +126,8 @@ public class SMSPlugin extends Plugin {
* The body should look like so:
* { "sendSms": true,
* "phoneNumber": "542904563213",
* "messageBody": "Hi mom!"
* "messageBody": "Hi mom!",
* "sub_id": "3859358340534"
* }
*/
private final static String PACKET_TYPE_SMS_REQUEST = "kdeconnect.sms.request";
@@ -141,9 +142,12 @@ public class SMSPlugin extends Plugin {
/**
* Packet sent to request all the messages in a particular conversation
* <p>
* The body should contain the key "threadID" mapping to the threadID (as a string) being requested
* For example:
* { "threadID": 203 }
* The following fields are available:
* "threadID": <long> // (Required) ThreadID to request
* "rangeStartTimestamp": <long> // (Optional) Millisecond epoch timestamp indicating the start of the range from which to return messages
* "numberToRequest": <long> // (Optional) Number of messages to return, starting from rangeStartTimestamp.
* // May return fewer than expected if there are not enough or more than expected if many
* // messages have the same timestamp.
*/
private final static String PACKET_TYPE_SMS_REQUEST_CONVERSATION = "kdeconnect.sms.request_conversation";
@@ -336,9 +340,11 @@ public class SMSPlugin extends Plugin {
if (np.getBoolean("sendSms")) {
String phoneNo = np.getString("phoneNumber");
String sms = np.getString("messageBody");
long subID = np.getLong("subID", -1);
try {
SmsManager smsManager = SmsManager.getDefault();
SmsManager smsManager = subID == -1? SmsManager.getDefault() :
SmsManager.getSmsManagerForSubscriptionId((int) subID);
ArrayList<String> parts = smsManager.divideMessage(sms);
// If this message turns out to fit in a single SMS, sendMultipartTextMessage
@@ -412,7 +418,19 @@ public class SMSPlugin extends Plugin {
private boolean handleRequestConversation(NetworkPacket packet) {
SMSHelper.ThreadID threadID = new SMSHelper.ThreadID(packet.getLong("threadID"));
List<SMSHelper.Message> conversation = SMSHelper.getMessagesInThread(this.context, threadID);
Long rangeStartTimestamp = packet.getLong("rangeStartTimestamp", -1);
Long numberToGet = packet.getLong("numberToRequest", -1);
if (numberToGet < 0) {
numberToGet = null;
}
List<SMSHelper.Message> conversation;
if (rangeStartTimestamp < 0) {
conversation = SMSHelper.getMessagesInThread(this.context, threadID, numberToGet);
} else {
conversation = SMSHelper.getMessagesInRange(this.context, threadID, rangeStartTimestamp, numberToGet);
}
NetworkPacket reply = constructBulkMessagePacket(conversation);

View File

@@ -27,6 +27,8 @@ import android.net.Uri;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.kde.kdeconnect.NetworkPacket;
@@ -43,19 +45,16 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
@PluginFactory.LoadablePlugin
public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPreferenceChangeListener {
private final static String PACKET_TYPE_SFTP = "kdeconnect.sftp";
private final static String PACKET_TYPE_SFTP_REQUEST = "kdeconnect.sftp.request";
private static final SimpleSftpServer server = new SimpleSftpServer();
static int PREFERENCE_KEY_STORAGE_INFO_LIST = R.string.sftp_preference_key_storage_info_list;
private static int PREFERENCE_KEY_ADD_CAMERA_SHORTCUT = R.string.sftp_preference_key_add_camera_shortcut;
private String KeyStorageInfoList;
private String KeyAddCameraShortcut;
private static final SimpleSftpServer server = new SimpleSftpServer();
@Override
public String getDisplayName() {
@@ -69,14 +68,11 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
@Override
public boolean onCreate() {
KeyStorageInfoList = context.getString(R.string.sftp_preference_key_storage_info_list);
KeyAddCameraShortcut = context.getString(R.string.sftp_preference_key_add_camera_shortcut);
try {
server.init(context, device);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
return SftpSettingsFragment.getStorageInfoList(context).size() != 0;
return SftpSettingsFragment.getStorageInfoList(context, this).size() != 0;
}
return true;
@@ -89,14 +85,14 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
@Override
public boolean checkOptionalPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return SftpSettingsFragment.getStorageInfoList(context).size() != 0;
return SftpSettingsFragment.getStorageInfoList(context, this).size() != 0;
}
return true;
}
@Override
public AlertDialogFragment getOptionalPermissionExplanationDialog(int requestCode) {
public AlertDialogFragment getOptionalPermissionExplanationDialog() {
return new DeviceSettingsAlertDialogFragment.Builder()
.setTitle(getDisplayName())
.setMessage(R.string.sftp_saf_permission_explanation)
@@ -110,7 +106,9 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
@Override
public void onDestroy() {
server.stop();
PreferenceManager.getDefaultSharedPreferences(context).unregisterOnSharedPreferenceChangeListener(this);
if (preferences != null) {
preferences.unregisterOnSharedPreferenceChangeListener(this);
}
}
@Override
@@ -119,7 +117,7 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
ArrayList<String> paths = new ArrayList<>();
ArrayList<String> pathNames = new ArrayList<>();
List<StorageInfo> storageInfoList = SftpSettingsFragment.getStorageInfoList(context);
List<StorageInfo> storageInfoList = SftpSettingsFragment.getStorageInfoList(context, this);
Collections.sort(storageInfoList, new StorageInfo.UriNameComparator());
if (storageInfoList.size() > 0) {
@@ -141,7 +139,9 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
removeChildren(storageInfoList);
if (server.start(storageInfoList)) {
PreferenceManager.getDefaultSharedPreferences(context).registerOnSharedPreferenceChangeListener(this);
if (preferences != null) {
preferences.registerOnSharedPreferenceChangeListener(this);
}
NetworkPacket np2 = new NetworkPacket(PACKET_TYPE_SFTP);
@@ -170,11 +170,13 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
private void getPathsAndNamesForStorageInfoList(List<String> paths, List<String> pathNames, List<StorageInfo> storageInfoList) {
StorageInfo prevInfo = null;
StringBuilder pathBuilder = new StringBuilder();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean addCameraShortcuts = false;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
addCameraShortcuts = prefs.getBoolean(context.getString(R.string.sftp_preference_key_add_camera_shortcut), true);
if (preferences != null) {
addCameraShortcuts = preferences.getBoolean(context.getString(PREFERENCE_KEY_ADD_CAMERA_SHORTCUT), true);
}
}
for (StorageInfo curInfo : storageInfoList) {
@@ -245,6 +247,33 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
return true;
}
@Override
public boolean supportsDeviceSpecificSettings() { return true; }
@Override
public void copyGlobalToDeviceSpecificSettings(SharedPreferences globalSharedPreferences) {
String KeyStorageInfoList = context.getString(PREFERENCE_KEY_STORAGE_INFO_LIST);
String KeyAddCameraShortcut = context.getString(PREFERENCE_KEY_ADD_CAMERA_SHORTCUT);
if (this.preferences != null &&
(!this.preferences.contains(KeyStorageInfoList) || !this.preferences.contains(KeyAddCameraShortcut))) {
this.preferences
.edit()
.putString(KeyStorageInfoList, globalSharedPreferences.getString(KeyStorageInfoList, "[]"))
.putBoolean(KeyAddCameraShortcut, globalSharedPreferences.getBoolean(KeyAddCameraShortcut, true))
.apply();
}
}
@Override
public void removeSettings(SharedPreferences sharedPreferences) {
sharedPreferences
.edit()
.remove(context.getString(PREFERENCE_KEY_STORAGE_INFO_LIST))
.remove(context.getString(PREFERENCE_KEY_ADD_CAMERA_SHORTCUT))
.apply();
}
@Override
public PluginSettingsFragment getSettingsFragment(Activity activity) {
return SftpSettingsFragment.newInstance(getPluginKey());
@@ -252,7 +281,8 @@ public class SftpPlugin extends Plugin implements SharedPreferences.OnSharedPref
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(KeyStorageInfoList) || key.equals(KeyAddCameraShortcut)) {
if (key.equals(context.getString(PREFERENCE_KEY_STORAGE_INFO_LIST)) ||
key.equals(context.getString(PREFERENCE_KEY_ADD_CAMERA_SHORTCUT))) {
//TODO: There used to be a way to request an un-mount (see desktop SftpPlugin's Mounter::onPackageReceived) but that is not handled anymore by the SftpPlugin on KDE.
if (server.isStarted()) {
server.stop();

View File

@@ -36,12 +36,21 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.appcompat.view.ActionMode;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Helpers.StorageHelper;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.UserInterface.PluginSettingsActivity;
import org.kde.kdeconnect.UserInterface.PluginSettingsFragment;
import org.kde.kdeconnect_tp.R;
@@ -52,15 +61,6 @@ import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import androidx.annotation.NonNull;
import androidx.appcompat.view.ActionMode;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
//TODO: Is it possible on API 19 to select a directory and then have write permission for everything beneath it
//TODO: Is it necessary to check if uri permissions are still in place? If it is make the user aware of the fact (red text or something)
public class SftpSettingsFragment
@@ -116,10 +116,10 @@ public class SftpSettingsFragment
int sdkInt = Build.VERSION.SDK_INT;
storageInfoList = getStorageInfoList(requireContext());
storageInfoList = getStorageInfoList(requireContext(), plugin);
PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceCategory = (PreferenceCategory) preferenceScreen
preferenceCategory = preferenceScreen
.findPreference(getString(R.string.sftp_preference_key_preference_category));
if (sdkInt <= 19) {
@@ -245,30 +245,30 @@ public class SftpSettingsFragment
}
private void saveStorageInfoList() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(requireContext());
SharedPreferences preferences = this.plugin.getPreferences();
JSONArray jsonArray = new JSONArray();
try {
for (SftpPlugin.StorageInfo storageInfo : storageInfoList) {
for (SftpPlugin.StorageInfo storageInfo : this.storageInfoList) {
jsonArray.put(storageInfo.toJSON());
}
} catch (JSONException ignored) {}
preferences
.edit()
.putString(requireContext().getString(R.string.sftp_preference_key_storage_info_list), jsonArray.toString())
.putString(requireContext().getString(SftpPlugin.PREFERENCE_KEY_STORAGE_INFO_LIST), jsonArray.toString())
.apply();
}
@NonNull
static List<SftpPlugin.StorageInfo> getStorageInfoList(@NonNull Context context) {
static List<SftpPlugin.StorageInfo> getStorageInfoList(@NonNull Context context, @NonNull Plugin plugin) {
ArrayList<SftpPlugin.StorageInfo> storageInfoList = new ArrayList<>();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences deviceSettings = plugin.getPreferences();
String jsonString = preferences
.getString(context.getString(R.string.sftp_preference_key_storage_info_list), "[]");
String jsonString = deviceSettings
.getString(context.getString(SftpPlugin.PREFERENCE_KEY_STORAGE_INFO_LIST), "[]");
try {
JSONArray jsonArray = new JSONArray(jsonString);
@@ -414,11 +414,19 @@ public class SftpSettingsFragment
addStoragePreferences(preferenceCategory);
Device device = getDeviceOrThrow();
device.reloadPluginsFromSettings();
}
private Device getDeviceOrThrow() {
Device device = BackgroundService.getInstance().getDevice(getDeviceId());
if (device != null) {
device.reloadPluginsFromSettings();
if (device == null) {
throw new RuntimeException("SftpSettingsFragment.getDeviceOrThrow(): No device with id: " + getDeviceId());
}
return device;
}
@Override

View File

@@ -29,8 +29,8 @@ import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.PublickeyAuthenticator;
import org.apache.sshd.server.command.ScpCommandFactory;
import org.apache.sshd.server.kex.DHG1;
import org.apache.sshd.server.kex.DHG14;
import org.apache.sshd.server.kex.ECDHP384;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.sftp.SftpSubsystem;
import org.kde.kdeconnect.Device;
@@ -38,6 +38,7 @@ import org.kde.kdeconnect.Helpers.RandomHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
@@ -75,8 +76,9 @@ class SimpleSftpServer {
void init(Context context, Device device) throws GeneralSecurityException {
sshd.setKeyExchangeFactories(Arrays.asList(
new DHG14.Factory(),
new DHG1.Factory()));
new ECDHP384.Factory(), // This is the best we have in mina-sshd 0.14.0 -- Upgrading is non-trivial
new DHG14.Factory() // Left for backwards-compatibility, but should probably be removed
));
//Reuse this device keys for the ssh connection as well
final KeyPair keyPair;
@@ -112,7 +114,7 @@ class SimpleSftpServer {
sshd.setPort(port);
sshd.start();
started = true;
} catch (Exception e) {
} catch (IOException e) {
port++;
if (port >= ENDPORT) {
port = -1;

View File

@@ -78,9 +78,10 @@ public class AlertDialogFragment extends DialogFragment implements DialogInterfa
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext())
.setTitle(titleString)
.setPositiveButton(positiveButtonResId, this)
.setNegativeButton(negativeButtonResId, this);
.setPositiveButton(positiveButtonResId, this);
if (negativeButtonResId != 0) {
builder.setNegativeButton(negativeButtonResId, this);
}
if (customViewResId != 0) {
builder.setView(customViewResId);
} else {

View File

@@ -37,6 +37,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import org.kde.kdeconnect.BackgroundService;
@@ -324,13 +325,13 @@ public class DeviceFragment extends Fragment {
pluginListItems.add(new PluginItem(p, v -> p.startMainActivity(mActivity)));
}
DeviceFragment.this.createPluginsList(device.getPluginsWithoutPermissions(), R.string.plugins_need_permission, (plugin) -> {
AlertDialogFragment dialog = plugin.getPermissionExplanationDialog(MainActivity.RESULT_NEEDS_RELOAD);
DialogFragment dialog = plugin.getPermissionExplanationDialog();
if (dialog != null) {
dialog.show(getChildFragmentManager(), null);
}
});
DeviceFragment.this.createPluginsList(device.getPluginsWithoutOptionalPermissions(), R.string.plugins_need_optional_permission, (plugin) -> {
AlertDialogFragment dialog = plugin.getOptionalPermissionExplanationDialog(MainActivity.RESULT_NEEDS_RELOAD);
DialogFragment dialog = plugin.getOptionalPermissionExplanationDialog();
if (dialog != null) {
dialog.show(getChildFragmentManager(), null);

View File

@@ -378,6 +378,13 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
}
}
public void reloadCurrentDevicePlugins() {
BackgroundService.RunCommand(this, service -> {
Device device = service.getDevice(mCurrentDevice);
device.reloadPluginsFromSettings();
});
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (DeviceHelper.KEY_DEVICE_NAME_PREFERENCE.equals(key)) {

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2019 Erik Duisters <e.duisters1@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.UserInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
import org.kde.kdeconnect_tp.R;
public class NoticeAlertDialogFragment extends AlertDialogFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCallback(new Callback() {
@Override
public void onPositiveButtonClicked() {
//TODO: Find a way to pass this callback from the Builder. For now, this is only used in one place and this is the callback needed.
MainActivity mainActivity = (MainActivity)requireActivity();
mainActivity.reloadCurrentDevicePlugins();
}
});
}
public static class Builder extends AbstractBuilder<Builder, NoticeAlertDialogFragment> {
public Builder() {
super();
setTitle(R.string.pref_plugin_clipboard);
setMessage(R.string.clipboard_android_x_incompat);
setPositiveButton(R.string.sad_ok);
}
@Override
public Builder getThis() {
return this;
}
@Override
protected NoticeAlertDialogFragment createFragment() {
return new NoticeAlertDialogFragment();
}
}
}

View File

@@ -67,12 +67,17 @@ public class PluginSettingsActivity
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragmentPlaceHolder);
if (fragment == null) {
if (pluginKey == null) {
fragment = PluginSettingsListFragment.newInstance(deviceId);
} else {
if (pluginKey != null) {
Device device = BackgroundService.getInstance().getDevice(deviceId);
Plugin plugin = device.getPlugin(pluginKey);
fragment = plugin.getSettingsFragment(this);
if (device != null) {
Plugin plugin = device.getPlugin(pluginKey);
if (plugin != null) {
fragment = plugin.getSettingsFragment(this);
}
}
}
if (fragment == null) {
fragment = PluginSettingsListFragment.newInstance(deviceId);
}
getSupportFragmentManager()

View File

@@ -20,20 +20,27 @@
package org.kde.kdeconnect.UserInterface;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect_tp.R;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceFragmentCompat;
public class PluginSettingsFragment extends PreferenceFragmentCompat {
private static final String ARG_PLUGIN_KEY = "plugin_key";
private String pluginKey;
protected Device device;
protected Plugin plugin;
public static PluginSettingsFragment newInstance(@NonNull String pluginKey) {
PluginSettingsFragment fragment = new PluginSettingsFragment();
@@ -60,12 +67,20 @@ public class PluginSettingsFragment extends PreferenceFragmentCompat {
}
pluginKey = getArguments().getString(ARG_PLUGIN_KEY);
this.device = getDeviceOrThrow(getDeviceId());
this.plugin = device.getPlugin(pluginKey);
super.onCreate(savedInstanceState);
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
if (this.plugin != null && this.plugin.supportsDeviceSpecificSettings()) {
PreferenceManager prefsManager = getPreferenceManager();
prefsManager.setSharedPreferencesName(this.plugin.getSharedPreferencesName());
prefsManager.setSharedPreferencesMode(Context.MODE_PRIVATE);
}
int resFile = getResources().getIdentifier(pluginKey.toLowerCase(Locale.ENGLISH) + "_preferences", "xml",
requireContext().getPackageName());
addPreferencesFromResource(resFile);
@@ -82,4 +97,14 @@ public class PluginSettingsFragment extends PreferenceFragmentCompat {
public String getDeviceId() {
return ((PluginSettingsActivity)requireActivity()).getDeviceId();
}
private Device getDeviceOrThrow(String deviceId) {
Device device = BackgroundService.getInstance().getDevice(deviceId);
if (device == null) {
throw new RuntimeException("PluginSettingsFragment.onCreatePreferences() - No device with id " + getDeviceId());
}
return device;
}
}

View File

@@ -8,14 +8,6 @@ import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.View;
import com.google.android.material.snackbar.Snackbar;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect.Helpers.NotificationHelper;
import org.kde.kdeconnect_tp.R;
import androidx.preference.EditTextPreference;
import androidx.preference.Preference;
@@ -24,6 +16,13 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreferenceCompat;
import androidx.preference.TwoStatePreference;
import com.google.android.material.snackbar.Snackbar;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect.Helpers.NotificationHelper;
import org.kde.kdeconnect_tp.R;
public class SettingsFragment extends PreferenceFragmentCompat {
private MainActivity mainActivity;

View File

@@ -155,17 +155,6 @@ public class DeviceTest {
Device.PairingCallback pairingCallback = Mockito.mock(Device.PairingCallback.class);
device.addPairingCallback(pairingCallback);
KeyPair keyPair;
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
keyPair = keyGen.genKeyPair();
} catch (Exception e) {
Log.e("KDE/initializeRsaKeys", "Exception", e);
Log.e("KDE/initializeRsaKeys", "Exception", e);
return;
}
device.publicKey = keyPair.getPublic();
ArgumentCaptor<BasePairingHandler.PairingHandlerCallback> pairingHandlerCallback = ArgumentCaptor.forClass(BasePairingHandler.PairingHandlerCallback.class);
Mockito.verify(link, Mockito.times(1)).getPairingHandler(eq(device), pairingHandlerCallback.capture());
@@ -174,7 +163,6 @@ public class DeviceTest {
assertEquals(device.getDeviceId(), "unpairedTestDevice");
assertEquals(device.getName(), "Unpaired Test Device");
assertEquals(device.getDeviceType(), Device.DeviceType.Phone);
assertNotNull(device.publicKey);
assertNull(device.certificate);
pairingHandlerCallback.getValue().pairingDone();
@@ -196,14 +184,6 @@ public class DeviceTest {
@Test
public void testPairingDoneWithCertificate() {
KeyPair keyPair = null;
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
keyPair = keyGen.genKeyPair();
} catch (Exception e) {
Log.e("KDE/initializeRsaKeys", "Exception", e);
}
NetworkPacket fakeNetworkPacket = new NetworkPacket(NetworkPacket.PACKET_TYPE_IDENTITY);
fakeNetworkPacket.set("deviceId", "unpairedTestDevice");
@@ -234,13 +214,11 @@ public class DeviceTest {
Mockito.when(link.getPairingHandler(any(Device.class), any(BasePairingHandler.PairingHandlerCallback.class))).thenReturn(Mockito.mock(LanPairingHandler.class));
Mockito.when(link.getLinkProvider()).thenReturn(linkProvider);
Device device = new Device(context, fakeNetworkPacket, link);
device.publicKey = keyPair.getPublic();
assertNotNull(device);
assertEquals(device.getDeviceId(), "unpairedTestDevice");
assertEquals(device.getName(), "Unpaired Test Device");
assertEquals(device.getDeviceType(), Device.DeviceType.Phone);
assertNotNull(device.publicKey);
assertNotNull(device.certificate);
Method method;